From nobody Fri Dec 19 19:22:19 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 58C81259485 for ; Thu, 9 Jan 2025 06:31:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736404285; cv=none; b=iaJ9qG6RepxZGyXeyNlIMJDDcYhU0i0NwCDtsviqKuW0+IX+WT9HYsEXYGqyjYf7KotZ0lPcSSm++YKBfCRz5NmcgNgi8q0UCnkAaysHjJF7xc8s0Y96cxs+UuQyhXugmAPLI+hoBi0pyJlYxKlcSSFA3lb2v11ZpdipwvNQ54U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736404285; c=relaxed/simple; bh=aLFq2nxZ2sdNdfLZxJIlCc2BseCDyw44v/JTQPGTSQA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=bUrAFyrNGSEdW8Wix/E4gaUJcpF7VxSwecW+yJ/2lIfYulJ9qgcmf/EYWA3XE+2+7yHlnxY3jI+MRaGSEBjFEsDI3MvkI+RMGOzo/rpVlfGK9NuiqrBkUBuSisNlHsHn54mg4acCXifmFxDCpj2zWdmyt5+5lYZSQKVBFOeUFks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [223.64.68.63]) by gateway (Coremail) with SMTP id _____8CxieEybX9nO25gAA--.61944S3; Thu, 09 Jan 2025 14:31:14 +0800 (CST) Received: from localhost.localdomain (unknown [223.64.68.63]) by front1 (Coremail) with SMTP id qMiowMBxUMYtbX9np88aAA--.16097S2; Thu, 09 Jan 2025 14:31:13 +0800 (CST) From: Huacai Chen To: Huacai Chen Cc: loongarch@lists.linux.dev, Xuefeng Li , Guo Ren , Xuerui Wang , Jiaxun Yang , linux-kernel@vger.kernel.org, loongson-kernel@lists.loongnix.cn, Huacai Chen Subject: [PATCH] LoongArch: Add debugfs entries to switch SFB/TSO state Date: Thu, 9 Jan 2025 14:30:56 +0800 Message-ID: <20250109063056.2438304-1-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.43.5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowMBxUMYtbX9np88aAA--.16097S2 X-CM-SenderInfo: hfkh0x5xdftxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBj93XoWxKF43Kw4ktr1ktryruFyDJwc_yoWfWw4fp3 4DC3y5Gr48urn3Jr9xtr98ur93W3srGw4aqFZxZ34rCF4IqF1Svrn29r9IvFWkW3s8WryI gF9Yy34YqFWDtwcCm3ZEXasCq-sJn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUU9jb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_tr0E3s1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AK xVW0oVCq3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0c Ia020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jrv_ JF1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwI xGrwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwCFI7km07C267AKxVWU XVWUAwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67 kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY 6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0x vEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Jr0_GrUvcSsGvfC2Kfnx nUUI43ZEXa7IU8hiSPUUUUU== Content-Type: text/plain; charset="utf-8" We need to switch SFB (Store Fill Buffer) and TSO (Total Store Order) state at runtime to debug memory management and KVM virtualization, so add two debugfs entries "sfb_state" and "tso_state" under the directory /sys/kernel/debug/loongarch. Query SFB: cat /sys/kernel/debug/loongarch/sfb_state Enable SFB: echo 1 > /sys/kernel/debug/loongarch/sfb_state Disable SFB: echo 0 > /sys/kernel/debug/loongarch/sfb_state Query TSO: cat /sys/kernel/debug/loongarch/tso_state Switch TSO: echo [TSO] > /sys/kernel/debug/loongarch/tso_state Available [TSO] states: 0 (No Load No Store) 1 (All Load No Store) 3 (Same Load No Store) 4 (No Load All Store) 5 (All Load All Store) 7 (Same Load All Store) Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/loongarch.h | 15 +++ arch/loongarch/kernel/Makefile | 2 +- arch/loongarch/kernel/kdebugfs.c | 168 +++++++++++++++++++++++++ arch/loongarch/kernel/unaligned.c | 8 +- 4 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 arch/loongarch/kernel/kdebugfs.c diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/includ= e/asm/loongarch.h index a3cc4f8d4c4a..15c245636176 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -108,6 +108,12 @@ #define CPUCFG3_SPW_HG_HF BIT(11) #define CPUCFG3_RVA BIT(12) #define CPUCFG3_RVAMAX GENMASK(16, 13) +#define CPUCFG3_ALDORDER_CAP BIT(18) /* All address load ordered, capabi= lity */ +#define CPUCFG3_ASTORDER_CAP BIT(19) /* All address store ordered, capab= ility */ +#define CPUCFG3_ALDORDER_STA BIT(20) /* All address load ordered, status= */ +#define CPUCFG3_ASTORDER_STA BIT(21) /* All address store ordered, statu= s */ +#define CPUCFG3_SLDORDER_CAP BIT(22) /* Same address load ordered, capab= ility */ +#define CPUCFG3_SLDORDER_STA BIT(23) /* Same address load ordered, statu= s */ =20 #define LOONGARCH_CPUCFG4 0x4 #define CPUCFG4_CCFREQ GENMASK(31, 0) @@ -565,6 +571,15 @@ =20 /* Implement dependent */ #define LOONGARCH_CSR_IMPCTL1 0x80 /* Loongson config1 */ +#define CSR_LDSTORDER_SHIFT 28 +#define CSR_LDSTORDER_WIDTH 3 +#define CSR_LDSTORDER_MASK (_ULCAST_(0x7) << CSR_LDSTORDER_SHIFT) +#define CSR_LDSTORDER_NLD_NST (_ULCAST_(0x0) << CSR_LDSTORDER_SHIFT) /* = 000 =3D No Load No Store */ +#define CSR_LDSTORDER_ALD_NST (_ULCAST_(0x1) << CSR_LDSTORDER_SHIFT) /* = 001 =3D All Load No Store */ +#define CSR_LDSTORDER_SLD_NST (_ULCAST_(0x3) << CSR_LDSTORDER_SHIFT) /* = 011 =3D Same Load No Store */ +#define CSR_LDSTORDER_NLD_AST (_ULCAST_(0x4) << CSR_LDSTORDER_SHIFT) /* = 100 =3D No Load All Store */ +#define CSR_LDSTORDER_ALD_AST (_ULCAST_(0x5) << CSR_LDSTORDER_SHIFT) /* = 101 =3D All Load All Store */ +#define CSR_LDSTORDER_SLD_AST (_ULCAST_(0x7) << CSR_LDSTORDER_SHIFT) /* = 111 =3D Same Load All Store */ #define CSR_MISPEC_SHIFT 20 #define CSR_MISPEC_WIDTH 8 #define CSR_MISPEC (_ULCAST_(0xff) << CSR_MISPEC_SHIFT) diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index 9497968ee158..4853e8b04c6f 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -10,7 +10,7 @@ extra-y :=3D vmlinux.lds obj-y +=3D head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \ traps.o irq.o idle.o process.o dma.o mem.o reset.o switch.o \ elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \ - alternative.o unwind.o + alternative.o kdebugfs.o unwind.o =20 obj-$(CONFIG_ACPI) +=3D acpi.o obj-$(CONFIG_EFI) +=3D efi.o diff --git a/arch/loongarch/kernel/kdebugfs.c b/arch/loongarch/kernel/kdebu= gfs.c new file mode 100644 index 000000000000..cf1d89888e32 --- /dev/null +++ b/arch/loongarch/kernel/kdebugfs.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +struct dentry *arch_debugfs_dir; +EXPORT_SYMBOL(arch_debugfs_dir); + +static int sfb_state, tso_state; + +static void set_sfb_state(void *info) +{ + int val =3D *(int *)info << CSR_STFILL_SHIFT; + + csr_xchg32(val, CSR_STFILL, LOONGARCH_CSR_IMPCTL1); +} + +static ssize_t sfb_read(struct file *file, char __user *buf, size_t count,= loff_t *ppos) +{ + int s, state; + char str[32]; + + state =3D (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_STFILL) >> CSR_STFILL_= SHIFT; + + s =3D snprintf(str, sizeof(str), "Boot State: %x\nCurrent State: %x\n", s= fb_state, state); + + if (*ppos >=3D s) + return 0; + + s -=3D *ppos; + s =3D min_t(u32, s, count); + + if (copy_to_user(buf, &str[*ppos], s)) + return -EFAULT; + + *ppos +=3D s; + + return s; +} + +static ssize_t sfb_write(struct file *file, const char __user *buf, size_t= count, loff_t *ppos) +{ + int state; + + if (kstrtoint_from_user(buf, count, 10, &state)) + return -EFAULT; + + switch (state) { + case 0: case 1: + on_each_cpu(set_sfb_state, &state, 1); + break; + default: + return -EINVAL; + } + + return count; +} + +static const struct file_operations sfb_fops =3D { + .read =3D sfb_read, + .write =3D sfb_write, + .open =3D simple_open, + .llseek =3D default_llseek +}; + +#define LDSTORDER_NLD_NST 0x0 /* 000 =3D No Load No Store */ +#define LDSTORDER_ALD_NST 0x1 /* 001 =3D All Load No Store */ +#define LDSTORDER_SLD_NST 0x3 /* 011 =3D Same Load No Store */ +#define LDSTORDER_NLD_AST 0x4 /* 100 =3D No Load All Store */ +#define LDSTORDER_ALD_AST 0x5 /* 101 =3D All Load All Store */ +#define LDSTORDER_SLD_AST 0x7 /* 111 =3D Same Load All Store */ + +static char *tso_hints[] =3D { + "No Load No Store", + "All Load No Store", + "Invalid Config", + "Same Load No Store", + "No Load All Store", + "All Load All Store", + "Invalid Config", + "Same Load All Store" +}; + +static void set_tso_state(void *info) +{ + int val =3D *(int *)info << CSR_LDSTORDER_SHIFT; + + csr_xchg32(val, CSR_LDSTORDER_MASK, LOONGARCH_CSR_IMPCTL1); +} + +static ssize_t tso_read(struct file *file, char __user *buf, size_t count,= loff_t *ppos) +{ + int s, state; + char str[240]; + + state =3D (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_LDSTORDER_MASK) >> CSR= _LDSTORDER_SHIFT; + + s =3D snprintf(str, sizeof(str), "Boot State: %d (%s)\n" + "Current State: %d (%s)\n\n" + "Available States:\n" + "0 (%s)\t" "1 (%s)\t" "3 (%s)\n" + "4 (%s)\t" "5 (%s)\t" "7 (%s)\n", + tso_state, tso_hints[tso_state], state, tso_hints[state], + tso_hints[0], tso_hints[1], tso_hints[3], tso_hints[4], tso_hin= ts[5], tso_hints[7]); + + if (*ppos >=3D s) + return 0; + + s -=3D *ppos; + s =3D min_t(u32, s, count); + + if (copy_to_user(buf, &str[*ppos], s)) + return -EFAULT; + + *ppos +=3D s; + + return s; +} + +static ssize_t tso_write(struct file *file, const char __user *buf, size_t= count, loff_t *ppos) +{ + int state; + + if (kstrtoint_from_user(buf, count, 10, &state)) + return -EFAULT; + + switch (state) { + case 0: case 1: case 3: + case 4: case 5: case 7: + on_each_cpu(set_tso_state, &state, 1); + break; + default: + return -EINVAL; + } + + return count; +} + +static const struct file_operations tso_fops =3D { + .read =3D tso_read, + .write =3D tso_write, + .open =3D simple_open, + .llseek =3D default_llseek +}; + +static int __init arch_kdebugfs_init(void) +{ + unsigned int config =3D read_cpucfg(LOONGARCH_CPUCFG3); + + arch_debugfs_dir =3D debugfs_create_dir("loongarch", NULL); + + if (config & CPUCFG3_SFB) { + debugfs_create_file("sfb_state", S_IRUGO | S_IWUGO, + arch_debugfs_dir, &sfb_state, &sfb_fops); + sfb_state =3D (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_STFILL) >> CSR_ST= FILL_SHIFT; + } + + if (config & (CPUCFG3_ALDORDER_CAP | CPUCFG3_ASTORDER_CAP)) { + debugfs_create_file("tso_state", S_IRUGO | S_IWUGO, + arch_debugfs_dir, &tso_state, &tso_fops); + tso_state =3D (csr_read32(LOONGARCH_CSR_IMPCTL1) & CSR_LDSTORDER_MASK) >= > CSR_LDSTORDER_SHIFT; + } + + return 0; +} +postcore_initcall(arch_kdebugfs_init); diff --git a/arch/loongarch/kernel/unaligned.c b/arch/loongarch/kernel/unal= igned.c index 3abf163dda05..487be604b96a 100644 --- a/arch/loongarch/kernel/unaligned.c +++ b/arch/loongarch/kernel/unaligned.c @@ -482,14 +482,10 @@ void emulate_load_store_insn(struct pt_regs *regs, vo= id __user *addr, unsigned i #ifdef CONFIG_DEBUG_FS static int __init debugfs_unaligned(void) { - struct dentry *d; - - d =3D debugfs_create_dir("loongarch", NULL); - debugfs_create_u32("unaligned_instructions_user", - S_IRUGO, d, &unaligned_instructions_user); + S_IRUGO, arch_debugfs_dir, &unaligned_instructions_user); debugfs_create_u32("unaligned_instructions_kernel", - S_IRUGO, d, &unaligned_instructions_kernel); + S_IRUGO, arch_debugfs_dir, &unaligned_instructions_kernel); =20 return 0; } --=20 2.43.5