diff -r 4122176ea935 -r 56f325a607ea kernel/eka/include/nkern/nk_cpu.h --- a/kernel/eka/include/nkern/nk_cpu.h Mon Dec 21 16:14:42 2009 +0000 +++ b/kernel/eka/include/nkern/nk_cpu.h Wed Dec 23 11:43:31 2009 +0000 @@ -779,47 +779,87 @@ #endif #endif // end of (_DEBUG) && !(__KERNEL_APIS_DISABLE_USER_MEMORY_GUARDS__) - -#ifdef __USER_MEMORY_GUARDS_ENABLED__ - -#define USER_MEMORY_GUARD_ON(cc,save,temp) \ - asm("mrc"#cc" p15, 0, "#save", c3, c0, 0 "); \ - asm("bic"#cc" "#temp", "#save", #0xc0000000 "); \ - asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0 "); \ - __INST_SYNC_BARRIER__(save) // Set DACR so no access to domain 15 - -#define USER_MEMORY_GUARD_OFF(cc,save,temp) \ - asm("mrc"#cc" p15, 0, "#save", c3, c0, 0 "); \ - asm("orr"#cc" "#temp", "#save", #0x40000000 "); \ - asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0 "); \ - __INST_SYNC_BARRIER__(save) // Set DACR so client of domain 15 +#ifndef __USER_MEMORY_GUARDS_ENABLED__ -#define USER_MEMORY_GUARD_RESTORE(save,temp) \ - asm("mrc p15, 0, "#temp", c3, c0, 0 "); \ - asm("and "#save", "#save", #0xc0000000 "); \ - asm("bic "#temp", "#temp", #0xc0000000 "); \ - asm("orr "#temp", "#temp", "#save ); \ - asm("mcr p15, 0, "#temp", c3, c0, 0 "); \ - __INST_SYNC_BARRIER__(save) // Restore domain 15 in DACR from value in 'save' +#define USER_MEMORY_GUARD_SAVE_WORDS 0 +#define USER_MEMORY_DOMAIN 0 -#define USER_MEMORY_GUARD_ON_IF_MODE_USR(rd) \ - asm("mrs "#rd", spsr"); \ - asm("tst "#rd", #0x0f "); \ - USER_MEMORY_GUARD_ON(eq,rd,rd) // If spsr is mode_usr then set DACR so no access to domain 15 - -#define USER_MEMORY_GUARD_OFF_IF_MODE_USR(rd) \ - asm("mrs "#rd", spsr"); \ - asm("tst "#rd", #0x0f "); \ - USER_MEMORY_GUARD_OFF(eq,rd,rd) // If spsr is mode_usr then set DACR so client of domain 15 - -#else // !__USER_MEMORY_GUARDS_ENABLED__ - +#define USER_MEMORY_GUARD_SAVE(save) +#define USER_MEMORY_GUARD_RESTORE(save,temp) #define USER_MEMORY_GUARD_ON(cc,save,temp) #define USER_MEMORY_GUARD_OFF(cc,save,temp) -#define USER_MEMORY_GUARD_RESTORE(save,temp) -#define USER_MEMORY_GUARD_ON_IF_MODE_USR(rd) -#define USER_MEMORY_GUARD_OFF_IF_MODE_USR(rd) +#define USER_MEMORY_GUARD_ON_IF_MODE_USR(temp) +#define USER_MEMORY_GUARD_OFF_IF_MODE_USR(temp) +#define USER_MEMORY_GUARD_ASSERT_ON(temp) +#define USER_MEMORY_GUARD_ASSERT_OFF_IF_MODE_USR(psr) + +#else // __USER_MEMORY_GUARDS_ENABLED__ + +#define USER_MEMORY_GUARD_SAVE_WORDS 2 +#define USER_MEMORY_DOMAIN 15 +#define USER_MEMORY_DOMAIN_MASK (3 << (2*USER_MEMORY_DOMAIN)) +#define USER_MEMORY_DOMAIN_CLIENT (1 << (2*USER_MEMORY_DOMAIN)) + +// Save the DACR in the named register +#define USER_MEMORY_GUARD_SAVE(save) \ + asm("mrc p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ + +// Restore access to domain 15 (user pages) to the state previously saved +// In this case, 'save' may not be the same register as 'temp' +#define USER_MEMORY_GUARD_RESTORE(save,temp) \ + asm("mrc p15, 0, "#temp", c3, c0, 0"); /* temp<-DACR */ \ + asm("bic "#temp", "#temp", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ + asm("and "#save", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ + asm("orr "#temp", "#temp", "#save ); \ + asm("mcr p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ + __INST_SYNC_BARRIER__(temp) + +// Disable access to domain 15 (user pages) +// 'save' may be the same register as 'temp', but in that case the use as +// a temporary takes precedence and the value left in 'save' is undefined +#define USER_MEMORY_GUARD_ON(cc,save,temp) \ + asm("mrc"#cc" p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ \ + asm("bic"#cc" "#temp", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ + asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ + __INST_SYNC_BARRIER__(temp) + +// Enable access to domain 15 (user pages) as a client +// 'save' may be the same register as 'temp', but in that case the use as +// a temporary takes precedence and the value left in 'save' is undefined +#define USER_MEMORY_GUARD_OFF(cc,save,temp) \ + asm("mrc"#cc" p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ \ + asm("orr"#cc" "#temp", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_CLIENT); \ + asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ + __INST_SYNC_BARRIER__(temp) + +// Disable access to domain 15 (user pages) if SPSR indicates mode_usr +// The specified 'temp' register is left with an undefined value +#define USER_MEMORY_GUARD_ON_IF_MODE_USR(temp) \ + asm("mrs "#temp", spsr"); \ + asm("tst "#temp", #0x0f"); \ + USER_MEMORY_GUARD_ON(eq,temp,temp) + +// Enable access to domain 15 (user pages) if SPSR indicates mode_usr +// The specified 'temp' register is left with an undefined value +#define USER_MEMORY_GUARD_OFF_IF_MODE_USR(temp) \ + asm("mrs "#temp", spsr"); \ + asm("tst "#temp", #0x0f"); \ + USER_MEMORY_GUARD_OFF(eq,temp,temp) + +// Assert that access to domain 15 (user pages) is disabled +#define USER_MEMORY_GUARD_ASSERT_ON(temp) \ + asm("mrc p15, 0, "#temp", c3, c0, 0"); /* temp<-DACR */ \ + asm("tst "#temp", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ + asm("cdpne p15, 0, c0, c0, c0, 0"); /* fault if nonzero */ + +// Assert that access to domain 15 (user pages) is enabled if the value +// in 'psr' says we came from/are going back to user mode +#define USER_MEMORY_GUARD_ASSERT_OFF_IF_MODE_USR(psr) \ + asm("tst "#psr", #0x0f"); /* check for mode_usr */ \ + asm("mrceq p15, 0, "#psr", c3, c0, 0"); /* psr<-DACR */ \ + asm("tsteq "#psr", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ + asm("cdpeq p15, 0, c0, c0, c0, 0"); /* fault if no access */ #endif // end of else __USER_MEMORY_GUARDS_ENABLED__ -#endif // End of file +#endif // __NK_CPU_H__