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

Merge tag 'x86_core_for_v5.16_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 core updates from Borislav Petkov:

- Do not #GP on userspace use of CLI/STI but pretend it was a NOP to
keep old userspace from breaking. Adjust the corresponding iopl
selftest to that.

- Improve stack overflow warnings to say which stack got overflowed and
raise the exception stack sizes to 2 pages since overflowing the
single page of exception stack is very easy to do nowadays with all
the tracing machinery enabled. With that, rip out the custom mapping
of AMD SEV's too.

- A bunch of changes in preparation for FGKASLR like supporting more
than 64K section headers in the relocs tool, correct ORC lookup table
size to cover the whole kernel .text and other adjustments.

* tag 'x86_core_for_v5.16_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage
vmlinux.lds.h: Have ORC lookup cover entire _etext - _stext
x86/boot/compressed: Avoid duplicate malloc() implementations
x86/boot: Allow a "silent" kaslr random byte fetch
x86/tools/relocs: Support >64K section headers
x86/sev: Make the #VC exception stacks part of the default stacks storage
x86: Increase exception stack sizes
x86/mm/64: Improve stack overflow warnings
x86/iopl: Fake iopl(3) CLI/STI usage

+284 -130
-4
arch/x86/boot/compressed/kaslr.c
··· 32 32 #include <generated/utsrelease.h> 33 33 #include <asm/efi.h> 34 34 35 - /* Macros used by the included decompressor code below. */ 36 - #define STATIC 37 - #include <linux/decompress/mm.h> 38 - 39 35 #define _SETUP 40 36 #include <asm/setup.h> /* For COMMAND_LINE_SIZE */ 41 37 #undef _SETUP
+3
arch/x86/boot/compressed/misc.c
··· 28 28 29 29 /* Macros used by the included decompressor code below. */ 30 30 #define STATIC static 31 + /* Define an externally visible malloc()/free(). */ 32 + #define MALLOC_VISIBLE 33 + #include <linux/decompress/mm.h> 31 34 32 35 /* 33 36 * Provide definitions of memzero and memmove as some of the decompressors will
+2
arch/x86/boot/compressed/misc.h
··· 46 46 /* misc.c */ 47 47 extern memptr free_mem_ptr; 48 48 extern memptr free_mem_end_ptr; 49 + void *malloc(int size); 50 + void free(void *where); 49 51 extern struct boot_params *boot_params; 50 52 void __putstr(const char *s); 51 53 void __puthex(unsigned long value);
+7 -1
arch/x86/include/asm/cpu_entry_area.h
··· 10 10 11 11 #ifdef CONFIG_X86_64 12 12 13 + #ifdef CONFIG_AMD_MEM_ENCRYPT 14 + #define VC_EXCEPTION_STKSZ EXCEPTION_STKSZ 15 + #else 16 + #define VC_EXCEPTION_STKSZ 0 17 + #endif 18 + 13 19 /* Macro to enforce the same ordering and stack sizes */ 14 20 #define ESTACKS_MEMBERS(guardsize, optional_stack_size) \ 15 21 char DF_stack_guard[guardsize]; \ ··· 34 28 35 29 /* The exception stacks' physical storage. No guard pages required */ 36 30 struct exception_stacks { 37 - ESTACKS_MEMBERS(0, 0) 31 + ESTACKS_MEMBERS(0, VC_EXCEPTION_STKSZ) 38 32 }; 39 33 40 34 /* The effective cpu entry area mapping with guard pages. */
+1
arch/x86/include/asm/insn-eval.h
··· 21 21 int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); 22 22 unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); 23 23 int insn_get_code_seg_params(struct pt_regs *regs); 24 + int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip); 24 25 int insn_fetch_from_user(struct pt_regs *regs, 25 26 unsigned char buf[MAX_INSN_SIZE]); 26 27 int insn_fetch_from_user_inatomic(struct pt_regs *regs,
+25 -12
arch/x86/include/asm/irq_stack.h
··· 77 77 * Function calls can clobber anything except the callee-saved 78 78 * registers. Tell the compiler. 79 79 */ 80 - #define call_on_irqstack(func, asm_call, argconstr...) \ 80 + #define call_on_stack(stack, func, asm_call, argconstr...) \ 81 81 { \ 82 82 register void *tos asm("r11"); \ 83 83 \ 84 - tos = ((void *)__this_cpu_read(hardirq_stack_ptr)); \ 84 + tos = ((void *)(stack)); \ 85 85 \ 86 86 asm_inline volatile( \ 87 87 "movq %%rsp, (%[tos]) \n" \ ··· 97 97 "memory" \ 98 98 ); \ 99 99 } 100 + 101 + #define ASM_CALL_ARG0 \ 102 + "call %P[__func] \n" 103 + 104 + #define ASM_CALL_ARG1 \ 105 + "movq %[arg1], %%rdi \n" \ 106 + ASM_CALL_ARG0 107 + 108 + #define ASM_CALL_ARG2 \ 109 + "movq %[arg2], %%rsi \n" \ 110 + ASM_CALL_ARG1 111 + 112 + #define ASM_CALL_ARG3 \ 113 + "movq %[arg3], %%rdx \n" \ 114 + ASM_CALL_ARG2 115 + 116 + #define call_on_irqstack(func, asm_call, argconstr...) \ 117 + call_on_stack(__this_cpu_read(hardirq_stack_ptr), \ 118 + func, asm_call, argconstr) 100 119 101 120 /* Macros to assert type correctness for run_*_on_irqstack macros */ 102 121 #define assert_function_type(func, proto) \ ··· 166 147 */ 167 148 #define ASM_CALL_SYSVEC \ 168 149 "call irq_enter_rcu \n" \ 169 - "movq %[arg1], %%rdi \n" \ 170 - "call %P[__func] \n" \ 150 + ASM_CALL_ARG1 \ 171 151 "call irq_exit_rcu \n" 172 152 173 153 #define SYSVEC_CONSTRAINTS , [arg1] "r" (regs) ··· 186 168 */ 187 169 #define ASM_CALL_IRQ \ 188 170 "call irq_enter_rcu \n" \ 189 - "movq %[arg1], %%rdi \n" \ 190 - "movl %[arg2], %%esi \n" \ 191 - "call %P[__func] \n" \ 171 + ASM_CALL_ARG2 \ 192 172 "call irq_exit_rcu \n" 193 173 194 - #define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" (vector) 174 + #define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" ((unsigned long)vector) 195 175 196 176 #define run_irq_on_irqstack_cond(func, regs, vector) \ 197 177 { \ ··· 202 186 } 203 187 204 188 #ifndef CONFIG_PREEMPT_RT 205 - #define ASM_CALL_SOFTIRQ \ 206 - "call %P[__func] \n" 207 - 208 189 /* 209 190 * Macro to invoke __do_softirq on the irq stack. This is only called from 210 191 * task context when bottom halves are about to be reenabled and soft ··· 211 198 #define do_softirq_own_stack() \ 212 199 { \ 213 200 __this_cpu_write(hardirq_stack_inuse, true); \ 214 - call_on_irqstack(__do_softirq, ASM_CALL_SOFTIRQ); \ 201 + call_on_irqstack(__do_softirq, ASM_CALL_ARG0); \ 215 202 __this_cpu_write(hardirq_stack_inuse, false); \ 216 203 } 217 204
+1 -1
arch/x86/include/asm/page_64_types.h
··· 15 15 #define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) 16 16 #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) 17 17 18 - #define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER) 18 + #define EXCEPTION_STACK_ORDER (1 + KASAN_STACK_ORDER) 19 19 #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) 20 20 21 21 #define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
+1
arch/x86/include/asm/processor.h
··· 516 516 */ 517 517 unsigned long iopl_emul; 518 518 519 + unsigned int iopl_warn:1; 519 520 unsigned int sig_on_uaccess_err:1; 520 521 521 522 /*
+10
arch/x86/include/asm/stacktrace.h
··· 38 38 bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, 39 39 struct stack_info *info); 40 40 41 + static __always_inline 42 + bool get_stack_guard_info(unsigned long *stack, struct stack_info *info) 43 + { 44 + /* make sure it's not in the stack proper */ 45 + if (get_stack_info_noinstr(stack, current, info)) 46 + return false; 47 + /* but if it is in the page below it, we hit a guard */ 48 + return get_stack_info_noinstr((void *)stack + PAGE_SIZE, current, info); 49 + } 50 + 41 51 const char *stack_type_name(enum stack_type type); 42 52 43 53 static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
+3 -3
arch/x86/include/asm/traps.h
··· 40 40 bool fault_in_kernel_space(unsigned long address); 41 41 42 42 #ifdef CONFIG_VMAP_STACK 43 - void __noreturn handle_stack_overflow(const char *message, 44 - struct pt_regs *regs, 45 - unsigned long fault_address); 43 + void __noreturn handle_stack_overflow(struct pt_regs *regs, 44 + unsigned long fault_address, 45 + struct stack_info *info); 46 46 #endif 47 47 48 48 #endif /* _ASM_X86_TRAPS_H */
+6
arch/x86/kernel/dumpstack_64.c
··· 32 32 { 33 33 BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); 34 34 35 + if (type == STACK_TYPE_TASK) 36 + return "TASK"; 37 + 35 38 if (type == STACK_TYPE_IRQ) 36 39 return "IRQ"; 40 + 41 + if (type == STACK_TYPE_SOFTIRQ) 42 + return "SOFTIRQ"; 37 43 38 44 if (type == STACK_TYPE_ENTRY) { 39 45 /*
+1
arch/x86/kernel/process.c
··· 146 146 frame->ret_addr = (unsigned long) ret_from_fork; 147 147 p->thread.sp = (unsigned long) fork_frame; 148 148 p->thread.io_bitmap = NULL; 149 + p->thread.iopl_warn = 0; 149 150 memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); 150 151 151 152 #ifdef CONFIG_X86_64
-32
arch/x86/kernel/sev.c
··· 46 46 struct sev_es_runtime_data { 47 47 struct ghcb ghcb_page; 48 48 49 - /* Physical storage for the per-CPU IST stack of the #VC handler */ 50 - char ist_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); 51 - 52 - /* 53 - * Physical storage for the per-CPU fall-back stack of the #VC handler. 54 - * The fall-back stack is used when it is not safe to switch back to the 55 - * interrupted stack in the #VC entry code. 56 - */ 57 - char fallback_stack[EXCEPTION_STKSZ] __aligned(PAGE_SIZE); 58 - 59 49 /* 60 50 * Reserve one page per CPU as backup storage for the unencrypted GHCB. 61 51 * It is needed when an NMI happens while the #VC handler uses the real ··· 88 98 89 99 /* Needed in vc_early_forward_exception */ 90 100 void do_early_exception(struct pt_regs *regs, int trapnr); 91 - 92 - static void __init setup_vc_stacks(int cpu) 93 - { 94 - struct sev_es_runtime_data *data; 95 - struct cpu_entry_area *cea; 96 - unsigned long vaddr; 97 - phys_addr_t pa; 98 - 99 - data = per_cpu(runtime_data, cpu); 100 - cea = get_cpu_entry_area(cpu); 101 - 102 - /* Map #VC IST stack */ 103 - vaddr = CEA_ESTACK_BOT(&cea->estacks, VC); 104 - pa = __pa(data->ist_stack); 105 - cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); 106 - 107 - /* Map VC fall-back stack */ 108 - vaddr = CEA_ESTACK_BOT(&cea->estacks, VC2); 109 - pa = __pa(data->fallback_stack); 110 - cea_set_pte((void *)vaddr, pa, PAGE_KERNEL); 111 - } 112 101 113 102 static __always_inline bool on_vc_stack(struct pt_regs *regs) 114 103 { ··· 757 788 for_each_possible_cpu(cpu) { 758 789 alloc_runtime_data(cpu); 759 790 init_ghcb(cpu); 760 - setup_vc_stacks(cpu); 761 791 } 762 792 763 793 sev_es_setup_play_dead();
+46 -12
arch/x86/kernel/traps.c
··· 313 313 } 314 314 315 315 #ifdef CONFIG_VMAP_STACK 316 - __visible void __noreturn handle_stack_overflow(const char *message, 317 - struct pt_regs *regs, 318 - unsigned long fault_address) 316 + __visible void __noreturn handle_stack_overflow(struct pt_regs *regs, 317 + unsigned long fault_address, 318 + struct stack_info *info) 319 319 { 320 - printk(KERN_EMERG "BUG: stack guard page was hit at %p (stack is %p..%p)\n", 321 - (void *)fault_address, current->stack, 322 - (char *)current->stack + THREAD_SIZE - 1); 323 - die(message, regs, 0); 320 + const char *name = stack_type_name(info->type); 321 + 322 + printk(KERN_EMERG "BUG: %s stack guard page was hit at %p (stack is %p..%p)\n", 323 + name, (void *)fault_address, info->begin, info->end); 324 + 325 + die("stack guard page", regs, 0); 324 326 325 327 /* Be absolutely certain we don't return. */ 326 - panic("%s", message); 328 + panic("%s stack guard hit", name); 327 329 } 328 330 #endif 329 331 ··· 355 353 356 354 #ifdef CONFIG_VMAP_STACK 357 355 unsigned long address = read_cr2(); 356 + struct stack_info info; 358 357 #endif 359 358 360 359 #ifdef CONFIG_X86_ESPFIX64 ··· 458 455 * stack even if the actual trigger for the double fault was 459 456 * something else. 460 457 */ 461 - if ((unsigned long)task_stack_page(tsk) - 1 - address < PAGE_SIZE) { 462 - handle_stack_overflow("kernel stack overflow (double-fault)", 463 - regs, address); 464 - } 458 + if (get_stack_guard_info((void *)address, &info)) 459 + handle_stack_overflow(regs, address, &info); 465 460 #endif 466 461 467 462 pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code); ··· 529 528 530 529 #define GPFSTR "general protection fault" 531 530 531 + static bool fixup_iopl_exception(struct pt_regs *regs) 532 + { 533 + struct thread_struct *t = &current->thread; 534 + unsigned char byte; 535 + unsigned long ip; 536 + 537 + if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3) 538 + return false; 539 + 540 + if (insn_get_effective_ip(regs, &ip)) 541 + return false; 542 + 543 + if (get_user(byte, (const char __user *)ip)) 544 + return false; 545 + 546 + if (byte != 0xfa && byte != 0xfb) 547 + return false; 548 + 549 + if (!t->iopl_warn && printk_ratelimit()) { 550 + pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx", 551 + current->comm, task_pid_nr(current), ip); 552 + print_vma_addr(KERN_CONT " in ", ip); 553 + pr_cont("\n"); 554 + t->iopl_warn = 1; 555 + } 556 + 557 + regs->ip += 1; 558 + return true; 559 + } 560 + 532 561 DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) 533 562 { 534 563 char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR; ··· 584 553 tsk = current; 585 554 586 555 if (user_mode(regs)) { 556 + if (fixup_iopl_exception(regs)) 557 + goto exit; 558 + 587 559 tsk->thread.error_code = error_code; 588 560 tsk->thread.trap_nr = X86_TRAP_GP; 589 561
+1 -1
arch/x86/lib/insn-eval.c
··· 1417 1417 } 1418 1418 } 1419 1419 1420 - static int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) 1420 + int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) 1421 1421 { 1422 1422 unsigned long seg_base = 0; 1423 1423
+12 -6
arch/x86/lib/kaslr.c
··· 56 56 unsigned long raw, random = get_boot_seed(); 57 57 bool use_i8254 = true; 58 58 59 - debug_putstr(purpose); 60 - debug_putstr(" KASLR using"); 59 + if (purpose) { 60 + debug_putstr(purpose); 61 + debug_putstr(" KASLR using"); 62 + } 61 63 62 64 if (has_cpuflag(X86_FEATURE_RDRAND)) { 63 - debug_putstr(" RDRAND"); 65 + if (purpose) 66 + debug_putstr(" RDRAND"); 64 67 if (rdrand_long(&raw)) { 65 68 random ^= raw; 66 69 use_i8254 = false; ··· 71 68 } 72 69 73 70 if (has_cpuflag(X86_FEATURE_TSC)) { 74 - debug_putstr(" RDTSC"); 71 + if (purpose) 72 + debug_putstr(" RDTSC"); 75 73 raw = rdtsc(); 76 74 77 75 random ^= raw; ··· 80 76 } 81 77 82 78 if (use_i8254) { 83 - debug_putstr(" i8254"); 79 + if (purpose) 80 + debug_putstr(" i8254"); 84 81 random ^= i8254(); 85 82 } 86 83 ··· 91 86 : "a" (random), "rm" (mix_const)); 92 87 random += raw; 93 88 94 - debug_putstr("...\n"); 89 + if (purpose) 90 + debug_putstr("...\n"); 95 91 96 92 return random; 97 93 }
+7
arch/x86/mm/cpu_entry_area.c
··· 110 110 cea_map_stack(NMI); 111 111 cea_map_stack(DB); 112 112 cea_map_stack(MCE); 113 + 114 + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { 115 + if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) { 116 + cea_map_stack(VC); 117 + cea_map_stack(VC2); 118 + } 119 + } 113 120 } 114 121 #else 115 122 static inline void percpu_setup_exception_stacks(unsigned int cpu)
+10 -10
arch/x86/mm/fault.c
··· 32 32 #include <asm/pgtable_areas.h> /* VMALLOC_START, ... */ 33 33 #include <asm/kvm_para.h> /* kvm_handle_async_pf */ 34 34 #include <asm/vdso.h> /* fixup_vdso_exception() */ 35 + #include <asm/irq_stack.h> 35 36 36 37 #define CREATE_TRACE_POINTS 37 38 #include <asm/trace/exceptions.h> ··· 632 631 page_fault_oops(struct pt_regs *regs, unsigned long error_code, 633 632 unsigned long address) 634 633 { 634 + #ifdef CONFIG_VMAP_STACK 635 + struct stack_info info; 636 + #endif 635 637 unsigned long flags; 636 638 int sig; 637 639 ··· 653 649 * that we're in vmalloc space to avoid this. 654 650 */ 655 651 if (is_vmalloc_addr((void *)address) && 656 - (((unsigned long)current->stack - 1 - address < PAGE_SIZE) || 657 - address - ((unsigned long)current->stack + THREAD_SIZE) < PAGE_SIZE)) { 658 - unsigned long stack = __this_cpu_ist_top_va(DF) - sizeof(void *); 652 + get_stack_guard_info((void *)address, &info)) { 659 653 /* 660 654 * We're likely to be running with very little stack space 661 655 * left. It's plausible that we'd hit this condition but ··· 664 662 * and then double-fault, though, because we're likely to 665 663 * break the console driver and lose most of the stack dump. 666 664 */ 667 - asm volatile ("movq %[stack], %%rsp\n\t" 668 - "call handle_stack_overflow\n\t" 669 - "1: jmp 1b" 670 - : ASM_CALL_CONSTRAINT 671 - : "D" ("kernel stack overflow (page fault)"), 672 - "S" (regs), "d" (address), 673 - [stack] "rm" (stack)); 665 + call_on_stack(__this_cpu_ist_top_va(DF) - sizeof(void*), 666 + handle_stack_overflow, 667 + ASM_CALL_ARG3, 668 + , [arg1] "r" (regs), [arg2] "r" (address), [arg3] "r" (&info)); 669 + 674 670 unreachable(); 675 671 } 676 672 #endif
+78 -25
arch/x86/tools/relocs.c
··· 14 14 static Elf_Ehdr ehdr; 15 15 static unsigned long shnum; 16 16 static unsigned int shstrndx; 17 + static unsigned int shsymtabndx; 18 + static unsigned int shxsymtabndx; 19 + 20 + static int sym_index(Elf_Sym *sym); 17 21 18 22 struct relocs { 19 23 uint32_t *offset; ··· 39 35 Elf_Shdr shdr; 40 36 struct section *link; 41 37 Elf_Sym *symtab; 38 + Elf32_Word *xsymtab; 42 39 Elf_Rel *reltab; 43 40 char *strtab; 44 41 }; ··· 273 268 name = sym_strtab + sym->st_name; 274 269 } 275 270 else { 276 - name = sec_name(sym->st_shndx); 271 + name = sec_name(sym_index(sym)); 277 272 } 278 273 return name; 279 274 } ··· 342 337 #define elf_off_to_cpu(x) elf32_to_cpu(x) 343 338 #define elf_xword_to_cpu(x) elf32_to_cpu(x) 344 339 #endif 340 + 341 + static int sym_index(Elf_Sym *sym) 342 + { 343 + Elf_Sym *symtab = secs[shsymtabndx].symtab; 344 + Elf32_Word *xsymtab = secs[shxsymtabndx].xsymtab; 345 + unsigned long offset; 346 + int index; 347 + 348 + if (sym->st_shndx != SHN_XINDEX) 349 + return sym->st_shndx; 350 + 351 + /* calculate offset of sym from head of table. */ 352 + offset = (unsigned long)sym - (unsigned long)symtab; 353 + index = offset / sizeof(*sym); 354 + 355 + return elf32_to_cpu(xsymtab[index]); 356 + } 345 357 346 358 static void read_ehdr(FILE *fp) 347 359 { ··· 493 471 static void read_symtabs(FILE *fp) 494 472 { 495 473 int i,j; 474 + 496 475 for (i = 0; i < shnum; i++) { 497 476 struct section *sec = &secs[i]; 498 - if (sec->shdr.sh_type != SHT_SYMTAB) { 477 + int num_syms; 478 + 479 + switch (sec->shdr.sh_type) { 480 + case SHT_SYMTAB_SHNDX: 481 + sec->xsymtab = malloc(sec->shdr.sh_size); 482 + if (!sec->xsymtab) { 483 + die("malloc of %" FMT " bytes for xsymtab failed\n", 484 + sec->shdr.sh_size); 485 + } 486 + if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 487 + die("Seek to %" FMT " failed: %s\n", 488 + sec->shdr.sh_offset, strerror(errno)); 489 + } 490 + if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp) 491 + != sec->shdr.sh_size) { 492 + die("Cannot read extended symbol table: %s\n", 493 + strerror(errno)); 494 + } 495 + shxsymtabndx = i; 499 496 continue; 500 - } 501 - sec->symtab = malloc(sec->shdr.sh_size); 502 - if (!sec->symtab) { 503 - die("malloc of %" FMT " bytes for symtab failed\n", 504 - sec->shdr.sh_size); 505 - } 506 - if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 507 - die("Seek to %" FMT " failed: %s\n", 508 - sec->shdr.sh_offset, strerror(errno)); 509 - } 510 - if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) 511 - != sec->shdr.sh_size) { 512 - die("Cannot read symbol table: %s\n", 513 - strerror(errno)); 514 - } 515 - for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) { 516 - Elf_Sym *sym = &sec->symtab[j]; 517 - sym->st_name = elf_word_to_cpu(sym->st_name); 518 - sym->st_value = elf_addr_to_cpu(sym->st_value); 519 - sym->st_size = elf_xword_to_cpu(sym->st_size); 520 - sym->st_shndx = elf_half_to_cpu(sym->st_shndx); 497 + 498 + case SHT_SYMTAB: 499 + num_syms = sec->shdr.sh_size / sizeof(Elf_Sym); 500 + 501 + sec->symtab = malloc(sec->shdr.sh_size); 502 + if (!sec->symtab) { 503 + die("malloc of %" FMT " bytes for symtab failed\n", 504 + sec->shdr.sh_size); 505 + } 506 + if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 507 + die("Seek to %" FMT " failed: %s\n", 508 + sec->shdr.sh_offset, strerror(errno)); 509 + } 510 + if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) 511 + != sec->shdr.sh_size) { 512 + die("Cannot read symbol table: %s\n", 513 + strerror(errno)); 514 + } 515 + for (j = 0; j < num_syms; j++) { 516 + Elf_Sym *sym = &sec->symtab[j]; 517 + 518 + sym->st_name = elf_word_to_cpu(sym->st_name); 519 + sym->st_value = elf_addr_to_cpu(sym->st_value); 520 + sym->st_size = elf_xword_to_cpu(sym->st_size); 521 + sym->st_shndx = elf_half_to_cpu(sym->st_shndx); 522 + } 523 + shsymtabndx = i; 524 + continue; 525 + 526 + default: 527 + continue; 521 528 } 522 529 } 523 530 } ··· 813 762 */ 814 763 static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) 815 764 { 816 - return (sym->st_shndx == per_cpu_shndx) && 765 + int shndx = sym_index(sym); 766 + 767 + return (shndx == per_cpu_shndx) && 817 768 strcmp(symname, "__init_begin") && 818 769 strcmp(symname, "__per_cpu_load") && 819 770 strncmp(symname, "init_per_cpu_", 13); ··· 1148 1095 sec_name(sec->shdr.sh_info), 1149 1096 rel_type(ELF_R_TYPE(rel->r_info)), 1150 1097 symname, 1151 - sec_name(sym->st_shndx)); 1098 + sec_name(sym_index(sym))); 1152 1099 return 0; 1153 1100 } 1154 1101
+2 -1
include/asm-generic/vmlinux.lds.h
··· 875 875 KEEP(*(.orc_unwind)) \ 876 876 __stop_orc_unwind = .; \ 877 877 } \ 878 + text_size = _etext - _stext; \ 878 879 . = ALIGN(4); \ 879 880 .orc_lookup : AT(ADDR(.orc_lookup) - LOAD_OFFSET) { \ 880 881 orc_lookup = .; \ 881 - . += (((SIZEOF(.text) + LOOKUP_BLOCK_SIZE - 1) / \ 882 + . += (((text_size + LOOKUP_BLOCK_SIZE - 1) / \ 882 883 LOOKUP_BLOCK_SIZE) + 1) * 4; \ 883 884 orc_lookup_end = .; \ 884 885 }
+10 -2
include/linux/decompress/mm.h
··· 25 25 #define STATIC_RW_DATA static 26 26 #endif 27 27 28 + /* 29 + * When an architecture needs to share the malloc()/free() implementation 30 + * between compilation units, it needs to have non-local visibility. 31 + */ 32 + #ifndef MALLOC_VISIBLE 33 + #define MALLOC_VISIBLE static 34 + #endif 35 + 28 36 /* A trivial malloc implementation, adapted from 29 37 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 30 38 */ 31 39 STATIC_RW_DATA unsigned long malloc_ptr; 32 40 STATIC_RW_DATA int malloc_count; 33 41 34 - static void *malloc(int size) 42 + MALLOC_VISIBLE void *malloc(int size) 35 43 { 36 44 void *p; 37 45 ··· 60 52 return p; 61 53 } 62 54 63 - static void free(void *where) 55 + MALLOC_VISIBLE void free(void *where) 64 56 { 65 57 malloc_count--; 66 58 if (!malloc_count)
+58 -20
tools/testing/selftests/x86/iopl.c
··· 85 85 printf("[OK]\toutb to 0x%02hx failed\n", port); 86 86 } 87 87 88 - static bool try_cli(void) 88 + #define RET_FAULTED 0 89 + #define RET_FAIL 1 90 + #define RET_EMUL 2 91 + 92 + static int try_cli(void) 89 93 { 94 + unsigned long flags; 95 + 90 96 sethandler(SIGSEGV, sigsegv, SA_RESETHAND); 91 97 if (sigsetjmp(jmpbuf, 1) != 0) { 92 - return false; 98 + return RET_FAULTED; 93 99 } else { 94 - asm volatile ("cli"); 95 - return true; 100 + asm volatile("cli; pushf; pop %[flags]" 101 + : [flags] "=rm" (flags)); 102 + 103 + /* X86_FLAGS_IF */ 104 + if (!(flags & (1 << 9))) 105 + return RET_FAIL; 106 + else 107 + return RET_EMUL; 96 108 } 97 109 clearhandler(SIGSEGV); 98 110 } 99 111 100 - static bool try_sti(void) 112 + static int try_sti(bool irqs_off) 101 113 { 114 + unsigned long flags; 115 + 102 116 sethandler(SIGSEGV, sigsegv, SA_RESETHAND); 103 117 if (sigsetjmp(jmpbuf, 1) != 0) { 104 - return false; 118 + return RET_FAULTED; 105 119 } else { 106 - asm volatile ("sti"); 107 - return true; 120 + asm volatile("sti; pushf; pop %[flags]" 121 + : [flags] "=rm" (flags)); 122 + 123 + /* X86_FLAGS_IF */ 124 + if (irqs_off && (flags & (1 << 9))) 125 + return RET_FAIL; 126 + else 127 + return RET_EMUL; 108 128 } 109 129 clearhandler(SIGSEGV); 110 130 } 111 131 112 - static void expect_gp_sti(void) 132 + static void expect_gp_sti(bool irqs_off) 113 133 { 114 - if (try_sti()) { 134 + int ret = try_sti(irqs_off); 135 + 136 + switch (ret) { 137 + case RET_FAULTED: 138 + printf("[OK]\tSTI faulted\n"); 139 + break; 140 + case RET_EMUL: 141 + printf("[OK]\tSTI NOPped\n"); 142 + break; 143 + default: 115 144 printf("[FAIL]\tSTI worked\n"); 116 145 nerrs++; 117 - } else { 118 - printf("[OK]\tSTI faulted\n"); 119 146 } 120 147 } 121 148 122 - static void expect_gp_cli(void) 149 + /* 150 + * Returns whether it managed to disable interrupts. 151 + */ 152 + static bool test_cli(void) 123 153 { 124 - if (try_cli()) { 154 + int ret = try_cli(); 155 + 156 + switch (ret) { 157 + case RET_FAULTED: 158 + printf("[OK]\tCLI faulted\n"); 159 + break; 160 + case RET_EMUL: 161 + printf("[OK]\tCLI NOPped\n"); 162 + break; 163 + default: 125 164 printf("[FAIL]\tCLI worked\n"); 126 165 nerrs++; 127 - } else { 128 - printf("[OK]\tCLI faulted\n"); 166 + return true; 129 167 } 168 + 169 + return false; 130 170 } 131 171 132 172 int main(void) ··· 192 152 } 193 153 194 154 /* Make sure that CLI/STI are blocked even with IOPL level 3 */ 195 - expect_gp_cli(); 196 - expect_gp_sti(); 155 + expect_gp_sti(test_cli()); 197 156 expect_ok_outb(0x80); 198 157 199 158 /* Establish an I/O bitmap to test the restore */ ··· 243 204 printf("[RUN]\tparent: write to 0x80 (should fail)\n"); 244 205 245 206 expect_gp_outb(0x80); 246 - expect_gp_cli(); 247 - expect_gp_sti(); 207 + expect_gp_sti(test_cli()); 248 208 249 209 /* Test the capability checks. */ 250 210 printf("\tiopl(3)\n");