Skip to content

Commit 3630400

Browse files
committed
Merge tag 'loongarch-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch updates from Huacai Chen: - Fix objtool about do_syscall() and Clang - Enable generic CPU vulnerabilites support - Enable ACPI BGRT handling - Rework CPU feature probe from CPUCFG/IOCSR - Add ARCH_HAS_SET_MEMORY support - Add ARCH_HAS_SET_DIRECT_MAP support - Improve hardware page table walker - Simplify _percpu_read() and _percpu_write() - Add advanced extended IRQ model documentions - Some bug fixes and other small changes * tag 'loongarch-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: Docs/LoongArch: Add advanced extended IRQ model description LoongArch: Remove posix_types.h include from sigcontext.h LoongArch: Fix memleak in pci_acpi_scan_root() LoongArch: Simplify _percpu_read() and _percpu_write() LoongArch: Improve hardware page table walker LoongArch: Add ARCH_HAS_SET_DIRECT_MAP support LoongArch: Add ARCH_HAS_SET_MEMORY support LoongArch: Rework CPU feature probe from CPUCFG/IOCSR LoongArch: Enable ACPI BGRT handling LoongArch: Enable generic CPU vulnerabilites support LoongArch: Remove STACK_FRAME_NON_STANDARD(do_syscall) LoongArch: Set AS_HAS_THIN_ADD_SUB as y if AS_IS_LLVM LoongArch: Enable objtool for Clang objtool: Handle frame pointer related instructions
2 parents ec38498 + f339bd3 commit 3630400

File tree

25 files changed

+565
-193
lines changed

25 files changed

+565
-193
lines changed

Documentation/arch/loongarch/irq-chip-model.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,38 @@ to CPUINTC directly::
8585
| Devices |
8686
+---------+
8787

88+
Advanced Extended IRQ model
89+
===========================
90+
91+
In this model, IPI (Inter-Processor Interrupt) and CPU Local Timer interrupt go
92+
to CPUINTC directly, CPU UARTS interrupts go to LIOINTC, PCH-MSI interrupts go
93+
to AVECINTC, and then go to CPUINTC directly, while all other devices interrupts
94+
go to PCH-PIC/PCH-LPC and gathered by EIOINTC, and then go to CPUINTC directly::
95+
96+
+-----+ +-----------------------+ +-------+
97+
| IPI | --> | CPUINTC | <-- | Timer |
98+
+-----+ +-----------------------+ +-------+
99+
^ ^ ^
100+
| | |
101+
+---------+ +----------+ +---------+ +-------+
102+
| EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
103+
+---------+ +----------+ +---------+ +-------+
104+
^ ^
105+
| |
106+
+---------+ +---------+
107+
| PCH-PIC | | PCH-MSI |
108+
+---------+ +---------+
109+
^ ^ ^
110+
| | |
111+
+---------+ +---------+ +---------+
112+
| Devices | | PCH-LPC | | Devices |
113+
+---------+ +---------+ +---------+
114+
^
115+
|
116+
+---------+
117+
| Devices |
118+
+---------+
119+
88120
ACPI-related definitions
89121
========================
90122

Documentation/translations/zh_CN/arch/loongarch/irq-chip-model.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,38 @@ PCH-LPC/PCH-MSI,然后被EIOINTC统一收集,再直接到达CPUINTC::
8787
| Devices |
8888
+---------+
8989

90+
高级扩展IRQ模型
91+
===============
92+
93+
在这种模型里面,IPI(Inter-Processor Interrupt)和CPU本地时钟中断直接发送到CPUINTC,
94+
CPU串口(UARTs)中断发送到LIOINTC,PCH-MSI中断发送到AVECINTC,而后通过AVECINTC直接
95+
送达CPUINTC,而其他所有设备的中断则分别发送到所连接的PCH-PIC/PCH-LPC,然后由EIOINTC
96+
统一收集,再直接到达CPUINTC::
97+
98+
+-----+ +-----------------------+ +-------+
99+
| IPI | --> | CPUINTC | <-- | Timer |
100+
+-----+ +-----------------------+ +-------+
101+
^ ^ ^
102+
| | |
103+
+---------+ +----------+ +---------+ +-------+
104+
| EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
105+
+---------+ +----------+ +---------+ +-------+
106+
^ ^
107+
| |
108+
+---------+ +---------+
109+
| PCH-PIC | | PCH-MSI |
110+
+---------+ +---------+
111+
^ ^ ^
112+
| | |
113+
+---------+ +---------+ +---------+
114+
| Devices | | PCH-LPC | | Devices |
115+
+---------+ +---------+ +---------+
116+
^
117+
|
118+
+---------+
119+
| Devices |
120+
+---------+
121+
90122
ACPI相关的定义
91123
==============
92124

