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 'loongarch-fixes-6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:
"Get correct cores_per_package for SMT systems, enable IRQ if do_ale()
triggered in irq-enabled context, and fix some bugs about vDSO, memory
managenent, hrtimer in KVM, etc"

* tag 'loongarch-fixes-6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
LoongArch: KVM: Mark hrtimer to expire in hard interrupt context
LoongArch: Make KASAN usable for variable cpu_vabits
LoongArch: Set initial pte entry with PAGE_GLOBAL for kernel space
LoongArch: Don't crash in stack_top() for tasks without vDSO
LoongArch: Set correct size for vDSO code mapping
LoongArch: Enable IRQ if do_ale() triggered in irq-enabled context
LoongArch: Get correct cores_per_package for SMT systems
LoongArch: Use "Exception return address" to comment ERA

+84 -47
+4
arch/loongarch/include/asm/bootinfo.h
··· 26 26 27 27 #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG) 28 28 29 + /* 30 + * The "core" of cores_per_node and cores_per_package stands for a 31 + * logical core, which means in a SMT system it stands for a thread. 32 + */ 29 33 struct loongson_system_configuration { 30 34 int nr_cpus; 31 35 int nr_nodes;
+1 -1
arch/loongarch/include/asm/kasan.h
··· 16 16 #define XRANGE_SHIFT (48) 17 17 18 18 /* Valid address length */ 19 - #define XRANGE_SHADOW_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3) 19 + #define XRANGE_SHADOW_SHIFT min(cpu_vabits, VA_BITS) 20 20 /* Used for taking out the valid address */ 21 21 #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) 22 22 /* One segment whole address space size */
+1 -1
arch/loongarch/include/asm/loongarch.h
··· 250 250 #define CSR_ESTAT_IS_WIDTH 15 251 251 #define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT) 252 252 253 - #define LOONGARCH_CSR_ERA 0x6 /* ERA */ 253 + #define LOONGARCH_CSR_ERA 0x6 /* Exception return address */ 254 254 255 255 #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ 256 256
+11
arch/loongarch/include/asm/pgalloc.h
··· 10 10 11 11 #define __HAVE_ARCH_PMD_ALLOC_ONE 12 12 #define __HAVE_ARCH_PUD_ALLOC_ONE 13 + #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL 13 14 #include <asm-generic/pgalloc.h> 14 15 15 16 static inline void pmd_populate_kernel(struct mm_struct *mm, ··· 44 43 extern void pagetable_init(void); 45 44 46 45 extern pgd_t *pgd_alloc(struct mm_struct *mm); 46 + 47 + static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 48 + { 49 + pte_t *pte = __pte_alloc_one_kernel(mm); 50 + 51 + if (pte) 52 + kernel_pte_init(pte); 53 + 54 + return pte; 55 + } 47 56 48 57 #define __pte_free_tlb(tlb, pte, address) \ 49 58 do { \
+7 -28
arch/loongarch/include/asm/pgtable.h
··· 269 269 extern void pgd_init(void *addr); 270 270 extern void pud_init(void *addr); 271 271 extern void pmd_init(void *addr); 272 + extern void kernel_pte_init(void *addr); 272 273 273 274 /* 274 275 * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that ··· 326 325 { 327 326 WRITE_ONCE(*ptep, pteval); 328 327 329 - if (pte_val(pteval) & _PAGE_GLOBAL) { 330 - pte_t *buddy = ptep_buddy(ptep); 331 - /* 332 - * Make sure the buddy is global too (if it's !none, 333 - * it better already be global) 334 - */ 335 - if (pte_none(ptep_get(buddy))) { 336 328 #ifdef CONFIG_SMP 337 - /* 338 - * For SMP, multiple CPUs can race, so we need 339 - * to do this atomically. 340 - */ 341 - __asm__ __volatile__( 342 - __AMOR "$zero, %[global], %[buddy] \n" 343 - : [buddy] "+ZB" (buddy->pte) 344 - : [global] "r" (_PAGE_GLOBAL) 345 - : "memory"); 346 - 347 - DBAR(0b11000); /* o_wrw = 0b11000 */ 348 - #else /* !CONFIG_SMP */ 349 - WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL)); 350 - #endif /* CONFIG_SMP */ 351 - } 352 - } 329 + if (pte_val(pteval) & _PAGE_GLOBAL) 330 + DBAR(0b11000); /* o_wrw = 0b11000 */ 331 + #endif 353 332 } 354 333 355 334 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 356 335 { 357 - /* Preserve global status for the pair */ 358 - if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL) 359 - set_pte(ptep, __pte(_PAGE_GLOBAL)); 360 - else 361 - set_pte(ptep, __pte(0)); 336 + pte_t pte = ptep_get(ptep); 337 + pte_val(pte) &= _PAGE_GLOBAL; 338 + set_pte(ptep, pte); 362 339 } 363 340 364 341 #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1)
+8 -6
arch/loongarch/kernel/process.c
··· 293 293 { 294 294 unsigned long top = TASK_SIZE & PAGE_MASK; 295 295 296 - /* Space for the VDSO & data page */ 297 - top -= PAGE_ALIGN(current->thread.vdso->size); 298 - top -= VVAR_SIZE; 296 + if (current->thread.vdso) { 297 + /* Space for the VDSO & data page */ 298 + top -= PAGE_ALIGN(current->thread.vdso->size); 299 + top -= VVAR_SIZE; 299 300 300 - /* Space to randomize the VDSO base */ 301 - if (current->flags & PF_RANDOMIZE) 302 - top -= VDSO_RANDOMIZE_SIZE; 301 + /* Space to randomize the VDSO base */ 302 + if (current->flags & PF_RANDOMIZE) 303 + top -= VDSO_RANDOMIZE_SIZE; 304 + } 303 305 304 306 return top; 305 307 }
+2 -1
arch/loongarch/kernel/setup.c
··· 55 55 #define SMBIOS_FREQHIGH_OFFSET 0x17 56 56 #define SMBIOS_FREQLOW_MASK 0xFF 57 57 #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 58 + #define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 58 59 #define LOONGSON_EFI_ENABLE (1 << 3) 59 60 60 61 unsigned long fw_arg0, fw_arg1, fw_arg2; ··· 126 125 cpu_clock_freq = freq_temp * 1000000; 127 126 128 127 loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); 129 - loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET); 128 + loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); 130 129 131 130 pr_info("CpuClock = %llu\n", cpu_clock_freq); 132 131 }
+5
arch/loongarch/kernel/traps.c
··· 555 555 #else 556 556 unsigned int *pc; 557 557 558 + if (regs->csr_prmd & CSR_PRMD_PIE) 559 + local_irq_enable(); 560 + 558 561 perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); 559 562 560 563 /* ··· 582 579 die_if_kernel("Kernel ale access", regs); 583 580 force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); 584 581 out: 582 + if (regs->csr_prmd & CSR_PRMD_PIE) 583 + local_irq_disable(); 585 584 #endif 586 585 irqentry_exit(regs, state); 587 586 }
+4 -4
arch/loongarch/kernel/vdso.c
··· 34 34 struct loongarch_vdso_data vdata; 35 35 } loongarch_vdso_data __page_aligned_data; 36 36 37 - static struct page *vdso_pages[] = { NULL }; 38 37 struct vdso_data *vdso_data = generic_vdso_data.data; 39 38 struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; 40 39 struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data; ··· 84 85 85 86 struct loongarch_vdso_info vdso_info = { 86 87 .vdso = vdso_start, 87 - .size = PAGE_SIZE, 88 88 .code_mapping = { 89 89 .name = "[vdso]", 90 - .pages = vdso_pages, 91 90 .mremap = vdso_mremap, 92 91 }, 93 92 .data_mapping = { ··· 100 103 unsigned long i, cpu, pfn; 101 104 102 105 BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); 103 - BUG_ON(!PAGE_ALIGNED(vdso_info.size)); 104 106 105 107 for_each_possible_cpu(cpu) 106 108 vdso_pdata[cpu].node = cpu_to_node(cpu); 109 + 110 + vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start); 111 + vdso_info.code_mapping.pages = 112 + kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL); 107 113 108 114 pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); 109 115 for (i = 0; i < vdso_info.size / PAGE_SIZE; i++)
+4 -3
arch/loongarch/kvm/timer.c
··· 161 161 if (kvm_vcpu_is_blocking(vcpu)) { 162 162 163 163 /* 164 - * HRTIMER_MODE_PINNED is suggested since vcpu may run in 165 - * the same physical cpu in next time 164 + * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in 165 + * the same physical cpu in next time, and the timer should run 166 + * in hardirq context even in the PREEMPT_RT case. 166 167 */ 167 - hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED); 168 + hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD); 168 169 } 169 170 } 170 171
+1 -1
arch/loongarch/kvm/vcpu.c
··· 1457 1457 vcpu->arch.vpid = 0; 1458 1458 vcpu->arch.flush_gpa = INVALID_GPA; 1459 1459 1460 - hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); 1460 + hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); 1461 1461 vcpu->arch.swtimer.function = kvm_swtimer_wakeup; 1462 1462 1463 1463 vcpu->arch.handle_exit = kvm_handle_exit;
+2
arch/loongarch/mm/init.c
··· 201 201 pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); 202 202 if (!pte) 203 203 panic("%s: Failed to allocate memory\n", __func__); 204 + 204 205 pmd_populate_kernel(&init_mm, pmd, pte); 206 + kernel_pte_init(pte); 205 207 } 206 208 207 209 return pte_offset_kernel(pmd, addr);
+20
arch/loongarch/mm/pgtable.c
··· 116 116 EXPORT_SYMBOL_GPL(pud_init); 117 117 #endif 118 118 119 + void kernel_pte_init(void *addr) 120 + { 121 + unsigned long *p, *end; 122 + 123 + p = (unsigned long *)addr; 124 + end = p + PTRS_PER_PTE; 125 + 126 + do { 127 + p[0] = _PAGE_GLOBAL; 128 + p[1] = _PAGE_GLOBAL; 129 + p[2] = _PAGE_GLOBAL; 130 + p[3] = _PAGE_GLOBAL; 131 + p[4] = _PAGE_GLOBAL; 132 + p += 8; 133 + p[-3] = _PAGE_GLOBAL; 134 + p[-2] = _PAGE_GLOBAL; 135 + p[-1] = _PAGE_GLOBAL; 136 + } while (p != end); 137 + } 138 + 119 139 pmd_t mk_pmd(struct page *page, pgprot_t prot) 120 140 { 121 141 pmd_t pmd;
+2 -1
include/linux/mm.h
··· 3818 3818 struct page * __populate_section_memmap(unsigned long pfn, 3819 3819 unsigned long nr_pages, int nid, struct vmem_altmap *altmap, 3820 3820 struct dev_pagemap *pgmap); 3821 - void pmd_init(void *addr); 3822 3821 void pud_init(void *addr); 3822 + void pmd_init(void *addr); 3823 + void kernel_pte_init(void *addr); 3823 3824 pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); 3824 3825 p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node); 3825 3826 pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
+7 -1
mm/kasan/init.c
··· 106 106 } 107 107 } 108 108 109 + void __weak __meminit kernel_pte_init(void *addr) 110 + { 111 + } 112 + 109 113 static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr, 110 114 unsigned long end) 111 115 { ··· 130 126 131 127 if (slab_is_available()) 132 128 p = pte_alloc_one_kernel(&init_mm); 133 - else 129 + else { 134 130 p = early_alloc(PAGE_SIZE, NUMA_NO_NODE); 131 + kernel_pte_init(p); 132 + } 135 133 if (!p) 136 134 return -ENOMEM; 137 135
+5
mm/sparse-vmemmap.c
··· 184 184 return p; 185 185 } 186 186 187 + void __weak __meminit kernel_pte_init(void *addr) 188 + { 189 + } 190 + 187 191 pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) 188 192 { 189 193 pmd_t *pmd = pmd_offset(pud, addr); ··· 195 191 void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node); 196 192 if (!p) 197 193 return NULL; 194 + kernel_pte_init(p); 198 195 pmd_populate_kernel(&init_mm, pmd, p); 199 196 } 200 197 return pmd;