Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+23 -12
+2 -2
arch/tile/include/asm/processor.h
··· 15 15 #ifndef _ASM_TILE_PROCESSOR_H 16 16 #define _ASM_TILE_PROCESSOR_H 17 17 18 + #include <arch/chip.h> 19 + 18 20 #ifndef __ASSEMBLY__ 19 21 20 22 /* ··· 27 25 #include <asm/ptrace.h> 28 26 #include <asm/percpu.h> 29 27 30 - #include <arch/chip.h> 31 28 #include <arch/spr_def.h> 32 29 33 30 struct task_struct; ··· 348 347 349 348 /* 350 349 * Provide symbolic constants for PLs. 351 - * Note that assembly code assumes that USER_PL is zero. 352 350 */ 353 351 #define USER_PL 0 354 352 #if CONFIG_KERNEL_PL == 2
+1 -1
arch/tile/include/asm/ptrace.h
··· 39 39 #define user_stack_pointer(regs) ((regs)->sp) 40 40 41 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 44 /* Fill in a struct pt_regs with the current kernel registers. */ 45 45 struct pt_regs *get_pt_regs(struct pt_regs *);
+17 -6
arch/tile/kernel/intvec_64.S
··· 34 34 35 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 48 .macro push_reg reg, ptr=sp, delta=-8 39 49 { ··· 318 308 */ 319 309 { 320 310 blbs sp, 2f 321 - andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 311 + IS_KERNEL_EX1(r0, r0) 322 312 } 323 313 324 314 .ifc \vecnum, INT_DOUBLE_FAULT ··· 651 641 /* 652 642 * If we will be returning to the kernel, we will need to 653 643 * reset the interrupt masks to the state they had before. 654 - * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled. 644 + * Set DISABLE_IRQ in flags iff we came from kernel pl with 645 + * irqs disabled. 655 646 */ 656 647 mfspr r32, SPR_EX_CONTEXT_K_1 657 648 { 658 - andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 649 + IS_KERNEL_EX1(r22, r22) 659 650 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS) 660 651 } 661 652 beqzt r32, 1f /* zero if from user space */ ··· 823 812 PTREGS_PTR(r29, PTREGS_OFFSET_EX1) 824 813 } 825 814 ld r29, r29 826 - andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 815 + IS_KERNEL_EX1(r29, r29) 827 816 { 828 817 beqzt r29, .Lresume_userspace 829 818 move r29, sp ··· 947 936 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS) 948 937 } 949 938 { 950 - andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK 939 + IS_KERNEL_EX1(r0, r0) 951 940 ld r32, r32 952 941 } 953 942 bnez r0, 1f ··· 1018 1007 pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC 1019 1008 { 1020 1009 mtspr SPR_EX_CONTEXT_K_1, lr 1021 - andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */ 1010 + IS_KERNEL_EX1(lr, lr) 1022 1011 } 1023 1012 { 1024 1013 mtspr SPR_EX_CONTEXT_K_0, r21
+1 -1
arch/tile/kernel/stack.c
··· 103 103 p->sp >= sp) { 104 104 if (kbt->verbose) 105 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 107 p->sp < PAGE_OFFSET && p->sp != 0) { 108 108 if (kbt->verbose) 109 109 pr_err(" <%s while in user mode>\n", fault);
+2 -2
arch/tile/mm/fault.c
··· 283 283 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 284 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 288 tsk = validate_current(); 289 289 ··· 824 824 } 825 825 826 826 #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 827 - if (EX1_PL(regs->ex1) != USER_PL) { 827 + if (!user_mode(regs)) { 828 828 struct async_tlb *async; 829 829 switch (fault_num) { 830 830 #if CHIP_HAS_TILE_DMA()