From ac249405a2ec766b361d942bc84cfde991b8e3a0 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Sun, 26 Jun 2011 02:37:34 +0200
Subject: [PATCH 13/18] kernel: Some more additions in preparation for hwpmc.

* Add TRAPF_USERMODE() and VM_{MIN,MAX}_KERNEL_ADDRESS() macros.

* Add linker_hwpmc_list_objects() and hashdestroy() functions.

In-collaboration-with: aggelos
---
 sys/cpu/i386/include/cpu.h          |    4 ++-
 sys/cpu/x86_64/include/cpu.h        |    4 ++-
 sys/kern/kern_linker.c              |   39 +++++++++++++++++++++++++++++++++++
 sys/kern/kern_subr.c                |   12 ++++++++++
 sys/platform/pc32/include/vmparam.h |    4 ++-
 sys/sys/linker.h                    |    2 +
 sys/sys/systm.h                     |    1 +
 7 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/sys/cpu/i386/include/cpu.h b/sys/cpu/i386/include/cpu.h
index 485bd18..51cb0bb 100644
--- a/sys/cpu/i386/include/cpu.h
+++ b/sys/cpu/i386/include/cpu.h
@@ -35,7 +35,6 @@
  *
  *	from: @(#)cpu.h	5.4 (Berkeley) 5/9/91
  * $FreeBSD: src/sys/i386/include/cpu.h,v 1.43.2.2 2001/06/15 09:37:57 scottl Exp $
- * $DragonFly: src/sys/cpu/i386/include/cpu.h,v 1.25 2007/03/01 01:46:52 corecode Exp $
  */
 
 #ifndef _CPU_CPU_H_
@@ -66,6 +65,9 @@
 #define CLKF_INTR(intr_nest)	((intr_nest) > 1 || (curthread->td_flags & TDF_INTTHREAD))
 #define	CLKF_PC(framep)		((framep)->if_eip)
 
+#define	TRAPF_USERMODE(framep) \
+	((ISPL((framep)->tf_cs) == SEL_UPL) || ((framep)->tf_eflags & PSL_VM))
+
 /*
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
diff --git a/sys/cpu/x86_64/include/cpu.h b/sys/cpu/x86_64/include/cpu.h
index 7cd162c..1fe4e9e 100644
--- a/sys/cpu/x86_64/include/cpu.h
+++ b/sys/cpu/x86_64/include/cpu.h
@@ -35,7 +35,6 @@
  *
  *	from: @(#)cpu.h	5.4 (Berkeley) 5/9/91
  * $FreeBSD: src/sys/i386/include/cpu.h,v 1.43.2.2 2001/06/15 09:37:57 scottl Exp $
- * $DragonFly: src/sys/cpu/i386/include/cpu.h,v 1.25 2007/03/01 01:46:52 corecode Exp $
  */
 
 #ifndef _CPU_CPU_H_
@@ -66,6 +65,9 @@
 #define CLKF_INTR(intr_nest)	((intr_nest) > 1 || (curthread->td_flags & TDF_INTTHREAD))
 #define	CLKF_PC(framep)		((framep)->if_rip)
 
+#define	TRAPF_USERMODE(framep) \
+	(ISPL((framep)->tf_cs) == SEL_UPL)
+
 /*
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 9fb83c8..79bc231 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -1456,6 +1456,45 @@ linker_search_path(const char *name)
     return(NULL);
 }
 
+#ifdef HWPMC_HOOKS
+/*
+ * Inform hwpmc about the set of kernel modules currently loaded.
+ */
+void *
+linker_hwpmc_list_objects(void)
+{
+	linker_file_t lf;
+	struct pmckern_map_in *kobase;
+	int i, nmappings;
+
+	nmappings = 0;
+	lockmgr(&lock, LK_SHARED);
+	TAILQ_FOREACH(lf, &linker_files, link)
+		nmappings++;
+
+	/* Allocate nmappings + 1 entries. */
+	kobase = kmalloc((nmappings + 1) * sizeof(struct pmckern_map_in),
+	    M_LINKER, M_WAITOK | M_ZERO);
+	i = 0;
+	TAILQ_FOREACH(lf, &linker_files, link) {
+
+		/* Save the info for this linker file. */
+		kobase[i].pm_file = lf->filename;
+		kobase[i].pm_address = (uintptr_t)lf->address;
+		i++;
+	}
+	lockmgr(&lock, LK_RELEASE);
+
+	KASSERT(i > 0, ("linker_hpwmc_list_objects: no kernel objects?"));
+
+	/* The last entry of the malloced area comprises of all zeros. */
+	KASSERT(kobase[i].pm_file == NULL,
+	    ("linker_hwpmc_list_objects: last object not NULL"));
+
+	return ((void *)kobase);
+}
+#endif
+
 /*
  * Find a file which contains given module and load it, if "parent" is not
  * NULL, register a reference to it.
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 71e09a4..06b6e81 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -289,6 +289,18 @@ hashinit_ext(int elements, size_t size, struct malloc_type *type,
 	return (hashtbl);
 }
 
+void
+hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
+{
+        LIST_HEAD(generic, generic) *hashtbl, *hp;
+
+        hashtbl = vhashtbl;
+        for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
+                if (!LIST_EMPTY(hp))
+                        panic("hashdestroy: hash not empty");
+        kfree(hashtbl, type);
+}
+
 static int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531, 2039,
 			2557, 3067, 3583, 4093, 4603, 5119, 5623, 6143, 6653,
 			7159, 7673, 8191, 12281, 16381, 24571, 32749 };
diff --git a/sys/platform/pc32/include/vmparam.h b/sys/platform/pc32/include/vmparam.h
index d5c378f..803a158 100644
--- a/sys/platform/pc32/include/vmparam.h
+++ b/sys/platform/pc32/include/vmparam.h
@@ -37,7 +37,6 @@
  *
  *	from: @(#)vmparam.h	5.9 (Berkeley) 5/12/91
  * $FreeBSD: src/sys/i386/include/vmparam.h,v 1.32.2.1 2000/04/02 08:47:01 peter Exp $
- * $DragonFly: src/sys/platform/pc32/include/vmparam.h,v 1.9 2006/12/28 18:29:06 dillon Exp $
  */
 
 
@@ -96,6 +95,9 @@
 #define KPT_MAX_ADDRESS		VADDR(PTDPTDI, KPTDI+NKPT)
 #define KPT_MIN_ADDRESS		VADDR(PTDPTDI, KPTDI)
 
+#define VM_MAX_KERNEL_ADDRESS	VADDR(KPTDI+NKPDE-1, NPTEPG-1)
+#define VM_MIN_KERNEL_ADDRESS	VADDR(PTDPTDI, PTDPTDI)
+
 #define UPT_MAX_ADDRESS		VADDR(PTDPTDI, PTDPTDI)
 #define UPT_MIN_ADDRESS		VADDR(PTDPTDI, 0)
 
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index d1e59c2..5aeb1e6 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -253,6 +253,8 @@ int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym,
 			     long *_diffp);
 int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval);
 
+/* HWPMC helper */
+void *linker_hwpmc_list_objects(void);
 
 #endif	/* _KERNEL */
 
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index f2905ea..0470206 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -150,6 +150,7 @@ void	mi_proc0init(struct globaldata *gd, struct user *proc0paddr);
 int	nullop (void);
 int	seltrue (cdev_t dev, int which);
 int	ureadc (int, struct uio *);
+void    hashdestroy(void *, struct malloc_type *, u_long);
 void	*hashinit (int count, struct malloc_type *type, u_long *hashmask);
 void	*phashinit (int count, struct malloc_type *type, u_long *nentries);
 void	*hashinit_ext (int count, size_t size,
-- 
1.7.0.5

