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 Will Deacon:
"Three arm64 fixes for -rc8/final.

The MTE and stolen time fixes have been doing the rounds for a little
while, but review and testing feedback was ongoing until earlier this
week. The kexec fix showed up on Monday and addresses a failure
observed under Qemu.

Summary:

- Add missing write barrier to publish MTE tags before a pte update

- Fix kexec relocation clobbering its own data structures

- Fix stolen time crash if a timer IRQ fires during CPU hotplug"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: mte: Ensure the cleared tags are visible before setting the PTE
arm64: kexec: load from kimage prior to clobbering
arm64: paravirt: Use RCU read locks to guard stolen_time

+39 -15
+3
arch/arm64/kernel/mte.c
··· 76 76 mte_sync_page_tags(page, old_pte, check_swap, 77 77 pte_is_tagged); 78 78 } 79 + 80 + /* ensure the tags are visible before the PTE is set */ 81 + smp_wmb(); 79 82 } 80 83 81 84 int memcmp_pages(struct page *page1, struct page *page2)
+21 -8
arch/arm64/kernel/paravirt.c
··· 35 35 DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock); 36 36 37 37 struct pv_time_stolen_time_region { 38 - struct pvclock_vcpu_stolen_time *kaddr; 38 + struct pvclock_vcpu_stolen_time __rcu *kaddr; 39 39 }; 40 40 41 41 static DEFINE_PER_CPU(struct pv_time_stolen_time_region, stolen_time_region); ··· 52 52 /* return stolen time in ns by asking the hypervisor */ 53 53 static u64 para_steal_clock(int cpu) 54 54 { 55 + struct pvclock_vcpu_stolen_time *kaddr = NULL; 55 56 struct pv_time_stolen_time_region *reg; 57 + u64 ret = 0; 56 58 57 59 reg = per_cpu_ptr(&stolen_time_region, cpu); 58 60 ··· 63 61 * online notification callback runs. Until the callback 64 62 * has run we just return zero. 65 63 */ 66 - if (!reg->kaddr) 64 + rcu_read_lock(); 65 + kaddr = rcu_dereference(reg->kaddr); 66 + if (!kaddr) { 67 + rcu_read_unlock(); 67 68 return 0; 69 + } 68 70 69 - return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time)); 71 + ret = le64_to_cpu(READ_ONCE(kaddr->stolen_time)); 72 + rcu_read_unlock(); 73 + return ret; 70 74 } 71 75 72 76 static int stolen_time_cpu_down_prepare(unsigned int cpu) 73 77 { 78 + struct pvclock_vcpu_stolen_time *kaddr = NULL; 74 79 struct pv_time_stolen_time_region *reg; 75 80 76 81 reg = this_cpu_ptr(&stolen_time_region); 77 82 if (!reg->kaddr) 78 83 return 0; 79 84 80 - memunmap(reg->kaddr); 81 - memset(reg, 0, sizeof(*reg)); 85 + kaddr = rcu_replace_pointer(reg->kaddr, NULL, true); 86 + synchronize_rcu(); 87 + memunmap(kaddr); 82 88 83 89 return 0; 84 90 } 85 91 86 92 static int stolen_time_cpu_online(unsigned int cpu) 87 93 { 94 + struct pvclock_vcpu_stolen_time *kaddr = NULL; 88 95 struct pv_time_stolen_time_region *reg; 89 96 struct arm_smccc_res res; 90 97 ··· 104 93 if (res.a0 == SMCCC_RET_NOT_SUPPORTED) 105 94 return -EINVAL; 106 95 107 - reg->kaddr = memremap(res.a0, 96 + kaddr = memremap(res.a0, 108 97 sizeof(struct pvclock_vcpu_stolen_time), 109 98 MEMREMAP_WB); 99 + 100 + rcu_assign_pointer(reg->kaddr, kaddr); 110 101 111 102 if (!reg->kaddr) { 112 103 pr_warn("Failed to map stolen time data structure\n"); 113 104 return -ENOMEM; 114 105 } 115 106 116 - if (le32_to_cpu(reg->kaddr->revision) != 0 || 117 - le32_to_cpu(reg->kaddr->attributes) != 0) { 107 + if (le32_to_cpu(kaddr->revision) != 0 || 108 + le32_to_cpu(kaddr->attributes) != 0) { 118 109 pr_warn_once("Unexpected revision or attributes in stolen time data\n"); 119 110 return -ENXIO; 120 111 }
+15 -7
arch/arm64/kernel/relocate_kernel.S
··· 37 37 * safe memory that has been set up to be preserved during the copy operation. 38 38 */ 39 39 SYM_CODE_START(arm64_relocate_new_kernel) 40 + /* 41 + * The kimage structure isn't allocated specially and may be clobbered 42 + * during relocation. We must load any values we need from it prior to 43 + * any relocation occurring. 44 + */ 45 + ldr x28, [x0, #KIMAGE_START] 46 + ldr x27, [x0, #KIMAGE_ARCH_EL2_VECTORS] 47 + ldr x26, [x0, #KIMAGE_ARCH_DTB_MEM] 48 + 40 49 /* Setup the list loop variables. */ 41 50 ldr x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */ 42 51 ldr x17, [x0, #KIMAGE_ARCH_TTBR1] /* x17 = linear map copy */ ··· 81 72 ic iallu 82 73 dsb nsh 83 74 isb 84 - ldr x4, [x0, #KIMAGE_START] /* relocation start */ 85 - ldr x1, [x0, #KIMAGE_ARCH_EL2_VECTORS] /* relocation start */ 86 - ldr x0, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */ 87 75 turn_off_mmu x12, x13 88 76 89 77 /* Start new image. */ 90 - cbz x1, .Lel1 91 - mov x1, x4 /* relocation start */ 92 - mov x2, x0 /* dtb address */ 78 + cbz x27, .Lel1 79 + mov x1, x28 /* kernel entry point */ 80 + mov x2, x26 /* dtb address */ 93 81 mov x3, xzr 94 82 mov x4, xzr 95 83 mov x0, #HVC_SOFT_RESTART 96 84 hvc #0 /* Jumps from el2 */ 97 85 .Lel1: 86 + mov x0, x26 /* dtb address */ 87 + mov x1, xzr 98 88 mov x2, xzr 99 89 mov x3, xzr 100 - br x4 /* Jumps from el1 */ 90 + br x28 /* Jumps from el1 */ 101 91 SYM_CODE_END(arm64_relocate_new_kernel)