6929029 hat_kpm_fault() on sun4v forces kernel panic
6938762 dr_mem_list_query() should use copy of phys_install
--- a/usr/src/uts/sun4v/io/dr_mem.c Mon Mar 29 17:56:28 2010 -0700
+++ b/usr/src/uts/sun4v/io/dr_mem.c Mon Mar 29 18:06:31 2010 -0700
@@ -708,6 +708,7 @@
int rlen;
int nml;
struct memlist *ml;
+ struct memlist *phys_copy = NULL;
dr_mem_blk_t *req_mblks, mb;
dr_mem_hdr_t *rp;
dr_mem_query_t *stat;
@@ -723,9 +724,13 @@
if (req_mblks->addr == NULL && req_mblks->size == 0) {
/*
* Request is for domain's full view of it's memory.
+ * place a copy in phys_copy then release the memlist lock.
*/
memlist_read_lock();
- for (ml = phys_install; ml; ml = ml->ml_next)
+ phys_copy = dr_memlist_dup(phys_install);
+ memlist_read_unlock();
+
+ for (ml = phys_copy; ml; ml = ml->ml_next)
nml++;
rlen += nml * sizeof (dr_mem_query_t);
@@ -744,12 +749,11 @@
/* get the status for each of the mblocks */
if (nml) {
- for (idx = 0, ml = phys_install; ml; ml = ml->ml_next, idx++) {
+ for (idx = 0, ml = phys_copy; ml; ml = ml->ml_next, idx++) {
mb.addr = ml->ml_address;
mb.size = ml->ml_size;
dr_mem_query(&mb, &stat[idx]);
}
- memlist_read_unlock();
} else {
for (idx = 0; idx < req->msg_arg; idx++)
dr_mem_query(&req_mblks[idx], &stat[idx]);
@@ -757,7 +761,9 @@
*resp = rp;
*resp_len = rlen;
-
+ if (phys_copy != NULL) {
+ dr_memlist_delete(phys_copy);
+ }
drctl_unblock();
return (0);
--- a/usr/src/uts/sun4v/io/dr_util.c Mon Mar 29 17:56:28 2010 -0700
+++ b/usr/src/uts/sun4v/io/dr_util.c Mon Mar 29 18:06:31 2010 -0700
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,7 +36,7 @@
#include <sys/sysevent/dr.h>
#include <sys/sysevent/eventdefs.h>
#include <sys/ldoms.h>
-
+#include <sys/memlist.h>
#include <sys/dr_util.h>
extern int ppvm_enable;
@@ -142,6 +142,44 @@
sysevent_free(ev);
}
+struct memlist *
+dr_memlist_dup(struct memlist *mlist)
+{
+ struct memlist *hl = NULL, *tl, **mlp;
+
+ if (mlist == NULL)
+ return (NULL);
+
+ mlp = &hl;
+ tl = *mlp;
+ for (; mlist; mlist = mlist->ml_next) {
+ *mlp = (struct memlist *)kmem_zalloc(sizeof (struct memlist),\
+ KM_SLEEP);
+ (*mlp)->ml_address = mlist->ml_address;
+ (*mlp)->ml_size = mlist->ml_size;
+ (*mlp)->ml_prev = tl;
+ tl = *mlp;
+ mlp = &((*mlp)->ml_next);
+ }
+ *mlp = NULL;
+
+ return (hl);
+}
+
+/*
+ * Free a memlist and its elements
+ */
+void
+dr_memlist_delete(struct memlist *mlist)
+{
+ register struct memlist *ml;
+
+ for (ml = mlist; ml; ml = mlist) {
+ mlist = ml->ml_next;
+ kmem_free((void *)ml, sizeof (struct memlist));
+ }
+}
+
/*
* Debugging Features
*/
--- a/usr/src/uts/sun4v/sys/dr_util.h Mon Mar 29 17:56:28 2010 -0700
+++ b/usr/src/uts/sun4v/sys/dr_util.h Mon Mar 29 18:06:31 2010 -0700
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -99,6 +99,8 @@
extern boolean_t dr_is_disabled(dr_type_t type);
extern void dr_generate_event(dr_type_t type, int se_hint);
+extern struct memlist *dr_memlist_dup(struct memlist *mlist);
+extern void dr_memlist_delete(struct memlist *mlist);
#ifdef __cplusplus
}
--- a/usr/src/uts/sun4v/vm/mach_kpm.c Mon Mar 29 17:56:28 2010 -0700
+++ b/usr/src/uts/sun4v/vm/mach_kpm.c Mon Mar 29 18:06:31 2010 -0700
@@ -192,7 +192,7 @@
return (page_numtopp_nolock(pfn));
}
-
+/*ARGSUSED*/
/*
* hat_kpm_fault is called from segkpm_fault when a kpm tsbmiss occurred.
* This should never happen on sun4v.
@@ -200,10 +200,12 @@
int
hat_kpm_fault(struct hat *hat, caddr_t vaddr)
{
- panic("pagefault in seg_kpm. hat: 0x%p vaddr: 0x%p",
- (void *)hat, (void *)vaddr);
+ /*
+ * Return FC_NOMAP for sun4v to allow the t_lofault_handler
+ * to handle this fault if one is installed
+ */
- return (0);
+ return (FC_NOMAP);
}
/*ARGSUSED*/