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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:

- avoid potential stack information leak via the ptrace ABI caused by
uninitialised variables

- SWIOTLB DMA API fall-back allocation fix when the SWIOTLB buffer is
not initialised (all RAM is suitable for 32-bit DMA masks)

- fix the bad_mode function returning for unhandled exceptions coming
from user space

- fix name clash in __page_to_voff()

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: avoid returning from bad_mode
arm64/ptrace: Reject attempts to set incomplete hardware breakpoint fields
arm64/ptrace: Avoid uninitialised struct padding in fpr_set()
arm64/ptrace: Preserve previous registers for short regset write
arm64/ptrace: Preserve previous registers for short regset write
arm64/ptrace: Preserve previous registers for short regset write
arm64: mm: avoid name clash in __page_to_voff()
arm64: Fix swiotlb fallback allocation

+40 -11
+1 -1
arch/arm64/include/asm/memory.h
··· 222 222 #define _virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 223 223 #else 224 224 #define __virt_to_pgoff(kaddr) (((u64)(kaddr) & ~PAGE_OFFSET) / PAGE_SIZE * sizeof(struct page)) 225 - #define __page_to_voff(page) (((u64)(page) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page)) 225 + #define __page_to_voff(kaddr) (((u64)(kaddr) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page)) 226 226 227 227 #define page_to_virt(page) ((void *)((__page_to_voff(page)) | PAGE_OFFSET)) 228 228 #define virt_to_page(vaddr) ((struct page *)((__virt_to_pgoff(vaddr)) | VMEMMAP_START))
+1
arch/arm64/include/uapi/asm/ptrace.h
··· 77 77 __uint128_t vregs[32]; 78 78 __u32 fpsr; 79 79 __u32 fpcr; 80 + __u32 __reserved[2]; 80 81 }; 81 82 82 83 struct user_hwdebug_state {
+1 -1
arch/arm64/kernel/entry.S
··· 683 683 mov x0, sp 684 684 mov x1, #BAD_SYNC 685 685 mov x2, x25 686 - bl bad_mode 686 + bl bad_el0_sync 687 687 b ret_to_user 688 688 ENDPROC(el0_sync) 689 689
+11 -5
arch/arm64/kernel/ptrace.c
··· 551 551 /* (address, ctrl) registers */ 552 552 limit = regset->n * regset->size; 553 553 while (count && offset < limit) { 554 + if (count < PTRACE_HBP_ADDR_SZ) 555 + return -EINVAL; 554 556 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &addr, 555 557 offset, offset + PTRACE_HBP_ADDR_SZ); 556 558 if (ret) ··· 562 560 return ret; 563 561 offset += PTRACE_HBP_ADDR_SZ; 564 562 563 + if (!count) 564 + break; 565 565 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 566 566 offset, offset + PTRACE_HBP_CTRL_SZ); 567 567 if (ret) ··· 600 596 const void *kbuf, const void __user *ubuf) 601 597 { 602 598 int ret; 603 - struct user_pt_regs newregs; 599 + struct user_pt_regs newregs = task_pt_regs(target)->user_regs; 604 600 605 601 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1); 606 602 if (ret) ··· 630 626 const void *kbuf, const void __user *ubuf) 631 627 { 632 628 int ret; 633 - struct user_fpsimd_state newstate; 629 + struct user_fpsimd_state newstate = 630 + target->thread.fpsimd_state.user_fpsimd; 634 631 635 632 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, 0, -1); 636 633 if (ret) ··· 655 650 const void *kbuf, const void __user *ubuf) 656 651 { 657 652 int ret; 658 - unsigned long tls; 653 + unsigned long tls = target->thread.tp_value; 659 654 660 655 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); 661 656 if (ret) ··· 681 676 unsigned int pos, unsigned int count, 682 677 const void *kbuf, const void __user *ubuf) 683 678 { 684 - int syscallno, ret; 679 + int syscallno = task_pt_regs(target)->syscallno; 680 + int ret; 685 681 686 682 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &syscallno, 0, -1); 687 683 if (ret) ··· 954 948 const void __user *ubuf) 955 949 { 956 950 int ret; 957 - compat_ulong_t tls; 951 + compat_ulong_t tls = target->thread.tp_value; 958 952 959 953 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); 960 954 if (ret)
+24 -4
arch/arm64/kernel/traps.c
··· 604 604 } 605 605 606 606 /* 607 - * bad_mode handles the impossible case in the exception vector. 607 + * bad_mode handles the impossible case in the exception vector. This is always 608 + * fatal. 608 609 */ 609 610 asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) 610 611 { 611 - siginfo_t info; 612 - void __user *pc = (void __user *)instruction_pointer(regs); 613 612 console_verbose(); 614 613 615 614 pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n", 616 615 handler[reason], smp_processor_id(), esr, 617 616 esr_get_class_string(esr)); 617 + 618 + die("Oops - bad mode", regs, 0); 619 + local_irq_disable(); 620 + panic("bad mode"); 621 + } 622 + 623 + /* 624 + * bad_el0_sync handles unexpected, but potentially recoverable synchronous 625 + * exceptions taken from EL0. Unlike bad_mode, this returns. 626 + */ 627 + asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) 628 + { 629 + siginfo_t info; 630 + void __user *pc = (void __user *)instruction_pointer(regs); 631 + console_verbose(); 632 + 633 + pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x -- %s\n", 634 + smp_processor_id(), esr, esr_get_class_string(esr)); 618 635 __show_regs(regs); 619 636 620 637 info.si_signo = SIGILL; ··· 639 622 info.si_code = ILL_ILLOPC; 640 623 info.si_addr = pc; 641 624 642 - arm64_notify_die("Oops - bad mode", regs, &info, 0); 625 + current->thread.fault_address = 0; 626 + current->thread.fault_code = 0; 627 + 628 + force_sig_info(info.si_signo, &info, current); 643 629 } 644 630 645 631 void __pte_error(const char *file, int line, unsigned long val)
+2
arch/arm64/mm/init.c
··· 404 404 if (swiotlb_force == SWIOTLB_FORCE || 405 405 max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) 406 406 swiotlb_init(1); 407 + else 408 + swiotlb_force = SWIOTLB_NO_FORCE; 407 409 408 410 set_max_mapnr(pfn_to_page(max_pfn) - mem_map); 409 411