Skip to content

Commit

Permalink
Merge tag 'loongarch-6.11' 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:

 - Define __ARCH_WANT_NEW_STAT in unistd.h

 - Always enumerate MADT and setup logical-physical CPU mapping

 - Add irq_work support via self IPIs

 - Add RANDOMIZE_KSTACK_OFFSET support

 - Add ARCH_HAS_PTE_DEVMAP support

 - Add ARCH_HAS_DEBUG_VM_PGTABLE support

 - Add writecombine support for DMW-based ioremap()

 - Add architectural preparation for CPUFreq

 - Add ACPI standard hardware register based S3 support

 - Add support for relocating the kernel with RELR relocation

 - Some bug fixes and other small changes

* tag 'loongarch-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: Make the users of larch_insn_gen_break() constant
  LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
  LoongArch: Use rustc option -Zdirect-access-external-data
  LoongArch: Add support for relocating the kernel with RELR relocation
  LoongArch: Remove a redundant checking in relocator
  LoongArch: Use correct API to map cmdline in relocate_kernel()
  LoongArch: Automatically disable KASLR for hibernation
  LoongArch: Add ACPI standard hardware register based S3 support
  LoongArch: Add architectural preparation for CPUFreq
  LoongArch: Add writecombine support for DMW-based ioremap()
  LoongArch: Add ARCH_HAS_DEBUG_VM_PGTABLE support
  LoongArch: Add ARCH_HAS_PTE_DEVMAP support
  LoongArch: Add RANDOMIZE_KSTACK_OFFSET support
  LoongArch: Add irq_work support via self IPIs
  LoongArch: Always enumerate MADT and setup logical-physical CPU mapping
  LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h
  • Loading branch information
Linus Torvalds committed Jul 22, 2024
2 parents 539fbb9 + 998b17d commit a362ade
Show file tree
Hide file tree
Showing 32 changed files with 256 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
| arm64: | ok |
| csky: | TODO |
| hexagon: | TODO |
| loongarch: | TODO |
| loongarch: | ok |
| m68k: | TODO |
| microblaze: | TODO |
| mips: | TODO |
Expand Down
5 changes: 5 additions & 0 deletions arch/loongarch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ config LOONGARCH
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_PTE_DEVMAP
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_INLINE_READ_LOCK if !PREEMPTION
Expand Down Expand Up @@ -106,6 +108,7 @@ config LOONGARCH
select HAVE_ARCH_KFENCE
select HAVE_ARCH_KGDB if PERF_EVENTS
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
Expand Down Expand Up @@ -607,6 +610,7 @@ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION

config RELOCATABLE
bool "Relocatable kernel"
select ARCH_HAS_RELR
help
This builds the kernel as a Position Independent Executable (PIE),
which retains all relocation metadata required, so as to relocate
Expand Down Expand Up @@ -710,6 +714,7 @@ config ARCH_HIBERNATION_POSSIBLE

source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
source "drivers/cpufreq/Kconfig"

endmenu

Expand Down
3 changes: 2 additions & 1 deletion arch/loongarch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ KBUILD_CFLAGS += -fno-jump-tables
endif

KBUILD_RUSTFLAGS += --target=loongarch64-unknown-none-softfloat
KBUILD_RUSTFLAGS_MODULE += -Crelocation-model=pic
KBUILD_RUSTFLAGS_KERNEL += -Zdirect-access-external-data=yes
KBUILD_RUSTFLAGS_MODULE += -Zdirect-access-external-data=no

ifeq ($(CONFIG_RELOCATABLE),y)
KBUILD_CFLAGS_KERNEL += -fPIE
Expand Down
4 changes: 4 additions & 0 deletions arch/loongarch/include/asm/addrspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ extern unsigned long vm_map_base;
#define UNCACHE_BASE CSR_DMW0_BASE
#endif

#ifndef WRITECOMBINE_BASE
#define WRITECOMBINE_BASE CSR_DMW2_BASE
#endif

#define DMW_PABITS 48
#define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1)

Expand Down
1 change: 1 addition & 0 deletions arch/loongarch/include/asm/asmmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@
lu32i.d \reg, 0
lu52i.d \reg, \reg, 0
.pushsection ".la_abs", "aw", %progbits
.p2align 3
.dword 766b
.dword \sym
.popsection
Expand Down
3 changes: 2 additions & 1 deletion arch/loongarch/include/asm/hardirq.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
extern void ack_bad_irq(unsigned int irq);
#define ack_bad_irq ack_bad_irq

