Skip to content

Commit

Permalink
Merge tag 'loongarch-6.12' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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
  • Loading branch information
torvalds committed Sep 27, 2024
2 parents ec38498 + f339bd3 commit 3630400
Show file tree
Hide file tree
Showing 25 changed files with 565 additions and 193 deletions.
32 changes: 32 additions & 0 deletions Documentation/arch/loongarch/irq-chip-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,38 @@ to CPUINTC directly::
| Devices |
+---------+

Advanced Extended IRQ model
===========================

In this model, IPI (Inter-Processor Interrupt) and CPU Local Timer interrupt go
to CPUINTC directly, CPU UARTS interrupts go to LIOINTC, PCH-MSI interrupts go
to AVECINTC, and then go to CPUINTC directly, while all other devices interrupts
go to PCH-PIC/PCH-LPC and gathered by EIOINTC, and then go to CPUINTC directly::

+-----+ +-----------------------+ +-------+
| IPI | --> | CPUINTC | <-- | Timer |
+-----+ +-----------------------+ +-------+
^ ^ ^
| | |
+---------+ +----------+ +---------+ +-------+
| EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
+---------+ +----------+ +---------+ +-------+
^ ^
| |
+---------+ +---------+
| PCH-PIC | | PCH-MSI |
+---------+ +---------+
^ ^ ^
| | |
+---------+ +---------+ +---------+
| Devices | | PCH-LPC | | Devices |
+---------+ +---------+ +---------+
^
|
+---------+
| Devices |
+---------+

ACPI-related definitions
========================

Expand Down
32 changes: 32 additions & 0 deletions Documentation/translations/zh_CN/arch/loongarch/irq-chip-model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,38 @@ PCH-LPC/PCH-MSI,然后被EIOINTC统一收集,再直接到达CPUINTC::
| Devices |
+---------+

高级扩展IRQ模型
===============

在这种模型里面,IPI(Inter-Processor Interrupt)和CPU本地时钟中断直接发送到CPUINTC,
CPU串口(UARTs)中断发送到LIOINTC,PCH-MSI中断发送到AVECINTC,而后通过AVECINTC直接
送达CPUINTC,而其他所有设备的中断则分别发送到所连接的PCH-PIC/PCH-LPC,然后由EIOINTC
统一收集,再直接到达CPUINTC::

+-----+ +-----------------------+ +-------+
| IPI | --> | CPUINTC | <-- | Timer |
+-----+ +-----------------------+ +-------+
^ ^ ^
| | |
+---------+ +----------+ +---------+ +-------+
| EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
+---------+ +----------+ +---------+ +-------+
^ ^
| |
+---------+ +---------+
| PCH-PIC | | PCH-MSI |
+---------+ +---------+
^ ^ ^
| | |
+---------+ +---------+ +---------+
| Devices | | PCH-LPC | | Devices |
+---------+ +---------+ +---------+
^
|
+---------+
| Devices |
+---------+

ACPI相关的定义
==============

Expand Down
7 changes: 5 additions & 2 deletions arch/loongarch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ config LOONGARCH
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_PTE_DEVMAP
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_MEMORY
select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_INLINE_READ_LOCK if !PREEMPTION
select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
Expand Down Expand Up @@ -82,6 +84,7 @@ config LOONGARCH
select GENERIC_CMOS_UPDATE
select GENERIC_CPU_AUTOPROBE
select GENERIC_CPU_DEVICES
select GENERIC_CPU_VULNERABILITIES
select GENERIC_ENTRY
select GENERIC_GETTIMEOFDAY
select GENERIC_IOREMAP if !ARCH_IOREMAP
Expand Down Expand Up @@ -147,7 +150,7 @@ config LOONGARCH
select HAVE_LIVEPATCH
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && !CC_IS_CLANG
select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
Expand Down Expand Up @@ -267,7 +270,7 @@ config AS_HAS_FCSR_CLASS
def_bool $(as-instr,movfcsr2gr \$t0$(comma)\$fcsr0)

config AS_HAS_THIN_ADD_SUB
def_bool $(cc-option,-Wa$(comma)-mthin-add-sub)
def_bool $(cc-option,-Wa$(comma)-mthin-add-sub) || AS_IS_LLVM

