Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/pmap.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 699 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct pmap_invl_gen *invl_gen; | struct pmap_invl_gen *invl_gen; | ||||
invl_gen = &td->td_md.md_invl_gen; | invl_gen = &td->td_md.md_invl_gen; | ||||
invl_gen->gen = 0; | invl_gen->gen = 0; | ||||
invl_gen->next = (void *)PMAP_INVL_GEN_NEXT_INVALID; | invl_gen->next = (void *)PMAP_INVL_GEN_NEXT_INVALID; | ||||
} | } | ||||
/* Copied from atomic.h. */ | |||||
#ifdef __GCC_ASM_FLAG_OUTPUTS__ | |||||
#define CC_FLAG_OUT_INST(cc, loc) | |||||
#define CC_FLAG_OUT_CONS(cc) "=@cc" #cc | |||||
#else | |||||
#define CC_FLAG_OUT_INST(cc, loc) "set" #cc " " loc " ; " | |||||
#define CC_FLAG_OUT_CONS(cc) "=q" | |||||
#endif | |||||
static bool | static bool | ||||
pmap_di_load_invl(struct pmap_invl_gen *ptr, struct pmap_invl_gen *out) | pmap_di_load_invl(struct pmap_invl_gen *ptr, struct pmap_invl_gen *out) | ||||
{ | { | ||||
uint64_t new_high, new_low, old_high, old_low; | uint64_t new_high, new_low, old_high, old_low; | ||||
char res; | char res; | ||||
old_low = new_low = 0; | old_low = new_low = 0; | ||||
old_high = new_high = (uintptr_t)0; | old_high = new_high = (uintptr_t)0; | ||||
__asm volatile("lock;cmpxchg16b\t%1" | __asm volatile("lock;cmpxchg16b\t%1;" CC_FLAG_OUT_INST(e, "%0") | ||||
: "=@cce" (res), "+m" (*ptr), "+a" (old_low), "+d" (old_high) | : CC_FLAG_OUT_CONS(e) (res), "+m" (*ptr), "+a" (old_low), | ||||
"+d" (old_high) | |||||
: "b"(new_low), "c" (new_high) | : "b"(new_low), "c" (new_high) | ||||
: "memory", "cc"); | : "memory", "cc"); | ||||
if (res == 0) { | if (res == 0) { | ||||
if ((old_high & PMAP_INVL_GEN_NEXT_INVALID) != 0) | if ((old_high & PMAP_INVL_GEN_NEXT_INVALID) != 0) | ||||
return (false); | return (false); | ||||
out->gen = old_low; | out->gen = old_low; | ||||
out->next = (void *)old_high; | out->next = (void *)old_high; | ||||
} else { | } else { | ||||
Show All 10 Lines | pmap_di_store_invl(struct pmap_invl_gen *ptr, struct pmap_invl_gen *old_val, | ||||
uint64_t new_high, new_low, old_high, old_low; | uint64_t new_high, new_low, old_high, old_low; | ||||
char res; | char res; | ||||
new_low = new_val->gen; | new_low = new_val->gen; | ||||
new_high = (uintptr_t)new_val->next; | new_high = (uintptr_t)new_val->next; | ||||
old_low = old_val->gen; | old_low = old_val->gen; | ||||
old_high = (uintptr_t)old_val->next; | old_high = (uintptr_t)old_val->next; | ||||
__asm volatile("lock;cmpxchg16b\t%1" | __asm volatile("lock;cmpxchg16b\t%1;" CC_FLAG_OUT_INST(e, "%0") | ||||
: "=@cce" (res), "+m" (*ptr), "+a" (old_low), "+d" (old_high) | : CC_FLAG_OUT_CONS(e) (res), "+m" (*ptr), "+a" (old_low), | ||||
"+d" (old_high) | |||||
: "b"(new_low), "c" (new_high) | : "b"(new_low), "c" (new_high) | ||||
: "memory", "cc"); | : "memory", "cc"); | ||||
return (res); | return (res); | ||||
} | } | ||||
#ifdef PV_STATS | #ifdef PV_STATS | ||||
static long invl_start_restart; | static long invl_start_restart; | ||||
SYSCTL_LONG(_vm_pmap, OID_AUTO, invl_start_restart, CTLFLAG_RD, | SYSCTL_LONG(_vm_pmap, OID_AUTO, invl_start_restart, CTLFLAG_RD, | ||||
▲ Show 20 Lines • Show All 9,917 Lines • Show Last 20 Lines |