777 #define __USER_MEMORY_GUARDS_ENABLED__ |
777 #define __USER_MEMORY_GUARDS_ENABLED__ |
778 #endif |
778 #endif |
779 #endif |
779 #endif |
780 #endif // end of (_DEBUG) && !(__KERNEL_APIS_DISABLE_USER_MEMORY_GUARDS__) |
780 #endif // end of (_DEBUG) && !(__KERNEL_APIS_DISABLE_USER_MEMORY_GUARDS__) |
781 |
781 |
782 |
782 #ifndef __USER_MEMORY_GUARDS_ENABLED__ |
783 #ifdef __USER_MEMORY_GUARDS_ENABLED__ |
783 |
784 |
784 #define USER_MEMORY_GUARD_SAVE_WORDS 0 |
785 #define USER_MEMORY_GUARD_ON(cc,save,temp) \ |
785 #define USER_MEMORY_DOMAIN 0 |
786 asm("mrc"#cc" p15, 0, "#save", c3, c0, 0 "); \ |
786 |
787 asm("bic"#cc" "#temp", "#save", #0xc0000000 "); \ |
787 #define USER_MEMORY_GUARD_SAVE(save) |
788 asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0 "); \ |
788 #define USER_MEMORY_GUARD_RESTORE(save,temp) |
789 __INST_SYNC_BARRIER__(save) // Set DACR so no access to domain 15 |
|
790 |
|
791 #define USER_MEMORY_GUARD_OFF(cc,save,temp) \ |
|
792 asm("mrc"#cc" p15, 0, "#save", c3, c0, 0 "); \ |
|
793 asm("orr"#cc" "#temp", "#save", #0x40000000 "); \ |
|
794 asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0 "); \ |
|
795 __INST_SYNC_BARRIER__(save) // Set DACR so client of domain 15 |
|
796 |
|
797 #define USER_MEMORY_GUARD_RESTORE(save,temp) \ |
|
798 asm("mrc p15, 0, "#temp", c3, c0, 0 "); \ |
|
799 asm("and "#save", "#save", #0xc0000000 "); \ |
|
800 asm("bic "#temp", "#temp", #0xc0000000 "); \ |
|
801 asm("orr "#temp", "#temp", "#save ); \ |
|
802 asm("mcr p15, 0, "#temp", c3, c0, 0 "); \ |
|
803 __INST_SYNC_BARRIER__(save) // Restore domain 15 in DACR from value in 'save' |
|
804 |
|
805 #define USER_MEMORY_GUARD_ON_IF_MODE_USR(rd) \ |
|
806 asm("mrs "#rd", spsr"); \ |
|
807 asm("tst "#rd", #0x0f "); \ |
|
808 USER_MEMORY_GUARD_ON(eq,rd,rd) // If spsr is mode_usr then set DACR so no access to domain 15 |
|
809 |
|
810 #define USER_MEMORY_GUARD_OFF_IF_MODE_USR(rd) \ |
|
811 asm("mrs "#rd", spsr"); \ |
|
812 asm("tst "#rd", #0x0f "); \ |
|
813 USER_MEMORY_GUARD_OFF(eq,rd,rd) // If spsr is mode_usr then set DACR so client of domain 15 |
|
814 |
|
815 #else // !__USER_MEMORY_GUARDS_ENABLED__ |
|
816 |
|
817 #define USER_MEMORY_GUARD_ON(cc,save,temp) |
789 #define USER_MEMORY_GUARD_ON(cc,save,temp) |
818 #define USER_MEMORY_GUARD_OFF(cc,save,temp) |
790 #define USER_MEMORY_GUARD_OFF(cc,save,temp) |
819 #define USER_MEMORY_GUARD_RESTORE(save,temp) |
791 #define USER_MEMORY_GUARD_ON_IF_MODE_USR(temp) |
820 #define USER_MEMORY_GUARD_ON_IF_MODE_USR(rd) |
792 #define USER_MEMORY_GUARD_OFF_IF_MODE_USR(temp) |
821 #define USER_MEMORY_GUARD_OFF_IF_MODE_USR(rd) |
793 #define USER_MEMORY_GUARD_ASSERT_ON(temp) |
|
794 #define USER_MEMORY_GUARD_ASSERT_OFF_IF_MODE_USR(psr) |
|
795 |
|
796 #else // __USER_MEMORY_GUARDS_ENABLED__ |
|
797 |
|
798 #define USER_MEMORY_GUARD_SAVE_WORDS 2 |
|
799 #define USER_MEMORY_DOMAIN 15 |
|
800 #define USER_MEMORY_DOMAIN_MASK (3 << (2*USER_MEMORY_DOMAIN)) |
|
801 #define USER_MEMORY_DOMAIN_CLIENT (1 << (2*USER_MEMORY_DOMAIN)) |
|
802 |
|
803 // Save the DACR in the named register |
|
804 #define USER_MEMORY_GUARD_SAVE(save) \ |
|
805 asm("mrc p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ |
|
806 |
|
807 // Restore access to domain 15 (user pages) to the state previously saved |
|
808 // In this case, 'save' may not be the same register as 'temp' |
|
809 #define USER_MEMORY_GUARD_RESTORE(save,temp) \ |
|
810 asm("mrc p15, 0, "#temp", c3, c0, 0"); /* temp<-DACR */ \ |
|
811 asm("bic "#temp", "#temp", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ |
|
812 asm("and "#save", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ |
|
813 asm("orr "#temp", "#temp", "#save ); \ |
|
814 asm("mcr p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ |
|
815 __INST_SYNC_BARRIER__(temp) |
|
816 |
|
817 // Disable access to domain 15 (user pages) |
|
818 // 'save' may be the same register as 'temp', but in that case the use as |
|
819 // a temporary takes precedence and the value left in 'save' is undefined |
|
820 #define USER_MEMORY_GUARD_ON(cc,save,temp) \ |
|
821 asm("mrc"#cc" p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ \ |
|
822 asm("bic"#cc" "#temp", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ |
|
823 asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ |
|
824 __INST_SYNC_BARRIER__(temp) |
|
825 |
|
826 // Enable access to domain 15 (user pages) as a client |
|
827 // 'save' may be the same register as 'temp', but in that case the use as |
|
828 // a temporary takes precedence and the value left in 'save' is undefined |
|
829 #define USER_MEMORY_GUARD_OFF(cc,save,temp) \ |
|
830 asm("mrc"#cc" p15, 0, "#save", c3, c0, 0"); /* save<-DACR */ \ |
|
831 asm("orr"#cc" "#temp", "#save", #%a0" : : "i" USER_MEMORY_DOMAIN_CLIENT); \ |
|
832 asm("mcr"#cc" p15, 0, "#temp", c3, c0, 0"); /* DACR<-temp */ \ |
|
833 __INST_SYNC_BARRIER__(temp) |
|
834 |
|
835 // Disable access to domain 15 (user pages) if SPSR indicates mode_usr |
|
836 // The specified 'temp' register is left with an undefined value |
|
837 #define USER_MEMORY_GUARD_ON_IF_MODE_USR(temp) \ |
|
838 asm("mrs "#temp", spsr"); \ |
|
839 asm("tst "#temp", #0x0f"); \ |
|
840 USER_MEMORY_GUARD_ON(eq,temp,temp) |
|
841 |
|
842 // Enable access to domain 15 (user pages) if SPSR indicates mode_usr |
|
843 // The specified 'temp' register is left with an undefined value |
|
844 #define USER_MEMORY_GUARD_OFF_IF_MODE_USR(temp) \ |
|
845 asm("mrs "#temp", spsr"); \ |
|
846 asm("tst "#temp", #0x0f"); \ |
|
847 USER_MEMORY_GUARD_OFF(eq,temp,temp) |
|
848 |
|
849 // Assert that access to domain 15 (user pages) is disabled |
|
850 #define USER_MEMORY_GUARD_ASSERT_ON(temp) \ |
|
851 asm("mrc p15, 0, "#temp", c3, c0, 0"); /* temp<-DACR */ \ |
|
852 asm("tst "#temp", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ |
|
853 asm("cdpne p15, 0, c0, c0, c0, 0"); /* fault if nonzero */ |
|
854 |
|
855 // Assert that access to domain 15 (user pages) is enabled if the value |
|
856 // in 'psr' says we came from/are going back to user mode |
|
857 #define USER_MEMORY_GUARD_ASSERT_OFF_IF_MODE_USR(psr) \ |
|
858 asm("tst "#psr", #0x0f"); /* check for mode_usr */ \ |
|
859 asm("mrceq p15, 0, "#psr", c3, c0, 0"); /* psr<-DACR */ \ |
|
860 asm("tsteq "#psr", #%a0" : : "i" USER_MEMORY_DOMAIN_MASK); \ |
|
861 asm("cdpeq p15, 0, c0, c0, c0, 0"); /* fault if no access */ |
822 |
862 |
823 #endif // end of else __USER_MEMORY_GUARDS_ENABLED__ |
863 #endif // end of else __USER_MEMORY_GUARDS_ENABLED__ |
824 |
864 |
825 #endif // End of file |
865 #endif // __NK_CPU_H__ |