config AS_HAS_LSX_EXTENSION
def_bool $(as-instr,vld \$vr0$(comma)\$a0$(comma)0)
Expand Down
2 changes: 2 additions & 0 deletions arch/loongarch/include/asm/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#define __LL "ll.w "
#define __SC "sc.w "
#define __AMADD "amadd.w "
#define __AMOR "amor.w "
#define __AMAND_DB "amand_db.w "
#define __AMOR_DB "amor_db.w "
#define __AMXOR_DB "amxor_db.w "
#elif __SIZEOF_LONG__ == 8
#define __LL "ll.d "
#define __SC "sc.d "
#define __AMADD "amadd.d "
#define __AMOR "amor.d "
#define __AMAND_DB "amand_db.d "
#define __AMOR_DB "amor_db.d "
#define __AMXOR_DB "amxor_db.d "
Expand Down
2 changes: 2 additions & 0 deletions arch/loongarch/include/asm/cpu-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define cpu_has_lbt_mips cpu_opt(LOONGARCH_CPU_LBT_MIPS)
#define cpu_has_lbt (cpu_has_lbt_x86|cpu_has_lbt_arm|cpu_has_lbt_mips)
#define cpu_has_csr cpu_opt(LOONGARCH_CPU_CSR)
#define cpu_has_iocsr cpu_opt(LOONGARCH_CPU_IOCSR)
#define cpu_has_tlb cpu_opt(LOONGARCH_CPU_TLB)
#define cpu_has_watch cpu_opt(LOONGARCH_CPU_WATCH)
#define cpu_has_vint cpu_opt(LOONGARCH_CPU_VINT)
Expand All @@ -65,6 +66,7 @@
#define cpu_has_guestid cpu_opt(LOONGARCH_CPU_GUESTID)
#define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR)
#define cpu_has_ptw cpu_opt(LOONGARCH_CPU_PTW)
#define cpu_has_lspw cpu_opt(LOONGARCH_CPU_LSPW)
#define cpu_has_avecint cpu_opt(LOONGARCH_CPU_AVECINT)

