aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/assembler.h30
-rw-r--r--arch/arm/include/asm/domain.h21
-rw-r--r--arch/arm/include/asm/uaccess.h14
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
80static inline void set_domain(unsigned val) 97static 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
97static inline void set_domain(unsigned val) { }
98static inline void modify_domain(unsigned dom, unsigned type) { } 115static 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 */
58static inline unsigned int uaccess_save_and_enable(void) 58static 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
63static inline void uaccess_restore(unsigned int flags) 73static 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/*