linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] CPUCFG emulation future-proofing & HWCAP addition
@ 2020-05-29 17:09 WANG Xuerui
  2020-05-29 17:09 ` [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG WANG Xuerui
  2020-05-29 17:10 ` [PATCH 2/2] MIPS: Expose Loongson CPUCFG availability via HWCAP WANG Xuerui
  0 siblings, 2 replies; 4+ messages in thread
From: WANG Xuerui @ 2020-05-29 17:09 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: WANG Xuerui, linux-mips

This patch series future-proofs the CPUCFG emulation, in light of
possibility of new Loongson cores still lacking native CPUCFG.
Also an HWCAP flag bit is allocated and exposed for userspace's probing
convenience, per the earlier plan shared on the mailing list.

WANG Xuerui (2):
  MIPS: Loongson64: Guard against future cores without CPUCFG
  MIPS: Expose Loongson CPUCFG availability via HWCAP

 .../include/asm/mach-loongson64/cpucfg-emul.h | 11 +++++
 arch/mips/include/uapi/asm/hwcap.h            |  1 +
 arch/mips/kernel/traps.c                      |  4 ++
 arch/mips/loongson64/cpucfg-emul.c            | 46 +++++++++++--------
 4 files changed, 44 insertions(+), 18 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG
  2020-05-29 17:09 [PATCH 0/2] CPUCFG emulation future-proofing & HWCAP addition WANG Xuerui
