mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
LoongArch changes for v6.11
1, Define __ARCH_WANT_NEW_STAT in unistd.h; 2, Always enumerate MADT and setup logical-physical CPU mapping; 3, Add irq_work support via self IPIs; 4, Add RANDOMIZE_KSTACK_OFFSET support; 5, Add ARCH_HAS_PTE_DEVMAP support; 6, Add ARCH_HAS_DEBUG_VM_PGTABLE support; 7, Add writecombine support for DMW-based ioremap(); 8, Add architectural preparation for CPUFreq; 9, Add ACPI standard hardware register based S3 support; 10, Add support for relocating the kernel with RELR relocation; 11, Some bug fixes and other small changes. -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmabzOsWHGNoZW5odWFj YWlAa2VybmVsLm9yZwAKCRAChivD8uImeqssD/9AG3WGb25R4IvgnZYuRCxpXsLk Qrj4YSPazaTLrQBWk1g+KqcBLe+jZV4zmnz0H93qoOpyMDwsmExugDug7QCKiBl1 olVZ0CeQ6dyMHAnFjTgy29KcyJRFith4jXFGq6kpNa80pezsXz7b869GkLZflZfy W9hALfcaxB4kx+z4HXblbOIsfzVwh2eBD/nkWukBG28CPMQ7pV4TtejIqSd9kDC5 LQjVQhjyrDgR3EPJEzr+48/hgFB6cZ8fmfv5JVTu+rQMngUldxDijj8xfoIUgIjN 2khFc2Orx5RVyIuBxtLKWf70HD9xXC0fqUVjFEn0Yn5i1JVLoMdqjownSWvPy3t7 z3V0E0VaYUdLgA3GeA5Fw1uZbORlocAZbA5B8bXY2foNfwPwLlGpNiyNiqx5kQmQ O+9jQJqdrZZ18wXEW8sR8AnT5+lzIQdv1GlkYt2f5a1rjMZwHtPZI4aPRDojPo/3 Fv0Q1+2XVnbPngzJJz9tlYCzt5iuY9z7DwsnbEBSiLZRapJ9ZECmJjSGnnR/fLLS ifdyooua8bviMwzmUEmfSgPRHyTZs+BjkD7AQ4xyRDAv0T2d9sDwkAWYBcViTslF awe6+x+zn6yXekhiloN8L+3HJ67bYojXmLciNqvFcVtSNgJQpXBjLDO9orCbNqmw ISxNA0GbR+eWGMdvCA== =bla1 -----END PGP SIGNATURE----- Merge tag 'loongarch-6.11' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
a362ade892
@ -12,7 +12,7 @@
|
||||
| arm64: | ok |
|
||||
| csky: | TODO |
|
||||
| hexagon: | TODO |
|
||||
| loongarch: | TODO |
|
||||
| loongarch: | ok |
|
||||
| m68k: | TODO |
|
||||
| microblaze: | TODO |
|
||||
| mips: | TODO |
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -710,6 +714,7 @@ config ARCH_HIBERNATION_POSSIBLE
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
source "drivers/acpi/Kconfig"
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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) \
|
||||
|
@ -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) \
|
||||
|
10
arch/loongarch/include/asm/irq_work.h
Normal file
10
arch/loongarch/include/asm/irq_work.h
Normal file
@ -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 */
|
@ -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)
|
||||
@ -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 */
|
||||
@ -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
|
||||
|
@ -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
|
||||
@ -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)
|
||||
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
@ -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))
|
||||
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <uapi/asm/unistd.h>
|
||||
|
||||
#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
|
||||
#define NR_syscalls (__NR_syscalls)
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# No special ABIs on loongarch so far
|
||||
syscall_abis_64 +=
|
||||
syscall_abis_64 += newstat
|
||||
|
@ -57,15 +57,22 @@ 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;
|
||||
|
||||
@ -73,11 +80,13 @@ static int set_processor_mask(u32 id, u32 flags)
|
||||
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;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
@ -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
|
||||
|
@ -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:
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <linux/preempt.h>
|
||||
#include <asm/break.h>
|
||||
|
||||
#define KPROBE_BP_INSN larch_insn_gen_break(BRK_KPROBE_BP)
|
||||
#define KPROBE_SSTEPBP_INSN larch_insn_gen_break(BRK_KPROBE_SSTEPBP)
|
||||
#define KPROBE_BP_INSN __emit_break(BRK_KPROBE_BP)
|
||||
#define KPROBE_SSTEPBP_INSN __emit_break(BRK_KPROBE_SSTEPBP)
|
||||
|
||||
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
|
||||
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kvm_para.h>
|
||||
#include <linux/reboot.h>
|
||||
@ -128,6 +129,11 @@ static irqreturn_t pv_ipi_interrupt(int irq, void *dev)
|
||||
info->ipi_irqs[IPI_CALL_FUNCTION]++;
|
||||
}
|
||||
|
||||
if (action & SMP_IRQ_WORK) {
|
||||
irq_work_run();
|
||||
info->ipi_irqs[IPI_IRQ_WORK]++;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -589,6 +589,7 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type,
|
||||
struct perf_event *bp;
|
||||
struct perf_event_attr attr;
|
||||
struct arch_hw_breakpoint_ctrl ctrl;
|
||||
struct thread_info *ti = task_thread_info(tsk);
|
||||
|
||||
bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
|
||||
if (IS_ERR(bp))
|
||||
@ -613,8 +614,10 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type,
|
||||
if (err)
|
||||
return err;
|
||||
attr.disabled = 0;
|
||||
set_ti_thread_flag(ti, TIF_LOAD_WATCH);
|
||||
} else {
|
||||
attr.disabled = 1;
|
||||
clear_ti_thread_flag(ti, TIF_LOAD_WATCH);
|
||||
}
|
||||
|
||||
return modify_user_hw_breakpoint(bp, &attr);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
#include <asm/inst.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
@ -34,11 +35,27 @@ static inline void __init relocate_relative(void)
|
||||
if (rela->r_info != R_LARCH_RELATIVE)
|
||||
continue;
|
||||
|
||||
if (relocated_addr >= VMLINUX_LOAD_ADDRESS)
|
||||
relocated_addr = (Elf64_Addr)RELOCATED(relocated_addr);
|
||||
|
||||
relocated_addr = (Elf64_Addr)RELOCATED(relocated_addr);
|
||||
*(Elf64_Addr *)RELOCATED(addr) = relocated_addr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RELR
|
||||
u64 *addr = NULL;
|
||||
u64 *relr = (u64 *)&__relr_dyn_begin;
|
||||
u64 *relr_end = (u64 *)&__relr_dyn_end;
|
||||
|
||||
for ( ; relr < relr_end; relr++) {
|
||||
if ((*relr & 1) == 0) {
|
||||
addr = (u64 *)(*relr + reloc_offset);
|
||||
*addr++ += reloc_offset;
|
||||
} else {
|
||||
for (u64 *p = addr, r = *relr >> 1; r; p++, r >>= 1)
|
||||
if (r & 1)
|
||||
*p += reloc_offset;
|
||||
addr += 63;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void __init relocate_absolute(long random_offset)
|
||||
@ -123,6 +140,32 @@ static inline __init bool kaslr_disabled(void)
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
return true;
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
str = strstr(builtin_cmdline, "nohibernate");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
|
||||
return false;
|
||||
|
||||
str = strstr(boot_command_line, "nohibernate");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
return false;
|
||||
|
||||
str = strstr(builtin_cmdline, "noresume");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
|
||||
return false;
|
||||
|
||||
str = strstr(boot_command_line, "noresume");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
return false;
|
||||
|
||||
str = strstr(builtin_cmdline, "resume=");
|
||||
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
|
||||
return true;
|
||||
|
||||
str = strstr(boot_command_line, "resume=");
|
||||
if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -170,7 +213,7 @@ unsigned long __init relocate_kernel(void)
|
||||
unsigned long kernel_length;
|
||||
unsigned long random_offset = 0;
|
||||
void *location_new = _text; /* Default to original kernel start */
|
||||
char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
|
||||
char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
|
||||
|
||||
strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
|
||||
|
||||
@ -182,6 +225,7 @@ unsigned long __init relocate_kernel(void)
|
||||
random_offset = (unsigned long)location_new - (unsigned long)(_text);
|
||||
#endif
|
||||
reloc_offset = (unsigned long)_text - VMLINUX_LOAD_ADDRESS;
|
||||
early_memunmap(cmdline, COMMAND_LINE_SIZE);
|
||||
|
||||
if (random_offset) {
|
||||
kernel_length = (long)(_end) - (long)(_text);
|
||||
|
@ -576,8 +576,10 @@ static void __init prefill_possible_map(void)
|
||||
|
||||
for (i = 0; i < possible; i++)
|
||||
set_cpu_possible(i, true);
|
||||
for (; i < NR_CPUS; i++)
|
||||
for (; i < NR_CPUS; i++) {
|
||||
set_cpu_present(i, false);
|
||||
set_cpu_possible(i, false);
|
||||
}
|
||||
|
||||
set_nr_cpu_ids(possible);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/smp.h>
|
||||
@ -70,6 +71,7 @@ static DEFINE_PER_CPU(int, cpu_state);
|
||||
static const char *ipi_types[NR_IPI] __tracepoint_string = {
|
||||
[IPI_RESCHEDULE] = "Rescheduling interrupts",
|
||||
[IPI_CALL_FUNCTION] = "Function call interrupts",
|
||||
[IPI_IRQ_WORK] = "IRQ work interrupts",
|
||||
};
|
||||
|
||||
void show_ipi_list(struct seq_file *p, int prec)
|
||||
@ -217,6 +219,13 @@ void arch_smp_send_reschedule(int cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arch_smp_send_reschedule);
|
||||
|
||||
#ifdef CONFIG_IRQ_WORK
|
||||
void arch_irq_work_raise(void)
|
||||
{
|
||||
mp_ops.send_ipi_single(smp_processor_id(), ACTION_IRQ_WORK);
|
||||
}
|
||||
#endif
|
||||
|
||||
static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
|
||||
{
|
||||
unsigned int action;
|
||||
@ -234,6 +243,11 @@ static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
|
||||
per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++;
|
||||
}
|
||||
|
||||
if (action & SMP_IRQ_WORK) {
|
||||
irq_work_run();
|
||||
per_cpu(irq_stat, cpu).ipi_irqs[IPI_IRQ_WORK]++;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -271,11 +285,10 @@ static void __init fdt_smp_setup(void)
|
||||
if (cpuid >= nr_cpu_ids)
|
||||
continue;
|
||||
|
||||
if (cpuid == loongson_sysconf.boot_cpu_id) {
|
||||
if (cpuid == loongson_sysconf.boot_cpu_id)
|
||||
cpu = 0;
|
||||
} else {
|
||||
cpu = cpumask_next_zero(-1, cpu_present_mask);
|
||||
}
|
||||
else
|
||||
cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);
|
||||
|
||||
num_processors++;
|
||||
set_cpu_possible(cpu, true);
|
||||
|
@ -9,11 +9,14 @@
|
||||
#include <linux/entry-common.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/objtool.h>
|
||||
#include <linux/randomize_kstack.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/signal.h>
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm-generic/syscalls.h>
|
||||
@ -39,7 +42,7 @@ void *sys_call_table[__NR_syscalls] = {
|
||||
typedef long (*sys_call_fn)(unsigned long, unsigned long,
|
||||
unsigned long, unsigned long, unsigned long, unsigned long);
|
||||
|
||||
void noinstr do_syscall(struct pt_regs *regs)
|
||||
void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long nr;
|
||||
sys_call_fn syscall_fn;
|
||||
@ -55,11 +58,28 @@ void noinstr do_syscall(struct pt_regs *regs)
|
||||
|
||||
nr = syscall_enter_from_user_mode(regs, nr);
|
||||
|
||||
add_random_kstack_offset();
|
||||
|
||||
if (nr < NR_syscalls) {
|
||||
syscall_fn = sys_call_table[nr];
|
||||
regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6],
|
||||
regs->regs[7], regs->regs[8], regs->regs[9]);
|
||||
}
|
||||
|
||||
/*
|
||||
* This value will get limited by KSTACK_OFFSET_MAX(), which is 10
|
||||
* bits. The actual entropy will be further reduced by the compiler
|
||||
* when applying stack alignment constraints: 16-bytes (i.e. 4-bits)
|
||||
* aligned, which will remove the 4 low bits from any entropy chosen
|
||||
* here.
|
||||
*
|
||||
* The resulting 6 bits of entropy is seen in SP[9:4].
|
||||
*/
|
||||
choose_random_kstack_offset(drdtime());
|
||||
|
||||
syscall_exit_to_user_mode(regs);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
|
||||
STACK_FRAME_NON_STANDARD(do_syscall);
|
||||
#endif
|
||||
|
@ -113,6 +113,14 @@ SECTIONS
|
||||
__rela_dyn_end = .;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RELR
|
||||
.relr.dyn : ALIGN(8) {
|
||||
__relr_dyn_begin = .;
|
||||
*(.relr.dyn)
|
||||
__relr_dyn_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
.data.rel : { *(.data.rel*) }
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
|
@ -34,22 +34,49 @@ void enable_pci_wakeup(void)
|
||||
acpi_write_bit_register(ACPI_BITREG_PCIEXP_WAKE_DISABLE, 0);
|
||||
}
|
||||
|
||||
static struct platform_device loongson3_cpufreq_device = {
|
||||
.name = "loongson3_cpufreq",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static int __init loongson_cpufreq_init(void)
|
||||
{
|
||||
if (!cpu_has_scalefreq)
|
||||
return -ENODEV;
|
||||
|
||||
return platform_device_register(&loongson3_cpufreq_device);
|
||||
}
|
||||
|
||||
arch_initcall(loongson_cpufreq_init);
|
||||
|
||||
static void default_suspend_addr(void)
|
||||
{
|
||||
acpi_enter_sleep_state(ACPI_STATE_S3);
|
||||
}
|
||||
|
||||
static int __init loongson3_acpi_suspend_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_status status;
|
||||
uint64_t suspend_addr = 0;
|
||||
|
||||
if (acpi_disabled || acpi_gbl_reduced_hardware)
|
||||
if (acpi_disabled)
|
||||
return 0;
|
||||
|
||||
if (!acpi_gbl_reduced_hardware)
|
||||
acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
|
||||
|
||||
if (!acpi_sleep_state_supported(ACPI_STATE_S3))
|
||||
return 0;
|
||||
|
||||
acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
|
||||
status = acpi_evaluate_integer(NULL, "\\SADR", NULL, &suspend_addr);
|
||||
if (ACPI_FAILURE(status) || !suspend_addr) {
|
||||
pr_err("ACPI S3 is not support!\n");
|
||||
return -1;
|
||||
pr_info("ACPI S3 supported with hardware register default\n");
|
||||
loongson_sysconf.suspend_addr = (u64)default_suspend_addr;
|
||||
} else {
|
||||
pr_info("ACPI S3 supported with Loongson ACPI SADR extension\n");
|
||||
loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr));
|
||||
}
|
||||
loongson_sysconf.suspend_addr = (u64)phys_to_virt(PHYSADDR(suspend_addr));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,18 +66,14 @@ SYM_FUNC_START(loongarch_suspend_enter)
|
||||
la.pcrel a0, loongarch_wakeup_start
|
||||
la.pcrel t0, loongarch_suspend_addr
|
||||
ld.d t0, t0, 0
|
||||
jirl a0, t0, 0 /* Call BIOS's STR sleep routine */
|
||||
jirl ra, t0, 0 /* Call BIOS's STR sleep routine */
|
||||
|
||||
/*
|
||||
* This is where we return upon wakeup.
|
||||
* Reload all of the registers and return.
|
||||
*/
|
||||
SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
|
||||
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
|
||||
|
||||
/* Enable PG */
|
||||
|
@ -74,6 +74,8 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
|
||||
/* Config Direct Mapping */
|
||||
csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
|
||||
csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
|
||||
csr_write64(CSR_DMW2_INIT, LOONGARCH_CSR_DMWIN2);
|
||||
csr_write64(CSR_DMW3_INIT, LOONGARCH_CSR_DMWIN3);
|
||||
|
||||
real_kernel_entry = (void *)kernel_entry_address(kernel_addr, image);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user