From 17d3804808091e3942d2744dc8155a3a918d88c3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 7 Feb 2025 15:49:00 +0100 Subject: [PATCH] s390/tlb: Convert MACHINE_HAS_TLB_GUEST to machine_has_tlb_guest() Use static branch(es) to implement and use machine_has_tlb_guest() instead of a runtime check via MACHINE_HAS_TLB_GUEST. Also add sclp_early_detect_machine_features() in order to allow for feature detection from the decompressor. Reviewed-by: Vasily Gorbik Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/boot/startup.c | 1 + arch/s390/include/asm/machine.h | 2 ++ arch/s390/include/asm/sclp.h | 1 + arch/s390/include/asm/setup.h | 2 -- arch/s390/include/asm/tlbflush.h | 3 ++- arch/s390/kvm/kvm-s390.c | 3 ++- arch/s390/mm/gmap.c | 7 ++++--- arch/s390/mm/pgtable.c | 13 +++++++------ drivers/s390/char/sclp_early.c | 2 -- drivers/s390/char/sclp_early_core.c | 11 +++++++++++ 10 files changed, 30 insertions(+), 15 deletions(-) diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 1c7367a338cdd..4ef2622f3d300 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -482,6 +482,7 @@ void startup_kernel(void) read_ipl_report(); sclp_early_read_info(); + sclp_early_detect_machine_features(); detect_facilities(); cmma_init(); sanitize_prot_virt_host(); diff --git a/arch/s390/include/asm/machine.h b/arch/s390/include/asm/machine.h index e0a0e4121d08c..33cb4403fc82b 100644 --- a/arch/s390/include/asm/machine.h +++ b/arch/s390/include/asm/machine.h @@ -11,6 +11,7 @@ #define MFEATURE_LOWCORE 0 #define MFEATURE_PCI_MIO 1 #define MFEATURE_SCC 2 +#define MFEATURE_TLB_GUEST 3 #ifndef __ASSEMBLY__ @@ -80,6 +81,7 @@ static __always_inline bool machine_has_##name(void) \ DEFINE_MACHINE_HAS_FEATURE(relocated_lowcore, MFEATURE_LOWCORE) DEFINE_MACHINE_HAS_FEATURE(scc, MFEATURE_SCC) +DEFINE_MACHINE_HAS_FEATURE(tlb_guest, MFEATURE_TLB_GUEST) #endif /* __ASSEMBLY__ */ #endif /* __ASM_S390_MACHINE_H */ diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 18f37dff03c99..1e62919bacf4a 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -168,6 +168,7 @@ int sclp_early_read_storage_info(void); int sclp_early_get_core_info(struct sclp_core_info *info); void sclp_early_get_ipl_info(struct sclp_ipl_info *info); void sclp_early_detect(void); +void sclp_early_detect_machine_features(void); void sclp_early_printk(const char *s); void __sclp_early_printk(const char *s, unsigned int len); void sclp_emergency_printk(const char *s); diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index b1f6ea1e000aa..bb9d701ec9a6f 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -23,7 +23,6 @@ #define MACHINE_FLAG_DIAG9C BIT(3) #define MACHINE_FLAG_ESOP BIT(4) #define MACHINE_FLAG_TE BIT(11) -#define MACHINE_FLAG_TLB_GUEST BIT(14) #define LPP_MAGIC BIT(31) #define LPP_PID_MASK _AC(0xffffffff, UL) @@ -74,7 +73,6 @@ extern unsigned long mio_wb_bit_mask; #define MACHINE_HAS_DIAG9C (get_lowcore()->machine_flags & MACHINE_FLAG_DIAG9C) #define MACHINE_HAS_ESOP (get_lowcore()->machine_flags & MACHINE_FLAG_ESOP) #define MACHINE_HAS_TE (get_lowcore()->machine_flags & MACHINE_FLAG_TE) -#define MACHINE_HAS_TLB_GUEST (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_GUEST) /* * Console mode. Override with conmode= diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 4a062317ca714..75491baa21974 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -6,6 +6,7 @@ #include #include #include +#include /* * Flush all TLB entries on the local CPU. @@ -23,7 +24,7 @@ static inline void __tlb_flush_idte(unsigned long asce) unsigned long opt; opt = IDTE_PTOA; - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) opt |= IDTE_GUEST_ASCE; /* Global TLB flush for the mm */ asm volatile("idte 0,%1,%0" : : "a" (opt), "a" (asce) : "cc"); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 703a6594cfafc..df21ea6fbd598 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -3397,7 +3398,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) /* we emulate STHYI in kvm */ set_kvm_facility(kvm->arch.model.fac_mask, 74); set_kvm_facility(kvm->arch.model.fac_list, 74); - if (MACHINE_HAS_TLB_GUEST) { + if (machine_has_tlb_guest()) { set_kvm_facility(kvm->arch.model.fac_mask, 147); set_kvm_facility(kvm->arch.model.fac_list, 147); } diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 7a2f5effd6263..0d7cce4f3e830 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -2026,7 +2027,7 @@ static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new, gaddr &= HPAGE_MASK; pmdp_notify_gmap(gmap, pmdp, gaddr); new = clear_pmd_bit(new, __pgprot(_SEGMENT_ENTRY_GMAP_IN)); - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_GLOBAL); else if (cpu_has_idte()) @@ -2104,7 +2105,7 @@ void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr) WARN_ON(pmd_val(*pmdp) & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | _SEGMENT_ENTRY_GMAP_UC | _SEGMENT_ENTRY)); - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_LOCAL); else if (cpu_has_idte()) @@ -2137,7 +2138,7 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr) WARN_ON(pmd_val(*pmdp) & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | _SEGMENT_ENTRY_GMAP_UC | _SEGMENT_ENTRY)); - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_GLOBAL); else if (cpu_has_idte()) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index ee3c4fec5055a..f6712781d8a1a 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -24,6 +24,7 @@ #include #include #include +#include pgprot_t pgprot_writecombine(pgprot_t prot) { @@ -50,7 +51,7 @@ static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr, { unsigned long opt, asce; - if (MACHINE_HAS_TLB_GUEST) { + if (machine_has_tlb_guest()) { opt = 0; asce = READ_ONCE(mm->context.gmap_asce); if (asce == 0UL || nodat) @@ -70,7 +71,7 @@ static inline void ptep_ipte_global(struct mm_struct *mm, unsigned long addr, { unsigned long opt, asce; - if (MACHINE_HAS_TLB_GUEST) { + if (machine_has_tlb_guest()) { opt = 0; asce = READ_ONCE(mm->context.gmap_asce); if (asce == 0UL || nodat) @@ -375,7 +376,7 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, static inline void pmdp_idte_local(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp) { - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, mm->context.asce, IDTE_LOCAL); else @@ -387,7 +388,7 @@ static inline void pmdp_idte_local(struct mm_struct *mm, static inline void pmdp_idte_global(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp) { - if (MACHINE_HAS_TLB_GUEST) { + if (machine_has_tlb_guest()) { __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, mm->context.asce, IDTE_GLOBAL); if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m) @@ -506,7 +507,7 @@ EXPORT_SYMBOL(pmdp_xchg_lazy); static inline void pudp_idte_local(struct mm_struct *mm, unsigned long addr, pud_t *pudp) { - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, mm->context.asce, IDTE_LOCAL); else @@ -516,7 +517,7 @@ static inline void pudp_idte_local(struct mm_struct *mm, static inline void pudp_idte_global(struct mm_struct *mm, unsigned long addr, pud_t *pudp) { - if (MACHINE_HAS_TLB_GUEST) + if (machine_has_tlb_guest()) __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, mm->context.asce, IDTE_GLOBAL); else if (cpu_has_idte()) diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index d9d6edaf8de82..fc83f157c4e45 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -52,8 +52,6 @@ static void __init sclp_early_facilities_detect(void) sclp.has_zpci_lsi = !!(sccb->fac118 & 0x01); if (sccb->fac85 & 0x02) get_lowcore()->machine_flags |= MACHINE_FLAG_ESOP; - if (sccb->fac91 & 0x40) - get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_GUEST; sclp.has_diag204_bif = !!(sccb->fac98 & 0x80); sclp.has_diag310 = !!(sccb->fac91 & 0x80); if (sccb->cpuoff > 134) { diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c index 5a5383cceb6ff..d03ad01082d09 100644 --- a/drivers/s390/char/sclp_early_core.c +++ b/drivers/s390/char/sclp_early_core.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "sclp.h" #include "sclp_rw.h" @@ -335,6 +336,16 @@ int __init sclp_early_get_hsa_size(unsigned long *hsa_size) return 0; } +void __init sclp_early_detect_machine_features(void) +{ + struct read_info_sccb *sccb = &sclp_info_sccb; + + if (!sclp_info_sccb_valid) + return; + if (sccb->fac91 & 0x40) + set_machine_feature(MFEATURE_TLB_GUEST); +} + #define SCLP_STORAGE_INFO_FACILITY 0x0000400000000000UL void __weak __init add_physmem_online_range(u64 start, u64 end) {} -- 2.47.2