diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-12-03 09:34:45 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-12-04 14:20:48 -0500 |
| commit | 77f1b959b0b6db7a7941b4b4f9d3d287c67d7c15 (patch) | |
| tree | 21189c499624902027284f01f3606b0d66b71ec4 | |
| parent | 08925c2f124f1bac6152a8b234268f9874fc70a5 (diff) | |
ARM: report proper DACR value in oops dumps
When printing the DACR value, we print the domain register value.
This is incorrect, as with SW_PAN enabled, that is the current setting,
rather than the faulting context's setting. Arrange to print the
faulting domain's saved DACR value instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/kernel/process.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 7a7c4cea5523..4adfb46e3ee9 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
| @@ -95,6 +95,22 @@ void __show_regs(struct pt_regs *regs) | |||
| 95 | { | 95 | { |
| 96 | unsigned long flags; | 96 | unsigned long flags; |
| 97 | char buf[64]; | 97 | char buf[64]; |
| 98 | #ifndef CONFIG_CPU_V7M | ||
| 99 | unsigned int domain; | ||
| 100 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 101 | /* | ||
| 102 | * Get the domain register for the parent context. In user | ||
| 103 | * mode, we don't save the DACR, so lets use what it should | ||
| 104 | * be. For other modes, we place it after the pt_regs struct. | ||
| 105 | */ | ||
| 106 | if (user_mode(regs)) | ||
| 107 | domain = DACR_UACCESS_ENABLE; | ||
| 108 | else | ||
| 109 | domain = *(unsigned int *)(regs + 1); | ||
| 110 | #else | ||
| 111 | domain = get_domain(); | ||
| 112 | #endif | ||
| 113 | #endif | ||
| 98 | 114 | ||
| 99 | show_regs_print_info(KERN_DEFAULT); | 115 | show_regs_print_info(KERN_DEFAULT); |
| 100 | 116 | ||
| @@ -123,21 +139,8 @@ void __show_regs(struct pt_regs *regs) | |||
| 123 | 139 | ||
| 124 | #ifndef CONFIG_CPU_V7M | 140 | #ifndef CONFIG_CPU_V7M |
| 125 | { | 141 | { |
| 126 | unsigned int domain = get_domain(); | ||
| 127 | const char *segment; | 142 | const char *segment; |
| 128 | 143 | ||
| 129 | #ifdef CONFIG_CPU_SW_DOMAIN_PAN | ||
| 130 | /* | ||
| 131 | * Get the domain register for the parent context. In user | ||
| 132 | * mode, we don't save the DACR, so lets use what it should | ||
| 133 | * be. For other modes, we place it after the pt_regs struct. | ||
| 134 | */ | ||
| 135 | if (user_mode(regs)) | ||
| 136 | domain = DACR_UACCESS_ENABLE; | ||
| 137 | else | ||
| 138 | domain = *(unsigned int *)(regs + 1); | ||
| 139 | #endif | ||
| 140 | |||
| 141 | if ((domain & domain_mask(DOMAIN_USER)) == | 144 | if ((domain & domain_mask(DOMAIN_USER)) == |
| 142 | domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) | 145 | domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) |
| 143 | segment = "none"; | 146 | segment = "none"; |
| @@ -163,11 +166,11 @@ void __show_regs(struct pt_regs *regs) | |||
| 163 | buf[0] = '\0'; | 166 | buf[0] = '\0'; |
| 164 | #ifdef CONFIG_CPU_CP15_MMU | 167 | #ifdef CONFIG_CPU_CP15_MMU |
| 165 | { | 168 | { |
| 166 | unsigned int transbase, dac = get_domain(); | 169 | unsigned int transbase; |
| 167 | asm("mrc p15, 0, %0, c2, c0\n\t" | 170 | asm("mrc p15, 0, %0, c2, c0\n\t" |
| 168 | : "=r" (transbase)); | 171 | : "=r" (transbase)); |
| 169 | snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", | 172 | snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", |
| 170 | transbase, dac); | 173 | transbase, domain); |
| 171 | } | 174 | } |
| 172 | #endif | 175 | #endif |
| 173 | asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl)); | 176 | asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl)); |
