summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2025-02-07 15:49:03 +0100
committerVasily Gorbik <gor@linux.ibm.com>2025-03-04 17:18:06 +0100
commitc275169919d16c1db23324199b00a71e1e6ea950 (patch)
tree2d722981737efca23dc2465db6144815bf537372
parentaaab4a4ff3220ef4c3bd7d23c5017e5eabde8aa5 (diff)
s390/diag: Convert MACHINE_HAS_DIAG9C to machine_has_diag9c()
Use static branch(es) to implement and use machine_has_diag9c() instead of a runtime check via MACHINE_HAS_DIAG9C. Reviewed-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--arch/s390/boot/startup.c32
-rw-r--r--arch/s390/include/asm/machine.h2
-rw-r--r--arch/s390/include/asm/setup.h3
-rw-r--r--arch/s390/kernel/early.c18
-rw-r--r--arch/s390/kernel/smp.c3
5 files changed, 36 insertions, 22 deletions
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 50ae83aaef16..41dda285ee2c 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -49,6 +49,37 @@ void error(char *x)
disabled_wait();
}
+static void detect_diag9c(void)
+{
+ unsigned long reg1, reg2;
+ unsigned int cpu;
+ int rc = 1;
+ psw_t old;
+
+ cpu = stap();
+ asm volatile(
+ " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n"
+ " epsw %[reg1],%[reg2]\n"
+ " st %[reg1],0(%[psw_pgm])\n"
+ " st %[reg2],4(%[psw_pgm])\n"
+ " larl %[reg1],1f\n"
+ " stg %[reg1],8(%[psw_pgm])\n"
+ " diag %[cpu],0,0x9c\n"
+ " lhi %[rc],0\n"
+ "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n"
+ : [reg1] "=&d" (reg1),
+ [reg2] "=&a" (reg2),
+ [rc] "+&d" (rc),
+ "+Q" (get_lowcore()->program_new_psw),
+ "=Q" (old)
+ : [psw_old] "a" (&old),
+ [psw_pgm] "a" (&get_lowcore()->program_new_psw),
+ [cpu] "d" (cpu)
+ : "cc", "memory");
+ if (!rc)
+ set_machine_feature(MFEATURE_DIAG9C);
+}
+
static void reset_tod_clock(void)
{
union tod_clock clk;
@@ -488,6 +519,7 @@ void startup_kernel(void)
sclp_early_read_info();
sclp_early_detect_machine_features();
detect_facilities();
+ detect_diag9c();
cmma_init();
sanitize_prot_virt_host();
max_physmem_end = detect_max_physmem_end();
diff --git a/arch/s390/include/asm/machine.h b/arch/s390/include/asm/machine.h
index dd61146d0a8d..4a1f1ab1888a 100644
--- a/arch/s390/include/asm/machine.h
+++ b/arch/s390/include/asm/machine.h
@@ -14,6 +14,7 @@
#define MFEATURE_TLB_GUEST 3
#define MFEATURE_TX 4
#define MFEATURE_ESOP 5
+#define MFEATURE_DIAG9C 6
#ifndef __ASSEMBLY__
@@ -86,6 +87,7 @@ DEFINE_MACHINE_HAS_FEATURE(scc, MFEATURE_SCC)
DEFINE_MACHINE_HAS_FEATURE(tlb_guest, MFEATURE_TLB_GUEST)
DEFINE_MACHINE_HAS_FEATURE(tx, MFEATURE_TX)
DEFINE_MACHINE_HAS_FEATURE(esop, MFEATURE_ESOP)
+DEFINE_MACHINE_HAS_FEATURE(diag9c, MFEATURE_DIAG9C)
#endif /* __ASSEMBLY__ */
#endif /* __ASM_S390_MACHINE_H */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index a90260f80f62..f465f82a9dca 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -20,7 +20,6 @@
#define MACHINE_FLAG_VM BIT(0)
#define MACHINE_FLAG_KVM BIT(1)
#define MACHINE_FLAG_LPAR BIT(2)
-#define MACHINE_FLAG_DIAG9C BIT(3)
#define LPP_MAGIC BIT(31)
#define LPP_PID_MASK _AC(0xffffffff, UL)
@@ -68,8 +67,6 @@ extern unsigned long mio_wb_bit_mask;
#define MACHINE_IS_KVM (get_lowcore()->machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_IS_LPAR (get_lowcore()->machine_flags & MACHINE_FLAG_LPAR)
-#define MACHINE_HAS_DIAG9C (get_lowcore()->machine_flags & MACHINE_FLAG_DIAG9C)
-
/*
* Console mode. Override with conmode=
*/
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index cc4e3d4dc55f..59b15f6a0a02 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -203,23 +203,6 @@ static noinline __init void setup_lowcore_early(void)
lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
}
-static __init void detect_diag9c(void)
-{
- unsigned int cpu_address;
- int rc;
-
- cpu_address = stap();
- diag_stat_inc(DIAG_STAT_X09C);
- asm volatile(
- " diag %2,0,0x9c\n"
- "0: la %0,0\n"
- "1:\n"
- EX_TABLE(0b,1b)
- : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc");
- if (!rc)
- get_lowcore()->machine_flags |= MACHINE_FLAG_DIAG9C;
-}
-
static __init void detect_machine_facilities(void)
{
if (test_facility(129))
@@ -269,7 +252,6 @@ void __init startup_init(void)
detect_machine_type();
setup_arch_string();
setup_boot_command_line();
- detect_diag9c();
detect_machine_facilities();
save_vector_registers();
setup_topology();
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2bf45d95165b..f2f05c5277f4 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -39,6 +39,7 @@
#include <linux/kprobes.h>
#include <asm/access-regs.h>
#include <asm/asm-offsets.h>
+#include <asm/machine.h>
#include <asm/ctlreg.h>
#include <asm/pfault.h>
#include <asm/diag.h>
@@ -417,7 +418,7 @@ EXPORT_SYMBOL(arch_vcpu_is_preempted);
void notrace smp_yield_cpu(int cpu)
{
- if (!MACHINE_HAS_DIAG9C)
+ if (!machine_has_diag9c())
return;
diag_stat_inc_norecursion(DIAG_STAT_X09C);
asm volatile("diag %0,0,0x9c"