diff options
Diffstat (limited to 'arch/arm/include')
| -rw-r--r-- | arch/arm/include/asm/assembler.h | 30 | ||||
| -rw-r--r-- | arch/arm/include/asm/domain.h | 21 | ||||
| -rw-r--r-- | arch/arm/include/asm/uaccess.h | 14 |
3 files changed, 63 insertions, 2 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index a91177043467..3ae0eda5e64f 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
| @@ -446,15 +446,45 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) | |||
| 446 | .endm | 446 | .endm |
| 447 | 447 | ||
| 448 | .macro uaccess_disable, tmp, isb=1 | 448 | .macro uaccess_disable, tmp, isb=1 |
| 449 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 450 | /* | ||
| 451 | * Whenever we re-enter userspace, the domains should always be | ||
| 452 | * set appropriately. | ||
| 453 | */ | ||
| 454 | mov \tmp, #DACR_UACCESS_DISABLE | ||
| 455 | mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register | ||
| 456 | .if \isb | ||
| 457 | instr_sync | ||
| 458 | .endif | ||
| 459 | #endif | ||
| 449 | .endm | 460 | .endm |
| 450 | 461 | ||
| 451 | .macro uaccess_enable, tmp, isb=1 | 462 | .macro uaccess_enable, tmp, isb=1 |
| 463 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 464 | /* | ||
| 465 | * Whenever we re-enter userspace, the domains should always be | ||
| 466 | * set appropriately. | ||
| 467 | */ | ||
| 468 | mov \tmp, #DACR_UACCESS_ENABLE | ||
| 469 | mcr p15, 0, \tmp, c3, c0, 0 | ||
| 470 | .if \isb | ||
| 471 | instr_sync | ||
| 472 | .endif | ||
| 473 | #endif | ||
| 452 | .endm | 474 | .endm |
| 453 | 475 | ||
| 454 | .macro uaccess_save, tmp | 476 | .macro uaccess_save, tmp |
| 477 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 478 | mrc p15, 0, \tmp, c3, c0, 0 | ||
| 479 | str \tmp, [sp, #S_FRAME_SIZE] | ||
| 480 | #endif | ||
| 455 | .endm | 481 | .endm |
| 456 | 482 | ||
| 457 | .macro uaccess_restore | 483 | .macro uaccess_restore |
| 484 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 485 | ldr r0, [sp, #S_FRAME_SIZE] | ||
| 486 | mcr p15, 0, r0, c3, c0, 0 | ||
| 487 | #endif | ||
| 458 | .endm | 488 | .endm |
| 459 | 489 | ||
| 460 | .macro uaccess_save_and_disable, tmp | 490 | .macro uaccess_save_and_disable, tmp |
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index 2be929549938..e878129f2fee 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h | |||
| @@ -57,11 +57,29 @@ | |||
| 57 | #define domain_mask(dom) ((3) << (2 * (dom))) | 57 | #define domain_mask(dom) ((3) << (2 * (dom))) |
| 58 | #define domain_val(dom,type) ((type) << (2 * (dom))) | 58 | #define domain_val(dom,type) ((type) << (2 * (dom))) |
| 59 | 59 | ||
| 60 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 61 | #define DACR_INIT \ | ||
| 62 | (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \ | ||
| 63 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ | ||
| 64 | domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \ | ||
| 65 | domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)) | ||
| 66 | #else | ||
| 60 | #define DACR_INIT \ | 67 | #define DACR_INIT \ |
| 61 | (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ | 68 | (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ |
| 62 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ | 69 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ |
| 63 | domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \ | 70 | domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \ |
| 64 | domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)) | 71 | domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)) |
| 72 | #endif | ||
| 73 | |||
| 74 | #define __DACR_DEFAULT \ | ||
| 75 | domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \ | ||
| 76 | domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \ | ||
| 77 | domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT) | ||
| 78 | |||
| 79 | #define DACR_UACCESS_DISABLE \ | ||
| 80 | (__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) | ||
| 81 | #define DACR_UACCESS_ENABLE \ | ||
| 82 | (__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_CLIENT)) | ||
| 65 | 83 | ||
| 66 | #ifndef __ASSEMBLY__ | 84 | #ifndef __ASSEMBLY__ |
| 67 | 85 | ||
| @@ -76,7 +94,6 @@ static inline unsigned int get_domain(void) | |||
| 76 | return domain; | 94 | return domain; |
| 77 | } | 95 | } |
| 78 | 96 | ||
| 79 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
| 80 | static inline void set_domain(unsigned val) | 97 | static inline void set_domain(unsigned val) |
| 81 | { | 98 | { |
| 82 | asm volatile( | 99 | asm volatile( |
| @@ -85,6 +102,7 @@ static inline void set_domain(unsigned val) | |||
| 85 | isb(); | 102 | isb(); |
| 86 | } | 103 | } |
| 87 | 104 | ||
| 105 | #ifdef CONFIG_CPU_USE_DOMAINS | ||
| 88 | #define modify_domain(dom,type) \ | 106 | #define modify_domain(dom,type) \ |
| 89 | do { \ | 107 | do { \ |
| 90 | unsigned int domain = get_domain(); \ | 108 | unsigned int domain = get_domain(); \ |
| @@ -94,7 +112,6 @@ static inline void set_domain(unsigned val) | |||
| 94 | } while (0) | 112 | } while (0) |
| 95 | 113 | ||
| 96 | #else | 114 | #else |
| 97 | static inline void set_domain(unsigned val) { } | ||
| 98 | static inline void modify_domain(unsigned dom, unsigned type) { } | 115 | static inline void modify_domain(unsigned dom, unsigned type) { } |
| 99 | #endif | 116 | #endif |
| 100 | 117 | ||
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 82880132f941..01bae13b2cea 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
| @@ -57,11 +57,25 @@ extern int fixup_exception(struct pt_regs *regs); | |||
| 57 | */ | 57 | */ |
| 58 | static inline unsigned int uaccess_save_and_enable(void) | 58 | static inline unsigned int uaccess_save_and_enable(void) |
| 59 | { | 59 | { |
| 60 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 61 | unsigned int old_domain = get_domain(); | ||
| 62 | |||
| 63 | /* Set the current domain access to permit user accesses */ | ||
| 64 | set_domain((old_domain & ~domain_mask(DOMAIN_USER)) | | ||
| 65 | domain_val(DOMAIN_USER, DOMAIN_CLIENT)); | ||
| 66 | |||
| 67 | return old_domain; | ||
| 68 | #else | ||
| 60 | return 0; | 69 | return 0; |
| 70 | #endif | ||
| 61 | } | 71 | } |
| 62 | 72 | ||
| 63 | static inline void uaccess_restore(unsigned int flags) | 73 | static inline void uaccess_restore(unsigned int flags) |
| 64 | { | 74 | { |
| 75 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 76 | /* Restore the user access mask */ | ||
| 77 | set_domain(flags); | ||
| 78 | #endif | ||
| 65 | } | 79 | } |
| 66 | 80 | ||
| 67 | /* | 81 | /* |
