Skip to content

Commit 3964f82

Browse files
committed
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
2 parents c2cd8e4 + 73adbd9 commit 3964f82

File tree

16 files changed

+85
-48
lines changed

16 files changed

+85
-48
lines changed

arch/loongarch/include/asm/bootinfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ struct loongson_board_info {
2626

2727
#define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG)
2828

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+
*/
2933
struct loongson_system_configuration {
3034
int nr_cpus;
3135
int nr_nodes;

arch/loongarch/include/asm/kasan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#define XRANGE_SHIFT (48)
1717

1818
/* Valid address length */
19-
#define XRANGE_SHADOW_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3)
19+
#define XRANGE_SHADOW_SHIFT min(cpu_vabits, VA_BITS)
2020
/* Used for taking out the valid address */
2121
#define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0)
2222
/* One segment whole address space size */

arch/loongarch/include/asm/loongarch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@
250250
#define CSR_ESTAT_IS_WIDTH 15
251251
#define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT)
252252

253-
#define LOONGARCH_CSR_ERA 0x6 /* ERA */
253+
#define LOONGARCH_CSR_ERA 0x6 /* Exception return address */
254254

255255
#define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */
256256

arch/loongarch/include/asm/pgalloc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#define __HAVE_ARCH_PMD_ALLOC_ONE
1212
#define __HAVE_ARCH_PUD_ALLOC_ONE
13+
#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
1314
#include <asm-generic/pgalloc.h>
1415

1516
static inline void pmd_populate_kernel(struct mm_struct *mm,
@@ -44,6 +45,16 @@ extern void pagetable_init(void);
4445

4546
extern pgd_t *pgd_alloc(struct mm_struct *mm);
4647

48+
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
49+
{
50+
pte_t *pte = __pte_alloc_one_kernel(mm);
51+
52+
if (pte)
53+
kernel_pte_init(pte);
54+
55+
return pte;
56+
}
57+
4758
#define __pte_free_tlb(tlb, pte, address) \
4859
do { \
4960
pagetable_pte_dtor(page_ptdesc(pte)); \

arch/loongarch/include/asm/pgtable.h

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pm
269269
extern void pgd_init(void *addr);
270270
extern void pud_init(void *addr);
271271
extern void pmd_init(void *addr);
272+
extern void kernel_pte_init(void *addr);
272273

273274
/*
274275
* Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
@@ -325,39 +326,17 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
325326
{
326327
WRITE_ONCE(*ptep, pteval);
327328

328-
if (pte_val(pteval) & _PAGE_GLOBAL) {
329-
pte_t *buddy = ptep_buddy(ptep);
330-
/*
331-
* Make sure the buddy is global too (if it's !none,
332-
* it better already be global)
333-
*/
334-
if (pte_none(ptep_get(buddy))) {
335329
#ifdef CONFIG_SMP
336-
/*
337-
* For SMP, multiple CPUs can race, so we need
338-
* to do this atomically.
339-
*/
340-
__asm__ __volatile__(
341-
__AMOR "$zero, %[global], %[buddy] \n"
342-
: [buddy] "+ZB" (buddy->pte)
343-
: [global] "r" (_PAGE_GLOBAL)
344-
: "memory");
345-
346-
DBAR(0b11000); /* o_wrw = 0b11000 */
347-
#else /* !CONFIG_SMP */
348-
WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL));
349-
#endif /* CONFIG_SMP */
350-
}
351-
}
330+
if (pte_val(pteval) & _PAGE_GLOBAL)
331+
DBAR(0b11000); /* o_wrw = 0b11000 */
332+
#endif
352333
}
353334

354335
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
355336
{
356-
/* Preserve global status for the pair */
357-
if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL)
358-
set_pte(ptep, __pte(_PAGE_GLOBAL));
359-
else
360-
set_pte(ptep, __pte(0));
337+
pte_t pte = ptep_get(ptep);
338+
pte_val(pte) &= _PAGE_GLOBAL;
339+
set_pte(ptep, pte);
361340
}
362341

