6929029 hat_kpm_fault() on sun4v forces kernel panic
authorSean McEnroe <Sean.McEnroe@Sun.COM>
Mon, 29 Mar 2010 18:06:31 -0700
changeset 12037 88afeddf1b92
parent 12036 aa269fb9cf77
child 12038 a76f1fd5c122
6929029 hat_kpm_fault() on sun4v forces kernel panic 6938762 dr_mem_list_query() should use copy of phys_install
usr/src/uts/sun4v/io/dr_mem.c
usr/src/uts/sun4v/io/dr_util.c
usr/src/uts/sun4v/sys/dr_util.h
usr/src/uts/sun4v/vm/mach_kpm.c
--- 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*/