@ 2020-05-29 17:09 ` WANG Xuerui
  2020-05-30  4:26   ` Huacai Chen
  2020-05-29 17:10 ` [PATCH 2/2] MIPS: Expose Loongson CPUCFG availability via HWCAP WANG Xuerui
  1 sibling, 1 reply; 4+ messages in thread
From: WANG Xuerui @ 2020-05-29 17:09 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: WANG Xuerui, linux-mips, Huacai Chen, Jiaxun Yang

Previously it was thought that all future Loongson cores would come with
native CPUCFG. From new information shared by Huacai this is definitely
not true (maybe some future 2K cores, for example), so collisions at
PRID_REV level are inevitable. The CPU model matching needs to take
PRID_IMP into consideration.

The emulation logic needs to be disabled for those future cores as well,
as we cannot possibly encode their non-discoverable features right now.

Reported-by: Huacai Chen <chenhc@lemote.com>
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: WANG Xuerui <git@xen0n.name>
---
 .../include/asm/mach-loongson64/cpucfg-emul.h | 11 ++++++
 arch/mips/kernel/traps.c                      |  4 ++
 arch/mips/loongson64/cpucfg-emul.c            | 37 ++++++++++---------
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h b/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
index 01dc308df7b2..d64af19c210d 100644
--- a/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
+++ b/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
@@ -12,6 +12,12 @@
 
 void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c);
 
+static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
+{
+	/* All supported cores have non-zero LOONGSON_CFG1 data. */
+	return c->loongson3_cpucfg_data[0] != 0;
+}
+
 static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
 	__u64 sel)
 {
@@ -53,6 +59,11 @@ static inline void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 {
 }
 
+static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
+{
+	return false;
+}
+
 static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
 	__u64 sel)
 {
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2d5b16daf331..caff4c921461 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -720,6 +720,10 @@ static int simulate_loongson3_cpucfg(struct pt_regs *regs,
 		int rs = (opcode & RS) >> 21;
 		__u64 sel = regs->regs[rs];
 
+		/* Do not emulate on unsupported core models. */
+		if (!loongson3_cpucfg_emulation_enabled(&current_cpu_data))
+			return -1;
+
 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
 
 		regs->regs[rd] = loongson3_cpucfg_read_synthesized(
diff --git a/arch/mips/loongson64/cpucfg-emul.c b/arch/mips/loongson64/cpucfg-emul.c
index fdd52b21c1df..c16023a13379 100644
--- a/arch/mips/loongson64/cpucfg-emul.c
+++ b/arch/mips/loongson64/cpucfg-emul.c
@@ -134,13 +134,9 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 	c->loongson3_cpucfg_data[1] = 0;
 	c->loongson3_cpucfg_data[2] = 0;
 
-	/* Add CPUCFG features non-discoverable otherwise.
-	 *
-	 * All Loongson processors covered by CPUCFG emulation have distinct
-	 * PRID_REV, so take advantage of this.
-	 */
-	switch (c->processor_id & PRID_REV_MASK) {
-	case PRID_REV_LOONGSON3A_R1:
+	/* Add CPUCFG features non-discoverable otherwise. */
+	switch (c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R1:
 		c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
 			LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
 			LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
@@ -153,8 +149,8 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 			LOONGSON_CFG3_LCAMVW_REV1);
 		break;
 
-	case PRID_REV_LOONGSON3B_R1:
-	case PRID_REV_LOONGSON3B_R2:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2:
 		c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
 			LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
 			LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
@@ -167,10 +163,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 			LOONGSON_CFG3_LCAMVW_REV1);
 		break;
 
-	case PRID_REV_LOONGSON2K_R1_0:
-	case PRID_REV_LOONGSON2K_R1_1:
-	case PRID_REV_LOONGSON2K_R1_2:
-	case PRID_REV_LOONGSON2K_R1_3:
+	case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0:
+	case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1:
+	case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2:
+	case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3:
 		decode_loongson_config6(c);
 		probe_uca(c);
 
@@ -183,10 +179,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 		c->loongson3_cpucfg_data[2] = 0;
 		break;
 
-	case PRID_REV_LOONGSON3A_R2_0:
-	case PRID_REV_LOONGSON3A_R2_1:
-	case PRID_REV_LOONGSON3A_R3_0:
-	case PRID_REV_LOONGSON3A_R3_1:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
+	case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
 		decode_loongson_config6(c);
 		probe_uca(c);
 
@@ -203,6 +199,13 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 			LOONGSON_CFG3_LCAMKW_REV1 |
 			LOONGSON_CFG3_LCAMVW_REV1);
 		break;
+
+	default:
+		/* It is possible that some future Loongson cores still do
+		 * not have CPUCFG, so do not emulate anything for these
+		 * cores.
+		 */
+		return;
 	}
 
 	/* This feature is set by firmware, but all known Loongson-64 systems
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] MIPS: Expose Loongson CPUCFG availability via HWCAP
  2020-05-29 17:09 [PATCH 0/2] CPUCFG emulation future-proofing & HWCAP addition WANG Xuerui
  2020-05-29 17:09 ` [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG WANG Xuerui
@ 2020-05-29 17:10 ` WANG Xuerui
  1 sibling, 0 replies; 4+ messages in thread
From: WANG Xuerui @ 2020-05-29 17:10 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: WANG Xuerui, linux-mips, Paul Burton, Jiaxun Yang, Huacai Chen

The point is to allow userspace to probe for CPUCFG without possibly
triggering invalid instructions. In addition to that, future Loongson
feature bits could all be stuffed into CPUCFG bit fields (or "leaves"
in x86-speak) if Loongson does not make mistakes, so ELF HWCAP bits are
conserved.

The other existing Loongson-specific HWCAP bits are, to my best
knowledge, unused, as

(1) they are fairly recent additions,
(2) Loongson never back-ported the patch into their kernel fork, and
(3) Loongson's existing installed base rarely upgrade, if ever;

However, they are still considered userspace ABI, hence unfortunately
unremovable. But at least we could stop adding new Loongson HWCAP bits
in the future.

Cc: Paul Burton <paulburton@kernel.org>
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
Cc: Huacai Chen <chenhc@lemote.com>
Signed-off-by: WANG Xuerui <git@xen0n.name>
---
 arch/mips/include/uapi/asm/hwcap.h | 1 +
 arch/mips/loongson64/cpucfg-emul.c | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/uapi/asm/hwcap.h b/arch/mips/include/uapi/asm/hwcap.h
index 1ade1daa4921..b7e02bdc1985 100644
--- a/arch/mips/include/uapi/asm/hwcap.h
+++ b/arch/mips/include/uapi/asm/hwcap.h
@@ -17,5 +17,6 @@
 #define HWCAP_LOONGSON_MMI  (1 << 11)
 #define HWCAP_LOONGSON_EXT  (1 << 12)
 #define HWCAP_LOONGSON_EXT2 (1 << 13)
+#define HWCAP_LOONGSON_CPUCFG (1 << 14)
 
 #endif /* _UAPI_ASM_HWCAP_H */
diff --git a/arch/mips/loongson64/cpucfg-emul.c b/arch/mips/loongson64/cpucfg-emul.c
index c16023a13379..ca75f07252df 100644
--- a/arch/mips/loongson64/cpucfg-emul.c
+++ b/arch/mips/loongson64/cpucfg-emul.c
@@ -4,6 +4,7 @@
 #include <linux/types.h>
 #include <asm/cpu.h>
 #include <asm/cpu-info.h>
+#include <asm/elf.h>
 
 #include <loongson_regs.h>
 #include <cpucfg-emul.h>
@@ -128,7 +129,7 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 
 	/* CPUs with CPUCFG support don't need to synthesize anything. */
 	if (cpu_has_cfg())
-		return;
+		goto have_cpucfg_now;
 
 	c->loongson3_cpucfg_data[0] = 0;
 	c->loongson3_cpucfg_data[1] = 0;
@@ -217,4 +218,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
 	patch_cpucfg_sel1(c);
 	patch_cpucfg_sel2(c);
 	patch_cpucfg_sel3(c);
+
+have_cpucfg_now:
+	/* We have usable CPUCFG now, emulated or not.
+	 * Announce CPUCFG availability to userspace via hwcap.
+	 */
+	elf_hwcap |= HWCAP_LOONGSON_CPUCFG;
 }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG
  2020-05-29 17:09 ` [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG WANG Xuerui
@ 2020-05-30  4:26   ` Huacai Chen
  0 siblings, 0 replies; 4+ messages in thread
From: Huacai Chen @ 2020-05-30  4:26 UTC (permalink / raw)
  To: WANG Xuerui; +Cc: Thomas Bogendoerfer, open list:MIPS, Jiaxun Yang

Hi, Xuerui,

On Sat, May 30, 2020 at 1:11 AM WANG Xuerui <git@xen0n.name> wrote:
>
> Previously it was thought that all future Loongson cores would come with
> native CPUCFG. From new information shared by Huacai this is definitely
> not true (maybe some future 2K cores, for example), so collisions at
> PRID_REV level are inevitable. The CPU model matching needs to take
> PRID_IMP into consideration.
>
> The emulation logic needs to be disabled for those future cores as well,
> as we cannot possibly encode their non-discoverable features right now.
>
> Reported-by: Huacai Chen <chenhc@lemote.com>
> Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: WANG Xuerui <git@xen0n.name>
> ---
>  .../include/asm/mach-loongson64/cpucfg-emul.h | 11 ++++++
>  arch/mips/kernel/traps.c                      |  4 ++
>  arch/mips/loongson64/cpucfg-emul.c            | 37 ++++++++++---------
>  3 files changed, 35 insertions(+), 17 deletions(-)
>
> diff --git a/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h b/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
> index 01dc308df7b2..d64af19c210d 100644
> --- a/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
> +++ b/arch/mips/include/asm/mach-loongson64/cpucfg-emul.h
> @@ -12,6 +12,12 @@
>
>  void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c);
>
> +static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
> +{
> +       /* All supported cores have non-zero LOONGSON_CFG1 data. */
> +       return c->loongson3_cpucfg_data[0] != 0;
> +}
> +
>  static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
>         __u64 sel)
>  {
> @@ -53,6 +59,11 @@ static inline void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>  {
>  }
>
> +static inline bool loongson3_cpucfg_emulation_enabled(struct cpuinfo_mips *c)
> +{
> +       return false;
> +}
> +
>  static inline u32 loongson3_cpucfg_read_synthesized(struct cpuinfo_mips *c,
>         __u64 sel)
>  {
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index 2d5b16daf331..caff4c921461 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -720,6 +720,10 @@ static int simulate_loongson3_cpucfg(struct pt_regs *regs,
>                 int rs = (opcode & RS) >> 21;
>                 __u64 sel = regs->regs[rs];
>
> +               /* Do not emulate on unsupported core models. */
> +               if (!loongson3_cpucfg_emulation_enabled(&current_cpu_data))
> +                       return -1;
> +
>                 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
>
>                 regs->regs[rd] = loongson3_cpucfg_read_synthesized(
> diff --git a/arch/mips/loongson64/cpucfg-emul.c b/arch/mips/loongson64/cpucfg-emul.c
> index fdd52b21c1df..c16023a13379 100644
> --- a/arch/mips/loongson64/cpucfg-emul.c
> +++ b/arch/mips/loongson64/cpucfg-emul.c
> @@ -134,13 +134,9 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>         c->loongson3_cpucfg_data[1] = 0;
>         c->loongson3_cpucfg_data[2] = 0;
>
> -       /* Add CPUCFG features non-discoverable otherwise.
> -        *
> -        * All Loongson processors covered by CPUCFG emulation have distinct
> -        * PRID_REV, so take advantage of this.
> -        */
> -       switch (c->processor_id & PRID_REV_MASK) {
> -       case PRID_REV_LOONGSON3A_R1:
> +       /* Add CPUCFG features non-discoverable otherwise. */
> +       switch (c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R1:
>                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
>                         LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
>                         LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
> @@ -153,8 +149,8 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>                         LOONGSON_CFG3_LCAMVW_REV1);
>                 break;
>
> -       case PRID_REV_LOONGSON3B_R1:
> -       case PRID_REV_LOONGSON3B_R2:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2:
>                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
>                         LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
>                         LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
> @@ -167,10 +163,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>                         LOONGSON_CFG3_LCAMVW_REV1);
>                 break;
>
> -       case PRID_REV_LOONGSON2K_R1_0:
> -       case PRID_REV_LOONGSON2K_R1_1:
> -       case PRID_REV_LOONGSON2K_R1_2:
> -       case PRID_REV_LOONGSON2K_R1_3:
> +       case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0:
> +       case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1:
> +       case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2:
> +       case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3:
>                 decode_loongson_config6(c);
>                 probe_uca(c);
>
> @@ -183,10 +179,10 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>                 c->loongson3_cpucfg_data[2] = 0;
>                 break;
>
> -       case PRID_REV_LOONGSON3A_R2_0:
> -       case PRID_REV_LOONGSON3A_R2_1:
> -       case PRID_REV_LOONGSON3A_R3_0:
> -       case PRID_REV_LOONGSON3A_R3_1:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
> +       case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
>                 decode_loongson_config6(c);
>                 probe_uca(c);
>
> @@ -203,6 +199,13 @@ void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
>                         LOONGSON_CFG3_LCAMKW_REV1 |
>                         LOONGSON_CFG3_LCAMVW_REV1);
>                 break;
I think it is better to use alpha-betical style here, which means move
Loongson-3B after Loongson-3A (not before Loongson-2K).

> +
> +       default:
> +               /* It is possible that some future Loongson cores still do
> +                * not have CPUCFG, so do not emulate anything for these
> +                * cores.
> +                */
> +               return;
>         }
>
>         /* This feature is set by firmware, but all known Loongson-64 systems
> --
> 2.26.2
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-30  4:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-29 17:09 [PATCH 0/2] CPUCFG emulation future-proofing & HWCAP addition WANG Xuerui
2020-05-29 17:09 ` [PATCH 1/2] MIPS: Loongson64: Guard against future cores without CPUCFG WANG Xuerui
2020-05-30  4:26   ` Huacai Chen
2020-05-29 17:10 ` [PATCH 2/2] MIPS: Expose Loongson CPUCFG availability via HWCAP WANG Xuerui

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).