#define NR_IPI 2
#define NR_IPI 3

enum ipi_msg_type {
IPI_RESCHEDULE,
IPI_CALL_FUNCTION,
IPI_IRQ_WORK,
};

typedef struct {
Expand Down
3 changes: 3 additions & 0 deletions arch/loongarch/include/asm/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \

DEF_EMIT_REG0I15_FORMAT(break, break_op)

/* like emit_break(imm) but returns a constant expression */
#define __emit_break(imm) ((u32)((imm) | (break_op << 15)))

#define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \
static inline void emit_##NAME(union loongarch_instruction *insn, \
int offset) \
Expand Down
10 changes: 8 additions & 2 deletions arch/loongarch/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ extern void __init early_iounmap(void __iomem *addr, unsigned long size);
static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
unsigned long prot_val)
{
if (prot_val & _CACHE_CC)
switch (prot_val & _CACHE_MASK) {
case _CACHE_CC:
return (void __iomem *)(unsigned long)(CACHE_BASE + offset);
else
case _CACHE_SUC:
return (void __iomem *)(unsigned long)(UNCACHE_BASE + offset);
case _CACHE_WUC:
return (void __iomem *)(unsigned long)(WRITECOMBINE_BASE + offset);
default:
return NULL;
}
}

#define ioremap(offset, size) \
Expand Down
10 changes: 10 additions & 0 deletions arch/loongarch/include/asm/irq_work.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_LOONGARCH_IRQ_WORK_H
#define _ASM_LOONGARCH_IRQ_WORK_H

static inline bool arch_irq_work_has_interrupt(void)
{
return IS_ENABLED(CONFIG_SMP);
}

#endif /* _ASM_LOONGARCH_IRQ_WORK_H */
13 changes: 12 additions & 1 deletion arch/loongarch/include/asm/loongarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@
#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */
#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */

/* Direct Map window 0/1 */
/* Direct Map window 0/1/2/3 */
#define CSR_DMW0_PLV0 _CONST64_(1 << 0)
#define CSR_DMW0_VSEG _CONST64_(0x8000)
#define CSR_DMW0_BASE (CSR_DMW0_VSEG << DMW_PABITS)
Expand All @@ -890,6 +890,14 @@
#define CSR_DMW1_BASE (CSR_DMW1_VSEG << DMW_PABITS)
#define CSR_DMW1_INIT (CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0)

#define CSR_DMW2_PLV0 _CONST64_(1 << 0)
#define CSR_DMW2_MAT _CONST64_(2 << 4)
#define CSR_DMW2_VSEG _CONST64_(0xa000)
#define CSR_DMW2_BASE (CSR_DMW2_VSEG << DMW_PABITS)
#define CSR_DMW2_INIT (CSR_DMW2_BASE | CSR_DMW2_MAT | CSR_DMW2_PLV0)

#define CSR_DMW3_INIT 0x0

/* Performance Counter registers */
#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */
#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */
Expand Down Expand Up @@ -1054,11 +1062,14 @@
#define LOONGARCH_IOCSR_NODECNT 0x408

#define LOONGARCH_IOCSR_MISC_FUNC 0x420
#define IOCSR_MISC_FUNC_SOFT_INT BIT_ULL(10)
#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21)
#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48)

#define LOONGARCH_IOCSR_CPUTEMP 0x428

#define LOONGARCH_IOCSR_SMCMBX 0x51c

/* PerCore CSR, only accessible by local cores */
#define LOONGARCH_IOCSR_IPI_STATUS 0x1000
#define LOONGARCH_IOCSR_IPI_EN 0x1004
Expand Down
6 changes: 4 additions & 2 deletions arch/loongarch/include/asm/pgtable-bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define _PAGE_PFN_SHIFT 12
#define _PAGE_SWP_EXCLUSIVE_SHIFT 23
#define _PAGE_PFN_END_SHIFT 48
#define _PAGE_DEVMAP_SHIFT 59
#define _PAGE_PRESENT_INVALID_SHIFT 60
#define _PAGE_NO_READ_SHIFT 61
#define _PAGE_NO_EXEC_SHIFT 62
Expand All @@ -35,6 +36,7 @@
#define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
#define _PAGE_PROTNONE (_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
#define _PAGE_SPECIAL (_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
#define _PAGE_DEVMAP (_ULCAST_(1) << _PAGE_DEVMAP_SHIFT)

