aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2013-09-03 14:45:52 -0400
committerChris Metcalf <cmetcalf@tilera.com>2013-09-03 14:45:52 -0400
commit051168df528fe4456d63f5f65b041c147c26fe97 (patch)
tree789109ca42db49bf4d8c0c2794cf55659a171a39
parent309272f99f3e65b9bb5c49a2901c63a1859172f3 (diff)
tile: don't assume user privilege is zero
Technically, user privilege is anything less than kernel privilege. We modify the existing user_mode() macro to have this semantic (and use it in a couple of places it wasn't being used before), and add an IS_KERNEL_EX1() macro to the assembly code as well. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r--arch/tile/include/asm/processor.h4
-rw-r--r--arch/tile/include/asm/ptrace.h2
-rw-r--r--arch/tile/kernel/intvec_64.S23
-rw-r--r--arch/tile/kernel/stack.c2
-rw-r--r--arch/tile/mm/fault.c4
5 files changed, 23 insertions, 12 deletions
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index 230b830e94d4..c72fcba7016a 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -15,6 +15,8 @@
15#ifndef _ASM_TILE_PROCESSOR_H 15#ifndef _ASM_TILE_PROCESSOR_H
16#define _ASM_TILE_PROCESSOR_H 16#define _ASM_TILE_PROCESSOR_H
17 17
18#include <arch/chip.h>
19
18#ifndef __ASSEMBLY__ 20#ifndef __ASSEMBLY__
19 21
20/* 22/*
@@ -25,7 +27,6 @@
25#include <asm/ptrace.h> 27#include <asm/ptrace.h>
26#include <asm/percpu.h> 28#include <asm/percpu.h>
27 29
28#include <arch/chip.h>
29#include <arch/spr_def.h> 30#include <arch/spr_def.h>
30 31
31struct task_struct; 32struct task_struct;
@@ -347,7 +348,6 @@ extern int kdata_huge;
347 348
348/* 349/*
349 * Provide symbolic constants for PLs. 350 * Provide symbolic constants for PLs.
350 * Note that assembly code assumes that USER_PL is zero.
351 */ 351 */
352#define USER_PL 0 352#define USER_PL 0
353#if CONFIG_KERNEL_PL == 2 353#if CONFIG_KERNEL_PL == 2
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
index 0d25c21bcd61..b9620c077abc 100644
--- a/arch/tile/include/asm/ptrace.h
+++ b/arch/tile/include/asm/ptrace.h
@@ -39,7 +39,7 @@ typedef unsigned long pt_reg_t;
39#define user_stack_pointer(regs) ((regs)->sp) 39#define user_stack_pointer(regs) ((regs)->sp)
40 40
41/* Does the process account for user or for system time? */ 41/* Does the process account for user or for system time? */
42#define user_mode(regs) (EX1_PL((regs)->ex1) == USER_PL) 42#define user_mode(regs) (EX1_PL((regs)->ex1) < KERNEL_PL)
43 43
44/* Fill in a struct pt_regs with the current kernel registers. */ 44/* Fill in a struct pt_regs with the current kernel registers. */
45struct pt_regs *get_pt_regs(struct pt_regs *); 45struct pt_regs *get_pt_regs(struct pt_regs *);
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 3b35bb490d3e..f020f01960cf 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -34,6 +34,16 @@
34 34
35#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR) 35#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
36 36
37#if CONFIG_KERNEL_PL == 1 || CONFIG_KERNEL_PL == 2
38/*
39 * Set "result" non-zero if ex1 holds the PL of the kernel
40 * (with or without ICS being set). Note this works only
41 * because we never find the PL at level 3.
42 */
43# define IS_KERNEL_EX1(result, ex1) andi result, ex1, CONFIG_KERNEL_PL
44#else
45# error Recode IS_KERNEL_EX1 for CONFIG_KERNEL_PL
46#endif
37 47
38 .macro push_reg reg, ptr=sp, delta=-8 48 .macro push_reg reg, ptr=sp, delta=-8
39 { 49 {
@@ -308,7 +318,7 @@ intvec_\vecname:
308 */ 318 */
309 { 319 {
310 blbs sp, 2f 320 blbs sp, 2f
311 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 321 IS_KERNEL_EX1(r0, r0)
312 } 322 }
313 323
314 .ifc \vecnum, INT_DOUBLE_FAULT 324 .ifc \vecnum, INT_DOUBLE_FAULT
@@ -641,11 +651,12 @@ intvec_\vecname:
641 /* 651 /*
642 * If we will be returning to the kernel, we will need to 652 * If we will be returning to the kernel, we will need to
643 * reset the interrupt masks to the state they had before. 653 * reset the interrupt masks to the state they had before.
644 * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled. 654 * Set DISABLE_IRQ in flags iff we came from kernel pl with
655 * irqs disabled.
645 */ 656 */
646 mfspr r32, SPR_EX_CONTEXT_K_1 657 mfspr r32, SPR_EX_CONTEXT_K_1
647 { 658 {
648 andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 659 IS_KERNEL_EX1(r22, r22)
649 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) 660 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
650 } 661 }
651 beqzt r32, 1f /* zero if from user space */ 662 beqzt r32, 1f /* zero if from user space */
@@ -812,7 +823,7 @@ STD_ENTRY(interrupt_return)
812 PTREGS_PTR(r29, PTREGS_OFFSET_EX1) 823 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
813 } 824 }
814 ld r29, r29 825 ld r29, r29
815 andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 826 IS_KERNEL_EX1(r29, r29)
816 { 827 {
817 beqzt r29, .Lresume_userspace 828 beqzt r29, .Lresume_userspace
818 move r29, sp 829 move r29, sp
@@ -936,7 +947,7 @@ STD_ENTRY(interrupt_return)
936 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS) 947 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS)
937 } 948 }
938 { 949 {
939 andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK 950 IS_KERNEL_EX1(r0, r0)
940 ld r32, r32 951 ld r32, r32
941 } 952 }
942 bnez r0, 1f 953 bnez r0, 1f
@@ -1007,7 +1018,7 @@ STD_ENTRY(interrupt_return)
1007 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC 1018 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC
1008 { 1019 {
1009 mtspr SPR_EX_CONTEXT_K_1, lr 1020 mtspr SPR_EX_CONTEXT_K_1, lr
1010 andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 1021 IS_KERNEL_EX1(lr, lr)
1011 } 1022 }
1012 { 1023 {
1013 mtspr SPR_EX_CONTEXT_K_0, r21 1024 mtspr SPR_EX_CONTEXT_K_0, r21
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
index 24fd223df65d..362284af3afd 100644
--- a/arch/tile/kernel/stack.c
+++ b/arch/tile/kernel/stack.c
@@ -103,7 +103,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
103 p->sp >= sp) { 103 p->sp >= sp) {
104 if (kbt->verbose) 104 if (kbt->verbose)
105 pr_err(" <%s while in kernel mode>\n", fault); 105 pr_err(" <%s while in kernel mode>\n", fault);
106 } else if (EX1_PL(p->ex1) == USER_PL && 106 } else if (user_mode(p) &&
107 p->sp < PAGE_OFFSET && p->sp != 0) { 107 p->sp < PAGE_OFFSET && p->sp != 0) {
108 if (kbt->verbose) 108 if (kbt->verbose)
109 pr_err(" <%s while in user mode>\n", fault); 109 pr_err(" <%s while in user mode>\n", fault);
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 64eec3f9584f..39c48cbe0a96 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -283,7 +283,7 @@ static int handle_page_fault(struct pt_regs *regs,
283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
284 (write ? FAULT_FLAG_WRITE : 0)); 284 (write ? FAULT_FLAG_WRITE : 0));
285 285
286 is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL); 286 is_kernel_mode = !user_mode(regs);
287 287
288 tsk = validate_current(); 288 tsk = validate_current();
289 289
@@ -824,7 +824,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
824 } 824 }
825 825
826#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 826#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
827 if (EX1_PL(regs->ex1) != USER_PL) { 827 if (!user_mode(regs)) {
828 struct async_tlb *async; 828 struct async_tlb *async;
829 switch (fault_num) { 829 switch (fault_num) {
830#if CHIP_HAS_TILE_DMA() 830#if CHIP_HAS_TILE_DMA()