arch/loongarch/Kconfig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ config LOONGARCH
2525
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
2626
select ARCH_HAS_PTE_DEVMAP
2727
select ARCH_HAS_PTE_SPECIAL
28+
select ARCH_HAS_SET_MEMORY
29+
select ARCH_HAS_SET_DIRECT_MAP
2830
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
2931
select ARCH_INLINE_READ_LOCK if !PREEMPTION
3032
select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
@@ -82,6 +84,7 @@ config LOONGARCH
8284
select GENERIC_CMOS_UPDATE
8385
select GENERIC_CPU_AUTOPROBE
8486
select GENERIC_CPU_DEVICES
87+
select GENERIC_CPU_VULNERABILITIES
8588
select GENERIC_ENTRY
8689
select GENERIC_GETTIMEOFDAY
8790
select GENERIC_IOREMAP if !ARCH_IOREMAP
@@ -147,7 +150,7 @@ config LOONGARCH
147150
select HAVE_LIVEPATCH
148151
select HAVE_MOD_ARCH_SPECIFIC
149152
select HAVE_NMI
150-
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && !CC_IS_CLANG
153+
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB
151154
select HAVE_PCI
152155
select HAVE_PERF_EVENTS
153156
select HAVE_PERF_REGS
@@ -267,7 +270,7 @@ config AS_HAS_FCSR_CLASS
267270
def_bool $(as-instr,movfcsr2gr \$t0$(comma)\$fcsr0)
268271

269272
config AS_HAS_THIN_ADD_SUB
270-
def_bool $(cc-option,-Wa$(comma)-mthin-add-sub)
273+
def_bool $(cc-option,-Wa$(comma)-mthin-add-sub) || AS_IS_LLVM
271274

272275
config AS_HAS_LSX_EXTENSION
273276
def_bool $(as-instr,vld \$vr0$(comma)\$a0$(comma)0)

arch/loongarch/include/asm/atomic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
#define __LL "ll.w "
1616
#define __SC "sc.w "
1717
#define __AMADD "amadd.w "
18+
#define __AMOR "amor.w "
1819
#define __AMAND_DB "amand_db.w "
1920
#define __AMOR_DB "amor_db.w "
2021
#define __AMXOR_DB "amxor_db.w "
2122
#elif __SIZEOF_LONG__ == 8
2223
#define __LL "ll.d "
2324
#define __SC "sc.d "
2425
#define __AMADD "amadd.d "
26+
#define __AMOR "amor.d "
2527
#define __AMAND_DB "amand_db.d "
2628
#define __AMOR_DB "amor_db.d "
2729
#define __AMXOR_DB "amxor_db.d "

arch/loongarch/include/asm/cpu-features.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define cpu_has_lbt_mips cpu_opt(LOONGARCH_CPU_LBT_MIPS)
5252
#define cpu_has_lbt (cpu_has_lbt_x86|cpu_has_lbt_arm|cpu_has_lbt_mips)
5353
#define cpu_has_csr cpu_opt(LOONGARCH_CPU_CSR)
54+
#define cpu_has_iocsr cpu_opt(LOONGARCH_CPU_IOCSR)
5455
#define cpu_has_tlb cpu_opt(LOONGARCH_CPU_TLB)
5556
#define cpu_has_watch cpu_opt(LOONGARCH_CPU_WATCH)
5657
#define cpu_has_vint cpu_opt(LOONGARCH_CPU_VINT)
@@ -65,6 +66,7 @@
6566
#define cpu_has_guestid cpu_opt(LOONGARCH_CPU_GUESTID)
6667
#define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR)
6768
#define cpu_has_ptw cpu_opt(LOONGARCH_CPU_PTW)
69+
#define cpu_has_lspw cpu_opt(LOONGARCH_CPU_LSPW)
6870
#define cpu_has_avecint cpu_opt(LOONGARCH_CPU_AVECINT)
6971