363342
#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1)

arch/loongarch/kernel/process.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,15 @@ unsigned long stack_top(void)
293293
{
294294
unsigned long top = TASK_SIZE & PAGE_MASK;
295295

296-
/* Space for the VDSO & data page */
297-
top -= PAGE_ALIGN(current->thread.vdso->size);
298-
top -= VVAR_SIZE;
299-
300-
/* Space to randomize the VDSO base */
301-
if (current->flags & PF_RANDOMIZE)
302-
top -= VDSO_RANDOMIZE_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;
300+
301+
/* Space to randomize the VDSO base */
302+
if (current->flags & PF_RANDOMIZE)
303+
top -= VDSO_RANDOMIZE_SIZE;
304+
}
303305

304306
return top;
305307
}

arch/loongarch/kernel/setup.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define SMBIOS_FREQHIGH_OFFSET 0x17
5656
#define SMBIOS_FREQLOW_MASK 0xFF
5757
#define SMBIOS_CORE_PACKAGE_OFFSET 0x23
58+
#define SMBIOS_THREAD_PACKAGE_OFFSET 0x25
5859
#define LOONGSON_EFI_ENABLE (1 << 3)
5960

6061
unsigned long fw_arg0, fw_arg1, fw_arg2;
@@ -125,7 +126,7 @@ static void __init parse_cpu_table(const struct dmi_header *dm)
125126
cpu_clock_freq = freq_temp * 1000000;
126127

127128
loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]);
128-
loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET);
129+
loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET);
129130

130131
pr_info("CpuClock = %llu\n", cpu_clock_freq);
131132
}

arch/loongarch/kernel/traps.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,9 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs)
555555
#else
556556
unsigned int *pc;
557557

558+
if (regs->csr_prmd & CSR_PRMD_PIE)
559+
local_irq_enable();
560+
558561
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr);
559562

560563
/*
@@ -579,6 +582,8 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs)
579582
die_if_kernel("Kernel ale access", regs);
580583
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr);
581584
out:
585+
if (regs->csr_prmd & CSR_PRMD_PIE)
586+
local_irq_disable();
582587
#endif
583588
irqentry_exit(regs, state);
584589
}

arch/loongarch/kernel/vdso.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ static union {
3434
struct loongarch_vdso_data vdata;
3535
} loongarch_vdso_data __page_aligned_data;
3636

37-
static struct page *vdso_pages[] = { NULL };
3837
struct vdso_data *vdso_data = generic_vdso_data.data;
3938
struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata;
4039
struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data;
@@ -85,10 +84,8 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
8584

8685
struct loongarch_vdso_info vdso_info = {
8786
.vdso = vdso_start,
88-
.size = PAGE_SIZE,
8987
.code_mapping = {
9088
.name = "[vdso]",
91-
.pages = vdso_pages,
9289
.mremap = vdso_mremap,
9390
},
9491
.data_mapping = {
@@ -103,11 +100,14 @@ static int __init init_vdso(void)
103100
unsigned long i, cpu, pfn;
104101

105102
BUG_ON(!PAGE_ALIGNED(vdso_info.vdso));
106-
BUG_ON(!PAGE_ALIGNED(vdso_info.size));
107103

108104
for_each_possible_cpu(cpu)
109105
vdso_pdata[cpu].node = cpu_to_node(cpu);
110106

107+
vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start);
108+
vdso_info.code_mapping.pages =
109+
kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL);
110+
111111
pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso));
112112
for (i = 0; i < vdso_info.size / PAGE_SIZE; i++)
113113
vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i);

arch/loongarch/kvm/timer.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,11 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
161161
if (kvm_vcpu_is_blocking(vcpu)) {
162162

163163
/*
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.
166167
*/
167-
hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
168+
hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD);
168169
}
169170
}
170171

0 commit comments

Comments
 (0)