#endif /* __ASM_CPU_FEATURES_H */
30 changes: 17 additions & 13 deletions arch/loongarch/include/asm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,21 @@ enum cpu_type_enum {
#define CPU_FEATURE_LBT_MIPS 12 /* CPU has MIPS Binary Translation */
#define CPU_FEATURE_TLB 13 /* CPU has TLB */
#define CPU_FEATURE_CSR 14 /* CPU has CSR */
#define CPU_FEATURE_WATCH 15 /* CPU has watchpoint registers */
#define CPU_FEATURE_VINT 16 /* CPU has vectored interrupts */
#define CPU_FEATURE_CSRIPI 17 /* CPU has CSR-IPI */
#define CPU_FEATURE_EXTIOI 18 /* CPU has EXT-IOI */
#define CPU_FEATURE_PREFETCH 19 /* CPU has prefetch instructions */
#define CPU_FEATURE_PMP 20 /* CPU has perfermance counter */
#define CPU_FEATURE_SCALEFREQ 21 /* CPU supports cpufreq scaling */
#define CPU_FEATURE_FLATMODE 22 /* CPU has flat mode */
#define CPU_FEATURE_EIODECODE 23 /* CPU has EXTIOI interrupt pin decode mode */
#define CPU_FEATURE_GUESTID 24 /* CPU has GuestID feature */
#define CPU_FEATURE_HYPERVISOR 25 /* CPU has hypervisor (running in VM) */
#define CPU_FEATURE_PTW 26 /* CPU has hardware page table walker */
#define CPU_FEATURE_AVECINT 27 /* CPU has avec interrupt */
#define CPU_FEATURE_IOCSR 15 /* CPU has IOCSR */
#define CPU_FEATURE_WATCH 16 /* CPU has watchpoint registers */
#define CPU_FEATURE_VINT 17 /* CPU has vectored interrupts */
#define CPU_FEATURE_CSRIPI 18 /* CPU has CSR-IPI */
#define CPU_FEATURE_EXTIOI 19 /* CPU has EXT-IOI */
#define CPU_FEATURE_PREFETCH 20 /* CPU has prefetch instructions */
#define CPU_FEATURE_PMP 21 /* CPU has perfermance counter */
#define CPU_FEATURE_SCALEFREQ 22 /* CPU supports cpufreq scaling */
#define CPU_FEATURE_FLATMODE 23 /* CPU has flat mode */
#define CPU_FEATURE_EIODECODE 24 /* CPU has EXTIOI interrupt pin decode mode */
#define CPU_FEATURE_GUESTID 25 /* CPU has GuestID feature */
#define CPU_FEATURE_HYPERVISOR 26 /* CPU has hypervisor (running in VM) */
#define CPU_FEATURE_PTW 27 /* CPU has hardware page table walker */
#define CPU_FEATURE_LSPW 28 /* CPU has LSPW (lddir/ldpte instructions) */
#define CPU_FEATURE_AVECINT 29 /* CPU has AVEC interrupt */

#define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
Expand All @@ -115,6 +117,7 @@ enum cpu_type_enum {
#define LOONGARCH_CPU_LBT_ARM BIT_ULL(CPU_FEATURE_LBT_ARM)
#define LOONGARCH_CPU_LBT_MIPS BIT_ULL(CPU_FEATURE_LBT_MIPS)
#define LOONGARCH_CPU_TLB BIT_ULL(CPU_FEATURE_TLB)
#define LOONGARCH_CPU_IOCSR BIT_ULL(CPU_FEATURE_IOCSR)
#define LOONGARCH_CPU_CSR BIT_ULL(CPU_FEATURE_CSR)
#define LOONGARCH_CPU_WATCH BIT_ULL(CPU_FEATURE_WATCH)
#define LOONGARCH_CPU_VINT BIT_ULL(CPU_FEATURE_VINT)
Expand All @@ -128,6 +131,7 @@ enum cpu_type_enum {
#define LOONGARCH_CPU_GUESTID BIT_ULL(CPU_FEATURE_GUESTID)
#define LOONGARCH_CPU_HYPERVISOR BIT_ULL(CPU_FEATURE_HYPERVISOR)
#define LOONGARCH_CPU_PTW BIT_ULL(CPU_FEATURE_PTW)
#define LOONGARCH_CPU_LSPW BIT_ULL(CPU_FEATURE_LSPW)
#define LOONGARCH_CPU_AVECINT BIT_ULL(CPU_FEATURE_AVECINT)

#endif /* _ASM_CPU_H */
1 change: 1 addition & 0 deletions arch/loongarch/include/asm/loongarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#define LOONGARCH_CPUCFG1 0x1
#define CPUCFG1_ISGR32 BIT(0)
#define CPUCFG1_ISGR64 BIT(1)
#define CPUCFG1_ISA GENMASK(1, 0)
#define CPUCFG1_PAGING BIT(2)
#define CPUCFG1_IOCSR BIT(3)
#define CPUCFG1_PABITS GENMASK(11, 4)
Expand Down
35 changes: 27 additions & 8 deletions arch/loongarch/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)

/* Normal, classic get_new_mmu_context */
static inline void
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, bool *need_flush)
{
u64 asid = asid_cache(cpu);

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

cpu_context(cpu, mm) = asid_cache(cpu) = asid;
}
Expand All @@ -74,21 +74,34 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
return 0;
}

static inline void atomic_update_pgd_asid(unsigned long asid, unsigned long pgdl)
{
__asm__ __volatile__(
"csrwr %[pgdl_val], %[pgdl_reg] \n\t"
"csrwr %[asid_val], %[asid_reg] \n\t"
: [asid_val] "+r" (asid), [pgdl_val] "+r" (pgdl)
: [asid_reg] "i" (LOONGARCH_CSR_ASID), [pgdl_reg] "i" (LOONGARCH_CSR_PGDL)
: "memory"
);
}

static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
bool need_flush = false;
unsigned int cpu = smp_processor_id();

/* Check if our ASID is of an older version and thus invalid */
if (!asid_valid(next, cpu))
get_new_mmu_context(next, cpu);

write_csr_asid(cpu_asid(cpu, next));
get_new_mmu_context(next, cpu, &need_flush);

if (next != &init_mm)
csr_write64((unsigned long)next->pgd, LOONGARCH_CSR_PGDL);
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)next->pgd);
else
csr_write64((unsigned long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)invalid_pg_dir);

if (need_flush)
local_flush_tlb_user(); /* Flush tlb after update ASID */

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

if (asid == cpu_asid(cpu, mm)) {
bool need_flush = false;

if (!current->mm || (current->mm == mm)) {
get_new_mmu_context(mm, cpu);
get_new_mmu_context(mm, cpu, &need_flush);

write_csr_asid(cpu_asid(cpu, mm));
if (need_flush)
local_flush_tlb_user(); /* Flush tlb after update ASID */

goto out;
}
}
Expand Down
Loading

0 comments on commit 3630400

Please sign in to comment.