Commit 40aacb31 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'loongarch-fixes-6.3-1' of...

Merge tag 'loongarch-fixes-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:
 "Some bug fixes, some build fixes, a comment fix and a trivial cleanup"

* tag 'loongarch-fixes-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  tools/loongarch: Use __SIZEOF_LONG__ to define __BITS_PER_LONG
  LoongArch: Replace hard-coded values in comments with VALEN
  LoongArch: Clean up plat_swiotlb_setup() related code
  LoongArch: Check unwind_error() in arch_stack_walk()
  LoongArch: Adjust user_regset_copyin parameter to the correct offset
  LoongArch: Adjust user_watch_state for explicit alignment
  LoongArch: module: set section addresses to 0x0
  LoongArch: Mark 3 symbol exports as non-GPL
  LoongArch: Enable PG when wakeup from suspend
  LoongArch: Fix _CONST64_(x) as unsigned
  LoongArch: Fix build error if CONFIG_SUSPEND is not set
  LoongArch: Fix probing of the CRC32 feature
  LoongArch: Make WriteCombine configurable for ioremap()
parents af67688d b5533e99
......@@ -128,6 +128,7 @@ parameter is applicable::
KVM Kernel Virtual Machine support is enabled.
LIBATA Libata driver is enabled
LP Printer support is enabled.
LOONGARCH LoongArch architecture is enabled.
LOOP Loopback device support is enabled.
M68k M68k architecture is enabled.
These options have more detailed description inside of
......
......@@ -6933,6 +6933,12 @@
When enabled, memory and cache locality will be
impacted.
writecombine= [LOONGARCH] Control the MAT (Memory Access Type) of
ioremap_wc().
on - Enable writecombine, use WUC for ioremap_wc()
off - Disable writecombine, use SUC for ioremap_wc()
x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
default x2apic cluster mode on platforms
supporting x2apic.
......
......@@ -447,6 +447,22 @@ config ARCH_IOREMAP
protection support. However, you can enable LoongArch DMW-based
ioremap() for better performance.
config ARCH_WRITECOMBINE
bool "Enable WriteCombine (WUC) for ioremap()"
help
LoongArch maintains cache coherency in hardware, but when paired
with LS7A chipsets the WUC attribute (Weak-ordered UnCached, which
is similar to WriteCombine) is out of the scope of cache coherency
machanism for PCIe devices (this is a PCIe protocol violation, which
may be fixed in newer chipsets).
This means WUC can only used for write-only memory regions now, so
this option is disabled by default, making WUC silently fallback to
SUC for ioremap(). You can enable this option if the kernel is ensured
to run on hardware without this bug.
You can override this setting via writecombine=on/off boot parameter.
config ARCH_STRICT_ALIGN
bool "Enable -mstrict-align to prevent unaligned accesses" if EXPERT
default y
......
......@@ -41,8 +41,11 @@ extern void loongarch_suspend_enter(void);
static inline unsigned long acpi_get_wakeup_address(void)
{
#ifdef CONFIG_SUSPEND
extern void loongarch_wakeup_start(void);
return (unsigned long)loongarch_wakeup_start;
#endif
return 0UL;
}
#endif /* _ASM_LOONGARCH_ACPI_H */
......@@ -71,9 +71,9 @@ extern unsigned long vm_map_base;
#define _ATYPE32_ int
#define _ATYPE64_ __s64
#ifdef CONFIG_64BIT
#define _CONST64_(x) x ## L
#define _CONST64_(x) x ## UL
#else
#define _CONST64_(x) x ## LL
#define _CONST64_(x) x ## ULL
#endif
#endif
......
......@@ -13,7 +13,6 @@ const char *get_system_type(void);
extern void init_environ(void);
extern void memblock_init(void);
extern void platform_init(void);
extern void plat_swiotlb_setup(void);
extern int __init init_numa_memory(void);
struct loongson_board_info {
......
......@@ -42,6 +42,7 @@
#define cpu_has_fpu cpu_opt(LOONGARCH_CPU_FPU)
#define cpu_has_lsx cpu_opt(LOONGARCH_CPU_LSX)
#define cpu_has_lasx cpu_opt(LOONGARCH_CPU_LASX)
#define cpu_has_crc32 cpu_opt(LOONGARCH_CPU_CRC32)
#define cpu_has_complex cpu_opt(LOONGARCH_CPU_COMPLEX)
#define cpu_has_crypto cpu_opt(LOONGARCH_CPU_CRYPTO)
#define cpu_has_lvz cpu_opt(LOONGARCH_CPU_LVZ)
......
......@@ -78,25 +78,26 @@ enum cpu_type_enum {
#define CPU_FEATURE_FPU 3 /* CPU has FPU */
#define CPU_FEATURE_LSX 4 /* CPU has LSX (128-bit SIMD) */
#define CPU_FEATURE_LASX 5 /* CPU has LASX (256-bit SIMD) */
#define CPU_FEATURE_COMPLEX 6 /* CPU has Complex instructions */
#define CPU_FEATURE_CRYPTO 7 /* CPU has Crypto instructions */
#define CPU_FEATURE_LVZ 8 /* CPU has Virtualization extension */
#define CPU_FEATURE_LBT_X86 9 /* CPU has X86 Binary Translation */
#define CPU_FEATURE_LBT_ARM 10 /* CPU has ARM Binary Translation */
#define CPU_FEATURE_LBT_MIPS 11 /* CPU has MIPS Binary Translation */
#define CPU_FEATURE_TLB 12 /* CPU has TLB */
#define CPU_FEATURE_CSR 13 /* CPU has CSR */
#define CPU_FEATURE_WATCH 14 /* CPU has watchpoint registers */
#define CPU_FEATURE_VINT 15 /* CPU has vectored interrupts */
#define CPU_FEATURE_CSRIPI 16 /* CPU has CSR-IPI */
#define CPU_FEATURE_EXTIOI 17 /* CPU has EXT-IOI */
#define CPU_FEATURE_PREFETCH 18 /* CPU has prefetch instructions */
#define CPU_FEATURE_PMP 19 /* CPU has perfermance counter */
#define CPU_FEATURE_SCALEFREQ 20 /* CPU supports cpufreq scaling */
#define CPU_FEATURE_FLATMODE 21 /* CPU has flat mode */
#define CPU_FEATURE_EIODECODE 22 /* CPU has EXTIOI interrupt pin decode mode */
#define CPU_FEATURE_GUESTID 23 /* CPU has GuestID feature */
#define CPU_FEATURE_HYPERVISOR 24 /* CPU has hypervisor (running in VM) */
#define CPU_FEATURE_CRC32 6 /* CPU has CRC32 instructions */
#define CPU_FEATURE_COMPLEX 7 /* CPU has Complex instructions */
#define CPU_FEATURE_CRYPTO 8 /* CPU has Crypto instructions */
#define CPU_FEATURE_LVZ 9 /* CPU has Virtualization extension */
#define CPU_FEATURE_LBT_X86 10 /* CPU has X86 Binary Translation */
#define CPU_FEATURE_LBT_ARM 11 /* CPU has ARM Binary Translation */
#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 LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG)
#define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM)
......@@ -104,6 +105,7 @@ enum cpu_type_enum {
#define LOONGARCH_CPU_FPU BIT_ULL(CPU_FEATURE_FPU)
#define LOONGARCH_CPU_LSX BIT_ULL(CPU_FEATURE_LSX)
#define LOONGARCH_CPU_LASX BIT_ULL(CPU_FEATURE_LASX)
#define LOONGARCH_CPU_CRC32 BIT_ULL(CPU_FEATURE_CRC32)
#define LOONGARCH_CPU_COMPLEX BIT_ULL(CPU_FEATURE_COMPLEX)
#define LOONGARCH_CPU_CRYPTO BIT_ULL(CPU_FEATURE_CRYPTO)
#define LOONGARCH_CPU_LVZ BIT_ULL(CPU_FEATURE_LVZ)
......
......@@ -54,8 +54,10 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
* @offset: bus address of the memory
* @size: size of the resource to map
*/
extern pgprot_t pgprot_wc;
#define ioremap_wc(offset, size) \
ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL_WUC))
ioremap_prot((offset), (size), pgprot_val(pgprot_wc))
#define ioremap_cache(offset, size) \
ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL))
......
......@@ -117,7 +117,7 @@ static inline u32 read_cpucfg(u32 reg)
#define CPUCFG1_EP BIT(22)
#define CPUCFG1_RPLV BIT(23)
#define CPUCFG1_HUGEPG BIT(24)
#define CPUCFG1_IOCSRBRD BIT(25)
#define CPUCFG1_CRC32 BIT(25)
#define CPUCFG1_MSGINT BIT(26)
#define LOONGARCH_CPUCFG2 0x2
......@@ -423,9 +423,9 @@ static __always_inline void iocsr_write64(u64 val, u32 reg)
#define CSR_ASID_ASID_WIDTH 10
#define CSR_ASID_ASID (_ULCAST_(0x3ff) << CSR_ASID_ASID_SHIFT)
#define LOONGARCH_CSR_PGDL 0x19 /* Page table base address when VA[47] = 0 */
#define LOONGARCH_CSR_PGDL 0x19 /* Page table base address when VA[VALEN-1] = 0 */
#define LOONGARCH_CSR_PGDH 0x1a /* Page table base address when VA[47] = 1 */
#define LOONGARCH_CSR_PGDH 0x1a /* Page table base address when VA[VALEN-1] = 1 */
#define LOONGARCH_CSR_PGD 0x1b /* Page table base */
......
......@@ -2,8 +2,8 @@
/* Copyright (C) 2020-2022 Loongson Technology Corporation Limited */
SECTIONS {
. = ALIGN(4);
.got : { BYTE(0) }
.plt : { BYTE(0) }
.plt.idx : { BYTE(0) }
.ftrace_trampoline : { BYTE(0) }
.got 0 : { BYTE(0) }
.plt 0 : { BYTE(0) }
.plt.idx 0 : { BYTE(0) }
.ftrace_trampoline 0 : { BYTE(0) }
}
......@@ -47,11 +47,12 @@ struct user_fp_state {
};
struct user_watch_state {
uint16_t dbg_info;
uint64_t dbg_info;
struct {
uint64_t addr;
uint64_t mask;
uint32_t ctrl;
uint32_t pad;
} dbg_regs[8];
};
......
......@@ -60,7 +60,7 @@ static inline void set_elf_platform(int cpu, const char *plat)
/* MAP BASE */
unsigned long vm_map_base;
EXPORT_SYMBOL_GPL(vm_map_base);
EXPORT_SYMBOL(vm_map_base);
static void cpu_probe_addrbits(struct cpuinfo_loongarch *c)
{
......@@ -94,13 +94,18 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH;
elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32;
elf_hwcap = HWCAP_LOONGARCH_CPUCFG;
config = read_cpucfg(LOONGARCH_CPUCFG1);
if (config & CPUCFG1_UAL) {
c->options |= LOONGARCH_CPU_UAL;
elf_hwcap |= HWCAP_LOONGARCH_UAL;
}
if (config & CPUCFG1_CRC32) {
c->options |= LOONGARCH_CPU_CRC32;
elf_hwcap |= HWCAP_LOONGARCH_CRC32;
}
config = read_cpucfg(LOONGARCH_CPUCFG2);
if (config & CPUCFG2_LAM) {
......
......@@ -76,6 +76,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (cpu_has_fpu) seq_printf(m, " fpu");
if (cpu_has_lsx) seq_printf(m, " lsx");
if (cpu_has_lasx) seq_printf(m, " lasx");
if (cpu_has_crc32) seq_printf(m, " crc32");
if (cpu_has_complex) seq_printf(m, " complex");
if (cpu_has_crypto) seq_printf(m, " crypto");
if (cpu_has_lvz) seq_printf(m, " lvz");
......
......@@ -391,10 +391,10 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
return 0;
}
static int ptrace_hbp_get_resource_info(unsigned int note_type, u16 *info)
static int ptrace_hbp_get_resource_info(unsigned int note_type, u64 *info)
{
u8 num;
u16 reg = 0;
u64 reg = 0;
switch (note_type) {
case NT_LOONGARCH_HW_BREAK:
......@@ -524,15 +524,16 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
return modify_user_hw_breakpoint(bp, &attr);
}
#define PTRACE_HBP_CTRL_SZ sizeof(u32)
#define PTRACE_HBP_ADDR_SZ sizeof(u64)
#define PTRACE_HBP_MASK_SZ sizeof(u64)
#define PTRACE_HBP_CTRL_SZ sizeof(u32)
#define PTRACE_HBP_PAD_SZ sizeof(u32)
static int hw_break_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
u16 info;
u64 info;
u32 ctrl;
u64 addr, mask;
int ret, idx = 0;
......@@ -545,7 +546,7 @@ static int hw_break_get(struct task_struct *target,
membuf_write(&to, &info, sizeof(info));
/* (address, ctrl) registers */
/* (address, mask, ctrl) registers */
while (to.left) {
ret = ptrace_hbp_get_addr(note_type, target, idx, &addr);
if (ret)
......@@ -562,6 +563,7 @@ static int hw_break_get(struct task_struct *target,
membuf_store(&to, addr);
membuf_store(&to, mask);
membuf_store(&to, ctrl);
membuf_zero(&to, sizeof(u32));
idx++;
}
......@@ -582,7 +584,7 @@ static int hw_break_set(struct task_struct *target,
offset = offsetof(struct user_watch_state, dbg_regs);
user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
/* (address, ctrl) registers */
/* (address, mask, ctrl) registers */
limit = regset->n * regset->size;
while (count && offset < limit) {
if (count < PTRACE_HBP_ADDR_SZ)
......@@ -602,7 +604,7 @@ static int hw_break_set(struct task_struct *target,
break;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &mask,
offset, offset + PTRACE_HBP_ADDR_SZ);
offset, offset + PTRACE_HBP_MASK_SZ);
if (ret)
return ret;
......@@ -611,8 +613,8 @@ static int hw_break_set(struct task_struct *target,
return ret;
offset += PTRACE_HBP_MASK_SZ;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &mask,
offset, offset + PTRACE_HBP_MASK_SZ);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl,
offset, offset + PTRACE_HBP_CTRL_SZ);
if (ret)
return ret;
......@@ -620,6 +622,11 @@ static int hw_break_set(struct task_struct *target,
if (ret)
return ret;
offset += PTRACE_HBP_CTRL_SZ;
user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
offset, offset + PTRACE_HBP_PAD_SZ);
offset += PTRACE_HBP_PAD_SZ;
idx++;
}
......
......@@ -160,6 +160,27 @@ static void __init smbios_parse(void)
dmi_walk(find_tokens, NULL);
}
#ifdef CONFIG_ARCH_WRITECOMBINE
pgprot_t pgprot_wc = PAGE_KERNEL_WUC;
#else
pgprot_t pgprot_wc = PAGE_KERNEL_SUC;
#endif
EXPORT_SYMBOL(pgprot_wc);
static int __init setup_writecombine(char *p)
{
if (!strcmp(p, "on"))
pgprot_wc = PAGE_KERNEL_WUC;
else if (!strcmp(p, "off"))
pgprot_wc = PAGE_KERNEL_SUC;
else
pr_warn("Unknown writecombine setting \"%s\".\n", p);
return 0;
}
early_param("writecombine", setup_writecombine);
static int usermem __initdata;
static int __init early_parse_mem(char *p)
......@@ -368,8 +389,8 @@ static void __init arch_mem_init(char **cmdline_p)
/*
* In order to reduce the possibility of kernel panic when failed to
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
* low memory as small as possible before plat_swiotlb_setup(), so
* make sparse_init() using top-down allocation.
* low memory as small as possible before swiotlb_init(), so make
* sparse_init() using top-down allocation.
*/
memblock_set_bottom_up(false);
sparse_init();
......
......@@ -30,7 +30,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
regs->regs[1] = 0;
for (unwind_start(&state, task, regs);
!unwind_done(&state); unwind_next_frame(&state)) {
!unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
addr = unwind_get_return_address(&state);
if (!addr || !consume_entry(cookie, addr))
break;
......
......@@ -28,5 +28,6 @@ bool default_next_frame(struct unwind_state *state)
} while (!get_stack_info(state->sp, state->task, info));
state->error = true;
return false;
}
......@@ -211,7 +211,7 @@ static bool next_frame(struct unwind_state *state)
pc = regs->csr_era;
if (user_mode(regs) || !__kernel_text_address(pc))
return false;
goto out;
state->first = true;
state->pc = pc;
......@@ -226,6 +226,8 @@ static bool next_frame(struct unwind_state *state)
} while (!get_stack_info(state->sp, state->task, info));
out:
state->error = true;
return false;
}
......
......@@ -41,7 +41,7 @@
* don't have to care about aliases on other CPUs.
*/
unsigned long empty_zero_page, zero_page_mask;
EXPORT_SYMBOL_GPL(empty_zero_page);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(zero_page_mask);
void setup_zero_pages(void)
......@@ -270,7 +270,7 @@ pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss;
#endif
#ifndef __PAGETABLE_PMD_FOLDED
pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned_bss;
EXPORT_SYMBOL_GPL(invalid_pmd_table);
EXPORT_SYMBOL(invalid_pmd_table);
#endif
pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
EXPORT_SYMBOL(invalid_pte_table);
......@@ -80,6 +80,10 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
JUMP_VIRT_ADDR t0, t1
/* Enable PG */
li.w t0, 0xb0 # PLV=0, IE=0, PG=1
csrwr t0, LOONGARCH_CSR_CRMD
la.pcrel t0, acpi_saved_sp
ld.d sp, t0, 0
SETUP_WAKEUP
......
......@@ -2,7 +2,7 @@
#ifndef __ASM_LOONGARCH_BITSPERLONG_H
#define __ASM_LOONGARCH_BITSPERLONG_H
#define __BITS_PER_LONG (__SIZEOF_POINTER__ * 8)
#define __BITS_PER_LONG (__SIZEOF_LONG__ * 8)
#include <asm-generic/bitsperlong.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment