aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorJoseph Koshy <jkoshy@FreeBSD.org>2006-03-26 12:20:54 +0000
committerJoseph Koshy <jkoshy@FreeBSD.org>2006-03-26 12:20:54 +0000
commit49874f6ea3d305366e9e829e2b93832c99a9c40d (patch)
treec2617fc6b46499b2b7e9b7d1145b96e592acedb1 /sys/vm
parent6882aa2c035756ef80031e97c7566dd41ea902e8 (diff)
Notes
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_mmap.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 9379c3b57b2f..33f387ede9ad 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -44,6 +44,7 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_hwpmc_hooks.h"
#include "opt_mac.h"
#include <sys/param.h>
@@ -79,6 +80,10 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
+#ifdef HWPMC_HOOKS
+#include <sys/pmckern.h>
+#endif
+
#ifndef _SYS_SYSPROTO_H_
struct sbrk_args {
int incr;
@@ -201,6 +206,9 @@ mmap(td, uap)
struct thread *td;
struct mmap_args *uap;
{
+#ifdef HWPMC_HOOKS
+ struct pmckern_map_in pkm;
+#endif
struct file *fp;
struct vnode *vp;
vm_offset_t addr;
@@ -364,6 +372,15 @@ mmap(td, uap)
error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
flags, handle_type, handle, pos);
+#ifdef HWPMC_HOOKS
+ /* inform hwpmc(4) if an executable is being mapped */
+ if (error == 0 && handle_type == OBJT_VNODE &&
+ (prot & PROT_EXEC)) {
+ pkm.pm_file = handle;
+ pkm.pm_address = (uintptr_t) addr;
+ PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm);
+ }
+#endif
if (error == 0)
td->td_retval[0] = (register_t) (addr + pageoff);
done:
@@ -495,6 +512,10 @@ munmap(td, uap)
struct thread *td;
struct munmap_args *uap;
{
+#ifdef HWPMC_HOOKS
+ struct pmckern_map_out pkm;
+ vm_map_entry_t entry;
+#endif
vm_offset_t addr;
vm_size_t size, pageoff;
vm_map_t map;
@@ -525,6 +546,26 @@ munmap(td, uap)
vm_map_unlock(map);
return (EINVAL);
}
+#ifdef HWPMC_HOOKS
+ /*
+ * Inform hwpmc if the address range being unmapped contains
+ * an executable region.
+ */
+ if (vm_map_lookup_entry(map, addr, &entry)) {
+ for (;
+ entry != &map->header && entry->start < addr + size;
+ entry = entry->next) {
+ if (vm_map_check_protection(map, entry->start,
+ entry->end, VM_PROT_EXECUTE) == TRUE) {
+ pkm.pm_address = (uintptr_t) addr;
+ pkm.pm_size = (size_t) size;
+ PMC_CALL_HOOK(td, PMC_FN_MUNMAP,
+ (void *) &pkm);
+ break;
+ }
+ }
+ }
+#endif
/* returns nothing but KERN_SUCCESS anyway */
vm_map_delete(map, addr, addr + size);
vm_map_unlock(map);