7072
#endif /* __ASM_CPU_FEATURES_H */

arch/loongarch/include/asm/cpu.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,21 @@ enum cpu_type_enum {
8787
#define CPU_FEATURE_LBT_MIPS 12 /* CPU has MIPS Binary Translation */
8888
#define CPU_FEATURE_TLB 13 /* CPU has TLB */
8989
#define CPU_FEATURE_CSR 14 /* CPU has CSR */
90-
#define CPU_FEATURE_WATCH 15 /* CPU has watchpoint registers */
91-
#define CPU_FEATURE_VINT 16 /* CPU has vectored interrupts */
92-
#define CPU_FEATURE_CSRIPI 17 /* CPU has CSR-IPI */
93-
#define CPU_FEATURE_EXTIOI 18 /* CPU has EXT-IOI */
94-
#define CPU_FEATURE_PREFETCH 19 /* CPU has prefetch instructions */
95-
#define CPU_FEATURE_PMP 20 /* CPU has perfermance counter */
96-
#define CPU_FEATURE_SCALEFREQ 21 /* CPU supports cpufreq scaling */
97-
#define CPU_FEATURE_FLATMODE 22 /* CPU has flat mode */
98-
#define CPU_FEATURE_EIODECODE 23 /* CPU has EXTIOI interrupt pin decode mode */
99-
#define CPU_FEATURE_GUESTID 24 /* CPU has GuestID feature */
100-
#define CPU_FEATURE_HYPERVISOR 25 /* CPU has hypervisor (running in VM) */
101-
#define CPU_FEATURE_PTW 26 /* CPU has hardware page table walker */
102-
#define CPU_FEATURE_AVECINT 27 /* CPU has avec interrupt */
90+
#define CPU_FEATURE_IOCSR 15 /* CPU has IOCSR */
91+
#define CPU_FEATURE_WATCH 16 /* CPU has watchpoint registers */
92+
#define CPU_FEATURE_VINT 17 /* CPU has vectored interrupts */
93+
#define CPU_FEATURE_CSRIPI 18 /* CPU has CSR-IPI */
94+
#define CPU_FEATURE_EXTIOI 19 /* CPU has EXT-IOI */
95+
#define CPU_FEATURE_PREFETCH 20 /* CPU has prefetch instructions */
96+
#define CPU_FEATURE_PMP 21 /* CPU has perfermance counter */
97+
#define CPU_FEATURE_SCALEFREQ 22 /* CPU supports cpufreq scaling */
98+
#define CPU_FEATURE_FLATMODE 23 /* CPU has flat mode */
99+
#define CPU_FEATURE_EIODECODE 24 /* CPU has EXTIOI interrupt pin decode mode */
100+
#define CPU_FEATURE_GUESTID 25 /* CPU has GuestID feature */
101+
#define CPU_FEATURE_HYPERVISOR 26 /* CPU has hypervisor (running in VM) */
102+
#define CPU_FEATURE_PTW 27 /* CPU has hardware page table walker */
103+
#define CPU_FEATURE_LSPW 28 /* CPU has LSPW (lddir/ldpte instructions) */
104+
#define CPU_FEATURE_AVECINT 29 /* CPU has AVEC interrupt */
103105

104106
#define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
105107
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
@@ -115,6 +117,7 @@ enum cpu_type_enum {
115117
#define LOONGARCH_CPU_LBT_ARM BIT_ULL(CPU_FEATURE_LBT_ARM)
116118
#define LOONGARCH_CPU_LBT_MIPS BIT_ULL(CPU_FEATURE_LBT_MIPS)
117119
#define LOONGARCH_CPU_TLB BIT_ULL(CPU_FEATURE_TLB)
120+
#define LOONGARCH_CPU_IOCSR BIT_ULL(CPU_FEATURE_IOCSR)
118121
#define LOONGARCH_CPU_CSR BIT_ULL(CPU_FEATURE_CSR)
119122
#define LOONGARCH_CPU_WATCH BIT_ULL(CPU_FEATURE_WATCH)
120123
#define LOONGARCH_CPU_VINT BIT_ULL(CPU_FEATURE_VINT)
@@ -128,6 +131,7 @@ enum cpu_type_enum {
128131
#define LOONGARCH_CPU_GUESTID BIT_ULL(CPU_FEATURE_GUESTID)
129132
#define LOONGARCH_CPU_HYPERVISOR BIT_ULL(CPU_FEATURE_HYPERVISOR)
130133
#define LOONGARCH_CPU_PTW BIT_ULL(CPU_FEATURE_PTW)
134+
#define LOONGARCH_CPU_LSPW BIT_ULL(CPU_FEATURE_LSPW)
131135
#define LOONGARCH_CPU_AVECINT BIT_ULL(CPU_FEATURE_AVECINT)
132136

133137
#endif /* _ASM_CPU_H */

arch/loongarch/include/asm/loongarch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#define LOONGARCH_CPUCFG1 0x1
6363
#define CPUCFG1_ISGR32 BIT(0)
6464
#define CPUCFG1_ISGR64 BIT(1)
65+
#define CPUCFG1_ISA GENMASK(1, 0)
6566
#define CPUCFG1_PAGING BIT(2)
6667
#define CPUCFG1_IOCSR BIT(3)
6768
#define CPUCFG1_PABITS GENMASK(11, 4)

arch/loongarch/include/asm/mmu_context.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
4949

5050
/* Normal, classic get_new_mmu_context */
5151
static inline void
52-
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
52+
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, bool *need_flush)
5353
{
5454
u64 asid = asid_cache(cpu);
5555

5656
if (!((++asid) & cpu_asid_mask(&cpu_data[cpu])))
57-
local_flush_tlb_user(); /* start new asid cycle */
57+
*need_flush = true; /* start new asid cycle */
5858

5959
cpu_context(cpu, mm) = asid_cache(cpu) = asid;
6060
}
@@ -74,21 +74,34 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
7474
return 0;
7575
}
7676

77+
static inline void atomic_update_pgd_asid(unsigned long asid, unsigned long pgdl)
78+
{
79+
__asm__ __volatile__(
80+
"csrwr %[pgdl_val], %[pgdl_reg] \n\t"
81+
"csrwr %[asid_val], %[asid_reg] \n\t"
82+
: [asid_val] "+r" (asid), [pgdl_val] "+r" (pgdl)
83+
: [asid_reg] "i" (LOONGARCH_CSR_ASID), [pgdl_reg] "i" (LOONGARCH_CSR_PGDL)
84+
: "memory"
85+
);
86+
}
87+
7788
static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
7889
struct task_struct *tsk)
7990
{
91+
bool need_flush = false;
8092
unsigned int cpu = smp_processor_id();
8193

8294
/* Check if our ASID is of an older version and thus invalid */
8395
if (!asid_valid(next, cpu))
84-
get_new_mmu_context(next, cpu);
85-
86-
write_csr_asid(cpu_asid(cpu, next));
96+
get_new_mmu_context(next, cpu, &need_flush);
8797

8898
if (next != &init_mm)
89-
csr_write64((unsigned long)next->pgd, LOONGARCH_CSR_PGDL);
99+
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)next->pgd);
90100
else
91-
csr_write64((unsigned long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
101+
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)invalid_pg_dir);
102+
103+
if (need_flush)
104+
local_flush_tlb_user(); /* Flush tlb after update ASID */
92105

93106
/*
94107
* Mark current->active_mm as not "active" anymore.
@@ -135,9 +148,15 @@ drop_mmu_context(struct mm_struct *mm, unsigned int cpu)
135148
asid = read_csr_asid() & cpu_asid_mask(&current_cpu_data);
136149

137150
if (asid == cpu_asid(cpu, mm)) {
151+
bool need_flush = false;
152+
138153
if (!current->mm || (current->mm == mm)) {
139-
get_new_mmu_context(mm, cpu);
154+
get_new_mmu_context(mm, cpu, &need_flush);
155+
140156
write_csr_asid(cpu_asid(cpu, mm));
157+
if (need_flush)
158+
local_flush_tlb_user(); /* Flush tlb after update ASID */
159+
141160
goto out;
142161
}
143162
}

0 commit comments

Comments
 (0)