hwpmc: partially depessimize munmap handling if the module is not loaded
HWPMC_HOOKS is enabled in GENERIC and triggers some work avoidable in the common (module not loaded) case. In particular this avoids permission checks + lock downgrade singlethreaded and in cases were an executable mapping is found the pmc sx lock is no longer bounced. Note this is a band aid. MFC after: 1 week
This commit is contained in:
parent
543b2f425d
commit
736ff8c396
@ -174,6 +174,9 @@ extern const int pmc_kernel_version;
|
|||||||
/* PMC soft per cpu trapframe */
|
/* PMC soft per cpu trapframe */
|
||||||
extern struct trapframe pmc_tf[MAXCPU];
|
extern struct trapframe pmc_tf[MAXCPU];
|
||||||
|
|
||||||
|
/* Quick check if preparatory work is necessary */
|
||||||
|
#define PMC_HOOK_INSTALLED(cmd) __predict_false(pmc_hook != NULL)
|
||||||
|
|
||||||
/* Hook invocation; for use within the kernel */
|
/* Hook invocation; for use within the kernel */
|
||||||
#define PMC_CALL_HOOK(t, cmd, arg) \
|
#define PMC_CALL_HOOK(t, cmd, arg) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -526,6 +526,7 @@ sys_munmap(td, uap)
|
|||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
struct pmckern_map_out pkm;
|
struct pmckern_map_out pkm;
|
||||||
vm_map_entry_t entry;
|
vm_map_entry_t entry;
|
||||||
|
bool pmc_handled;
|
||||||
#endif
|
#endif
|
||||||
vm_offset_t addr;
|
vm_offset_t addr;
|
||||||
vm_size_t size, pageoff;
|
vm_size_t size, pageoff;
|
||||||
@ -551,6 +552,9 @@ sys_munmap(td, uap)
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
vm_map_lock(map);
|
vm_map_lock(map);
|
||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
|
pmc_handled = false;
|
||||||
|
if (PMC_HOOK_INSTALLED(PMC_FN_MUNMAP)) {
|
||||||
|
pmc_handled = true;
|
||||||
/*
|
/*
|
||||||
* Inform hwpmc if the address range being unmapped contains
|
* Inform hwpmc if the address range being unmapped contains
|
||||||
* an executable region.
|
* an executable region.
|
||||||
@ -568,18 +572,21 @@ sys_munmap(td, uap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
vm_map_delete(map, addr, addr + size);
|
vm_map_delete(map, addr, addr + size);
|
||||||
|
|
||||||
#ifdef HWPMC_HOOKS
|
#ifdef HWPMC_HOOKS
|
||||||
|
if (__predict_false(pmc_handled)) {
|
||||||
/* downgrade the lock to prevent a LOR with the pmc-sx lock */
|
/* downgrade the lock to prevent a LOR with the pmc-sx lock */
|
||||||
vm_map_lock_downgrade(map);
|
vm_map_lock_downgrade(map);
|
||||||
if (pkm.pm_address != (uintptr_t) NULL)
|
if (pkm.pm_address != (uintptr_t) NULL)
|
||||||
PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm);
|
PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm);
|
||||||
vm_map_unlock_read(map);
|
vm_map_unlock_read(map);
|
||||||
#else
|
} else
|
||||||
vm_map_unlock(map);
|
|
||||||
#endif
|
#endif
|
||||||
|
vm_map_unlock(map);
|
||||||
|
|
||||||
/* vm_map_delete returns nothing but KERN_SUCCESS anyway */
|
/* vm_map_delete returns nothing but KERN_SUCCESS anyway */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user