/* We borrow bit 23 to store the exclusive marker in swap PTEs. */
#define _PAGE_SWP_EXCLUSIVE (_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT)
Expand Down Expand Up @@ -74,8 +76,8 @@
#define __READABLE (_PAGE_VALID)
#define __WRITEABLE (_PAGE_DIRTY | _PAGE_WRITE)

#define _PAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
#define _HPAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)
#define _PAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PAGE_DEVMAP | _PFN_MASK | _CACHE_MASK | _PAGE_PLV)
#define _HPAGE_CHG_MASK (_PAGE_MODIFIED | _PAGE_SPECIAL | _PAGE_DEVMAP | _PFN_MASK | _CACHE_MASK | _PAGE_PLV | _PAGE_HUGE)

#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_NO_READ | \
_PAGE_USER | _CACHE_CC)
Expand Down
19 changes: 19 additions & 0 deletions arch/loongarch/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL;
static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; return pte; }
#endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */

static inline int pte_devmap(pte_t pte) { return !!(pte_val(pte) & _PAGE_DEVMAP); }
static inline pte_t pte_mkdevmap(pte_t pte) { pte_val(pte) |= _PAGE_DEVMAP; return pte; }

#define pte_accessible pte_accessible
static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
{
Expand Down Expand Up @@ -558,6 +561,17 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
return pmd;
}

static inline int pmd_devmap(pmd_t pmd)
{
return !!(pmd_val(pmd) & _PAGE_DEVMAP);
}

static inline pmd_t pmd_mkdevmap(pmd_t pmd)
{
pmd_val(pmd) |= _PAGE_DEVMAP;
return pmd;
}

static inline struct page *pmd_page(pmd_t pmd)
{
if (pmd_trans_huge(pmd))
Expand Down Expand Up @@ -613,6 +627,11 @@ static inline long pmd_protnone(pmd_t pmd)
#define pmd_leaf(pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0)
#define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0)

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define pud_devmap(pud) (0)
#define pgd_devmap(pgd) (0)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

/*
* We provide our own get_unmapped area to cope with the virtual aliasing
* constraints placed on us by the cache architecture.
Expand Down
5 changes: 5 additions & 0 deletions arch/loongarch/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ extern long __la_abs_end;
extern long __rela_dyn_begin;
extern long __rela_dyn_end;

#ifdef CONFIG_RELR
extern long __relr_dyn_begin;
extern long __relr_dyn_end;
#endif

extern unsigned long __init relocate_kernel(void);

#endif
Expand Down
2 changes: 2 additions & 0 deletions arch/loongarch/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ extern int __cpu_logical_map[NR_CPUS];
#define ACTION_BOOT_CPU 0
#define ACTION_RESCHEDULE 1
#define ACTION_CALL_FUNCTION 2
#define ACTION_IRQ_WORK 3
#define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU)
#define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE)
#define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION)
#define SMP_IRQ_WORK BIT(ACTION_IRQ_WORK)

struct secondary_data {
unsigned long stack;
Expand Down
11 changes: 11 additions & 0 deletions arch/loongarch/include/asm/stackframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@
cfi_restore \reg \offset \docfi
.endm

.macro SETUP_DMWINS temp
li.d \temp, CSR_DMW0_INIT # WUC, PLV0, 0x8000 xxxx xxxx xxxx
csrwr \temp, LOONGARCH_CSR_DMWIN0
li.d \temp, CSR_DMW1_INIT # CAC, PLV0, 0x9000 xxxx xxxx xxxx
csrwr \temp, LOONGARCH_CSR_DMWIN1
li.d \temp, CSR_DMW2_INIT # WUC, PLV0, 0xa000 xxxx xxxx xxxx
csrwr \temp, LOONGARCH_CSR_DMWIN2
li.d \temp, CSR_DMW3_INIT # 0x0, unused
csrwr \temp, LOONGARCH_CSR_DMWIN3
.endm

/* Jump to the runtime virtual address. */
.macro JUMP_VIRT_ADDR temp1 temp2
li.d \temp1, CACHE_BASE
Expand Down
1 change: 1 addition & 0 deletions arch/loongarch/include/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <uapi/asm/unistd.h>

#define __ARCH_WANT_NEW_STAT
#define __ARCH_WANT_SYS_CLONE

#define NR_syscalls (__NR_syscalls)
4 changes: 2 additions & 2 deletions arch/loongarch/include/asm/uprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ typedef u32 uprobe_opcode_t;
#define MAX_UINSN_BYTES 8
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES

#define UPROBE_SWBP_INSN larch_insn_gen_break(BRK_UPROBE_BP)
#define UPROBE_SWBP_INSN __emit_break(BRK_UPROBE_BP)
#define UPROBE_SWBP_INSN_SIZE LOONGARCH_INSN_SIZE

#define UPROBE_XOLBP_INSN larch_insn_gen_break(BRK_UPROBE_XOLBP)
#define UPROBE_XOLBP_INSN __emit_break(BRK_UPROBE_XOLBP)

struct arch_uprobe {
unsigned long resume_era;
Expand Down
3 changes: 1 addition & 2 deletions arch/loongarch/kernel/Makefile.syscalls
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0

# No special ABIs on loongarch so far
syscall_abis_64 +=
syscall_abis_64 += newstat
22 changes: 16 additions & 6 deletions arch/loongarch/kernel/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,36 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
return ioremap_cache(phys, size);
}

static int cpu_enumerated = 0;

#ifdef CONFIG_SMP
static int set_processor_mask(u32 id, u32 flags)
{

int nr_cpus;
int cpu, cpuid = id;

if (num_processors >= nr_cpu_ids) {
pr_warn(PREFIX "nr_cpus/possible_cpus limit of %i reached."
" processor 0x%x ignored.\n", nr_cpu_ids, cpuid);
if (!cpu_enumerated)
nr_cpus = NR_CPUS;
else
nr_cpus = nr_cpu_ids;

if (num_processors >= nr_cpus) {
pr_warn(PREFIX "nr_cpus limit of %i reached."
" processor 0x%x ignored.\n", nr_cpus, cpuid);

return -ENODEV;

}
if (cpuid == loongson_sysconf.boot_cpu_id)
cpu = 0;
else
cpu = cpumask_next_zero(-1, cpu_present_mask);
cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);

if (!cpu_enumerated)
set_cpu_possible(cpu, true);

if (flags & ACPI_MADT_ENABLED) {
num_processors++;
set_cpu_possible(cpu, true);
set_cpu_present(cpu, true);
__cpu_number_map[cpuid] = cpu;
__cpu_logical_map[cpu] = cpuid;
Expand Down Expand Up @@ -138,6 +147,7 @@ static void __init acpi_process_madt(void)
acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC,
acpi_parse_eio_master, MAX_IO_PICS);

cpu_enumerated = 1;
loongson_sysconf.nr_cpus = num_processors;
}

Expand Down
11 changes: 2 additions & 9 deletions arch/loongarch/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize);
SYM_CODE_START(kernel_entry) # kernel entry point

/* Config direct window and set PG */
li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx
csrwr t0, LOONGARCH_CSR_DMWIN0
li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx
csrwr t0, LOONGARCH_CSR_DMWIN1

SETUP_DMWINS t0
JUMP_VIRT_ADDR t0, t1

/* Enable PG */
Expand Down Expand Up @@ -124,11 +120,8 @@ SYM_CODE_END(kernel_entry)
* function after setting up the stack and tp registers.
*/
SYM_CODE_START(smpboot_entry)
li.d t0, CSR_DMW0_INIT # UC, PLV0
csrwr t0, LOONGARCH_CSR_DMWIN0
li.d t0, CSR_DMW1_INIT # CA, PLV0
csrwr t0, LOONGARCH_CSR_DMWIN1

SETUP_DMWINS t0
JUMP_VIRT_ADDR t0, t1

#ifdef CONFIG_PAGE_SIZE_4KB
Expand Down
2 changes: 1 addition & 1 deletion arch/loongarch/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ static int hw_breakpoint_control(struct perf_event *bp,
}
enable = csr_read64(LOONGARCH_CSR_CRMD);
csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD);
if (bp->hw.target)
if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH))
regs->csr_prmd |= CSR_PRMD_PWE;
break;
case HW_BREAKPOINT_UNINSTALL:
Expand Down
Loading

0 comments on commit a362ade

Please sign in to comment.