* [PATCH v4 0/3] Support Common Not Private translations @ 2018-05-18 10:06 Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 1/3] arm64: mm: " Vladimir Murzin ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Vladimir Murzin @ 2018-05-18 10:06 UTC (permalink / raw) To: linux-arm-kernel Common Not Private (CNP) translations is a feature of ARMv8.2 extension which allows translation table entries to be shared between different PEs in the same inner shareable domain, so the hardware can use this fact to optimise the caching of such entries in the TLB. This patch set is an attempt to bring CNP support into Linux. It was tested on a v8.2 Fast Model with exploring traces and checking that TTBRx_ELy and VTTBR_EL2 have CnP bit set where appropriate. Changelog: v3 -> v4 - rebased on 4.17-rc4 for real v2 -> v3 - do not enable CNP if we are crush kernel (per James) - default to "no" - rebased on 4.17-rc4 v1 -> v2 - handle cpuilde case (per James) - use lm_allias with swapper_pg_dir (per James) - rule out ARM64_SW_TTBR0_PAN case (per Catalin) - s/BUG_ON/WARN_ON/ (per Catalin) - comment and commit message updates (per Catalin) - TTBR_CNP_BIT moved to asm/pgtable-hwdef.h (per Catalin) - has_useable_cnp() simplified (per Julien) RFC -> v1 - dropped RFC tag - rebased on 4.14-rc4 Thanks! Vladimir Murzin (3): arm64: mm: Support Common Not Private translations arm64: KVM: Enable Common Not Private translations arm64: Introduce command line parameter to disable CNP Documentation/admin-guide/kernel-parameters.txt | 4 +++ arch/arm/include/asm/kvm_mmu.h | 5 ++++ arch/arm64/Kconfig | 13 +++++++++ arch/arm64/include/asm/cpucaps.h | 3 +- arch/arm64/include/asm/cpufeature.h | 6 ++++ arch/arm64/include/asm/kvm_mmu.h | 5 ++++ arch/arm64/include/asm/mmu_context.h | 12 ++++++++ arch/arm64/include/asm/pgtable-hwdef.h | 2 ++ arch/arm64/kernel/cpufeature.c | 39 +++++++++++++++++++++++++ arch/arm64/kernel/hibernate.c | 2 +- arch/arm64/kernel/suspend.c | 4 +++ arch/arm64/kvm/hyp-init.S | 3 ++ arch/arm64/mm/context.c | 3 ++ arch/arm64/mm/proc.S | 6 ++++ virt/kvm/arm/arm.c | 4 +-- 15 files changed, 107 insertions(+), 4 deletions(-) -- 2.0.0 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] arm64: mm: Support Common Not Private translations 2018-05-18 10:06 [PATCH v4 0/3] Support Common Not Private translations Vladimir Murzin @ 2018-05-18 10:07 ` Vladimir Murzin 2018-06-08 17:44 ` James Morse 2018-05-18 10:07 ` [PATCH v4 2/3] arm64: KVM: Enable " Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP Vladimir Murzin 2 siblings, 1 reply; 10+ messages in thread From: Vladimir Murzin @ 2018-05-18 10:07 UTC (permalink / raw) To: linux-arm-kernel Common Not Private (CNP) is a feature of ARMv8.2 extension which allows translation table entries to be shared between different PEs in the same inner shareable domain, so the hardware can use this fact to optimise the caching of such entries in the TLB. CNP occupies one bit in TTBRx_ELy and VTTBR_EL2, which advertises to the hardware that the translation table entries pointed to by this TTBR are the same as every PE in the same inner shareable domain for which the equivalent TTBR also has CNP bit set. In case CNP bit is set but TTBR does not point at the same translation table entries for a given ASID and VMID, then the system is mis-configured, so the results of translations are UNPREDICTABLE. For EL1 we postpone setting CNP till all cpus are up and rely on cpufeature framework to 1) patch the code which is sensitive to CNP and 2) update TTBR1_EL1 with CNP bit set. TTBR1_EL1 can be reprogrammed as result of hibernation or cpuidle (via __enable_mmu). cpuidle's path has been changed to restore CnP and for hibernation the code has been changed to save raw TTBR1_EL1 and blindly restore it on resume. For EL0 there are a few cases we need to care of changes in TTBR0_EL1: - a switch to idmap - software emulated PAN we rule out latter via Kconfig options and for the former we make sure that CNP is set for non-zero ASIDs only. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> --- arch/arm64/Kconfig | 13 +++++++++++++ arch/arm64/include/asm/cpucaps.h | 3 ++- arch/arm64/include/asm/cpufeature.h | 6 ++++++ arch/arm64/include/asm/mmu_context.h | 12 ++++++++++++ arch/arm64/include/asm/pgtable-hwdef.h | 2 ++ arch/arm64/kernel/cpufeature.c | 30 ++++++++++++++++++++++++++++++ arch/arm64/kernel/hibernate.c | 2 +- arch/arm64/kernel/suspend.c | 4 ++++ arch/arm64/mm/context.c | 3 +++ arch/arm64/mm/proc.S | 6 ++++++ 10 files changed, 79 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index eb2cf49..cde5d75 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1125,6 +1125,19 @@ config ARM64_RAS_EXTN and access the new registers if the system supports the extension. Platform RAS features may additionally depend on firmware support. +config ARM64_CNP + bool "Enable support for Common Not Private (CNP) translations" + depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN + help + Common Not Private (CNP) allows translation table entries to + be shared between different PEs in the same inner shareable + domain, so the hardware can use this fact to optimise the + caching of such entries in the TLB. + + Selecting this option allows the CNP feature to be detected + at runtime, and does not affect PEs that do not implement + this feature. + endmenu config ARM64_SVE diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index bc51b72..f474a61 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -48,7 +48,8 @@ #define ARM64_HAS_CACHE_IDC 27 #define ARM64_HAS_CACHE_DIC 28 #define ARM64_HW_DBM 29 +#define ARM64_HAS_CNP 30 -#define ARM64_NCAPS 30 +#define ARM64_NCAPS 31 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 09b0f2a..1f7c056 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -510,6 +510,12 @@ static inline bool system_supports_sve(void) cpus_have_const_cap(ARM64_SVE); } +static inline bool system_supports_cnp(void) +{ + return IS_ENABLED(CONFIG_ARM64_CNP) && + cpus_have_const_cap(ARM64_HAS_CNP); +} + /* * Read the pseudo-ZCR used by cpufeatures to identify the supported SVE * vector length. diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 39ec0b8..4f9e3ea 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -149,6 +149,18 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp) phys_addr_t pgd_phys = virt_to_phys(pgdp); + if (system_supports_cnp() && !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) { + /* + * cpu_replace_ttbr1() is used when there's a boot CPU + * up (i.e. cpufeature framework is not up yet) and + * latter only when we enable CNP via cpufeature's + * enable() callback. + * Also we rely on the cpu_hwcap bit being set before + * calling the enable() function. + */ + pgd_phys |= TTBR_CNP_BIT; + } + replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1); cpu_install_idmap(); diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index fd208ea..1d7d8da 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -211,6 +211,8 @@ #define PHYS_MASK_SHIFT (CONFIG_ARM64_PA_BITS) #define PHYS_MASK ((UL(1) << PHYS_MASK_SHIFT) - 1) +#define TTBR_CNP_BIT (UL(1) << 0) + /* * TCR flags. */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9d1b06d..199e9dd 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -20,6 +20,7 @@ #include <linux/bsearch.h> #include <linux/cpumask.h> +#include <linux/crash_dump.h> #include <linux/sort.h> #include <linux/stop_machine.h> #include <linux/types.h> @@ -117,6 +118,7 @@ EXPORT_SYMBOL(cpu_hwcap_keys); static bool __maybe_unused cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused); +static void cpu_enable_cnp(struct arm64_cpu_capabilities const *cap); /* * NOTE: Any changes to the visibility of features should be kept in @@ -858,6 +860,16 @@ static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT); } +static bool __maybe_unused +has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) +{ +#ifdef CONFIG_CRASH_DUMP + if (elfcorehdr_size) + return false; +#endif + return has_cpuid_feature(entry, scope); +} + #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */ @@ -1202,6 +1214,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_hw_dbm, }, #endif +#ifdef CONFIG_ARM64_CNP + { + .desc = "Common not Private translations", + .capability = ARM64_HAS_CNP, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_useable_cnp, + .sys_reg = SYS_ID_AA64MMFR2_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64MMFR2_CNP_SHIFT, + .min_field_value = 1, + .cpu_enable = cpu_enable_cnp, + }, +#endif {}, }; @@ -1642,6 +1667,11 @@ cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused) return (cpus_have_const_cap(ARM64_HAS_PAN) && !cpus_have_const_cap(ARM64_HAS_UAO)); } +static void __maybe_unused cpu_enable_cnp (struct arm64_cpu_capabilities const *cap) +{ + cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); +} + /* * We emulate only the following system register space. * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7] diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 1ec5f28..ea27121 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -125,7 +125,7 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size) return -EOVERFLOW; arch_hdr_invariants(&hdr->invariants); - hdr->ttbr1_el1 = __pa_symbol(swapper_pg_dir); + hdr->ttbr1_el1 = read_sysreg(ttbr1_el1); hdr->reenter_kernel = _cpu_resume; /* We can't use __hyp_get_vectors() because kvm may still be loaded */ diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index a307b9e..9576643 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -48,6 +48,10 @@ void notrace __cpu_suspend_exit(void) */ cpu_uninstall_idmap(); + /* Restore CnP bit in TTBR1_EL1 */ + if (system_supports_cnp()) + cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); + /* * PSTATE was not saved over suspend/resume, re-enable any detected * features that might not have been set correctly. diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c index 301417a..3c1b2c1 100644 --- a/arch/arm64/mm/context.c +++ b/arch/arm64/mm/context.c @@ -196,6 +196,9 @@ void check_and_switch_context(struct mm_struct *mm, unsigned int cpu) unsigned long flags; u64 asid, old_active_asid; + if (system_supports_cnp()) + cpu_set_reserved_ttbr0(); + asid = atomic64_read(&mm->context.id); /* diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 5f9a73a..d46d0ca 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -160,6 +160,12 @@ ENTRY(cpu_do_switch_mm) mrs x2, ttbr1_el1 mmid x1, x1 // get mm->context.id phys_to_ttbr x3, x0 + +alternative_if ARM64_HAS_CNP + cbz x1, 1f // skip CNP for reserved ASID + orr x3, x3, #TTBR_CNP_BIT +1: +alternative_else_nop_endif #ifdef CONFIG_ARM64_SW_TTBR0_PAN bfi x3, x1, #48, #16 // set the ASID field in TTBR0 #endif -- 2.0.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] arm64: mm: Support Common Not Private translations 2018-05-18 10:07 ` [PATCH v4 1/3] arm64: mm: " Vladimir Murzin @ 2018-06-08 17:44 ` James Morse 0 siblings, 0 replies; 10+ messages in thread From: James Morse @ 2018-06-08 17:44 UTC (permalink / raw) To: linux-arm-kernel Hi Vladimir, On 18/05/18 11:07, Vladimir Murzin wrote: > Common Not Private (CNP) is a feature of ARMv8.2 extension which > allows translation table entries to be shared between different PEs in > the same inner shareable domain, so the hardware can use this fact to > optimise the caching of such entries in the TLB. > > CNP occupies one bit in TTBRx_ELy and VTTBR_EL2, which advertises to > the hardware that the translation table entries pointed to by this > TTBR are the same as every PE in the same inner shareable domain for > which the equivalent TTBR also has CNP bit set. In case CNP bit is set > but TTBR does not point at the same translation table entries for a > given ASID and VMID, then the system is mis-configured, so the results > of translations are UNPREDICTABLE. > > For EL1 we postpone setting CNP till all cpus are up and rely on > cpufeature framework to 1) patch the code which is sensitive to CNP > and 2) update TTBR1_EL1 with CNP bit set. TTBR1_EL1 can be > reprogrammed as result of hibernation or cpuidle (via __enable_mmu). > cpuidle's path has been changed to restore CnP and for hibernation the > code has been changed to save raw TTBR1_EL1 and blindly restore it on > resume. > > For EL0 there are a few cases we need to care of changes in > TTBR0_EL1: > - a switch to idmap > - software emulated PAN (Nit: I don't think this has anything to do with EL0, its just the low half of the VA space in TTBR0...) > we rule out latter via Kconfig options and for the former we make > sure that CNP is set for non-zero ASIDs only. Reviewed-by: James Morse <james.morse@arm.com> > diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h > index 39ec0b8..4f9e3ea 100644 > --- a/arch/arm64/include/asm/mmu_context.h > +++ b/arch/arm64/include/asm/mmu_context.h > @@ -149,6 +149,18 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp) > > phys_addr_t pgd_phys = virt_to_phys(pgdp); > > + if (system_supports_cnp() && !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) { > + /* > + * cpu_replace_ttbr1() is used when there's a boot CPU > + * up (i.e. cpufeature framework is not up yet) and > + * latter only when we enable CNP via cpufeature's > + * enable() callback. > + * Also we rely on the cpu_hwcap bit being set before (Nit: stray whitespace) > + * calling the enable() function. > + */ > + pgd_phys |= TTBR_CNP_BIT; > + } > + > replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1); > > cpu_install_idmap(); > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 9d1b06d..199e9dd 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -858,6 +860,16 @@ static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, > return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT); > } > > +static bool __maybe_unused > +has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) > +{ > +#ifdef CONFIG_CRASH_DUMP > + if (elfcorehdr_size) > + return false; > +#endif It might be worth a comment why kdump is relevant, (here or in the commit message). Kdump isn't guaranteed to power-off all secondary CPUs, CNP may share TLB entries with a CPU stuck in the crashed kernel. I don't think we can't trust it even if we bring all CPUs into the new kernel as the DT may not reflect all the CPUs the crashed-kernel had. (kexec doesn't have this problem as it always powers-off secondaries before kexec-ing) > + return has_cpuid_feature(entry, scope); > +} > + > #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 > static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */ > > @@ -1642,6 +1667,11 @@ cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused) > return (cpus_have_const_cap(ARM64_HAS_PAN) && !cpus_have_const_cap(ARM64_HAS_UAO)); > } > > +static void __maybe_unused cpu_enable_cnp (struct arm64_cpu_capabilities const *cap) Nit: stray space between cpu_enable_cnp and the parameters. > +{ > + cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); > +} > + > /* > * We emulate only the following system register space. > * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7] > diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c > index 1ec5f28..ea27121 100644 > --- a/arch/arm64/kernel/hibernate.c > +++ b/arch/arm64/kernel/hibernate.c > @@ -125,7 +125,7 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size) > return -EOVERFLOW; > > arch_hdr_invariants(&hdr->invariants); > - hdr->ttbr1_el1 = __pa_symbol(swapper_pg_dir); > + hdr->ttbr1_el1 = read_sysreg(ttbr1_el1); > hdr->reenter_kernel = _cpu_resume; > > /* We can't use __hyp_get_vectors() because kvm may still be loaded */ We also run__cpu_suspend_exit() from hibernate's restore, which will restore CNP so this isn't strictly necessary. There is some future-cleanup we can do here, if hibernate set the idmap when calling __cpu_suspend_exit(), that function could do the replace_ttbr1() without an extra install/uninstall of the idmap. Thanks, James ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] arm64: KVM: Enable Common Not Private translations 2018-05-18 10:06 [PATCH v4 0/3] Support Common Not Private translations Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 1/3] arm64: mm: " Vladimir Murzin @ 2018-05-18 10:07 ` Vladimir Murzin 2018-05-23 17:11 ` Catalin Marinas 2018-06-08 17:44 ` James Morse 2018-05-18 10:07 ` [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP Vladimir Murzin 2 siblings, 2 replies; 10+ messages in thread From: Vladimir Murzin @ 2018-05-18 10:07 UTC (permalink / raw) To: linux-arm-kernel We rely on cpufeature framework to detect and enable CNP so for KVM we need to patch hyp to set CNP bit just before TTBR0_EL2 gets written. For the guest we encode CNP bit while building vttbr, so we don't need to bother with that in a world switch. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> --- arch/arm/include/asm/kvm_mmu.h | 5 +++++ arch/arm64/include/asm/kvm_mmu.h | 5 +++++ arch/arm64/kvm/hyp-init.S | 3 +++ virt/kvm/arm/arm.c | 4 ++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 707a1f0..9c83710 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -321,6 +321,11 @@ static inline int kvm_map_vectors(void) #define kvm_phys_to_vttbr(addr) (addr) +static inline bool kvm_cpu_has_cnp(void) +{ + return false; +} + #endif /* !__ASSEMBLY__ */ #endif /* __ARM_KVM_MMU_H__ */ diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 0821109..c9ee6c3 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -459,5 +459,10 @@ static inline int kvm_map_vectors(void) #define kvm_phys_to_vttbr(addr) phys_to_ttbr(addr) +static inline bool kvm_cpu_has_cnp(void) +{ + return system_supports_cnp(); +} + #endif /* __ASSEMBLY__ */ #endif /* __ARM64_KVM_MMU_H__ */ diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 6fd91b3..94998d5 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -64,6 +64,9 @@ __do_hyp_init: b.lo __kvm_handle_stub_hvc phys_to_ttbr x4, x0 +alternative_if ARM64_HAS_CNP + orr x4, x4, #TTBR_CNP_BIT +alternative_else_nop_endif msr ttbr0_el2, x4 mrs x4, tcr_el1 diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index a4c1b76..9a651a2 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -472,7 +472,7 @@ static bool need_new_vmid_gen(struct kvm *kvm) static void update_vttbr(struct kvm *kvm) { phys_addr_t pgd_phys; - u64 vmid; + u64 vmid, cnp = kvm_cpu_has_cnp() ? 1 : 0; bool new_gen; read_lock(&kvm_vmid_lock); @@ -522,7 +522,7 @@ static void update_vttbr(struct kvm *kvm) pgd_phys = virt_to_phys(kvm->arch.pgd); BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); - kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid; + kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid | cnp; write_unlock(&kvm_vmid_lock); } -- 2.0.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] arm64: KVM: Enable Common Not Private translations 2018-05-18 10:07 ` [PATCH v4 2/3] arm64: KVM: Enable " Vladimir Murzin @ 2018-05-23 17:11 ` Catalin Marinas 2018-06-08 17:44 ` James Morse 1 sibling, 0 replies; 10+ messages in thread From: Catalin Marinas @ 2018-05-23 17:11 UTC (permalink / raw) To: linux-arm-kernel On Fri, May 18, 2018 at 11:07:01AM +0100, Vladimir Murzin wrote: > diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c > index a4c1b76..9a651a2 100644 > --- a/virt/kvm/arm/arm.c > +++ b/virt/kvm/arm/arm.c > @@ -472,7 +472,7 @@ static bool need_new_vmid_gen(struct kvm *kvm) > static void update_vttbr(struct kvm *kvm) > { > phys_addr_t pgd_phys; > - u64 vmid; > + u64 vmid, cnp = kvm_cpu_has_cnp() ? 1 : 0; Please define a VTTBR_CNP_BIT here instead of a hard-coded value. > bool new_gen; > > read_lock(&kvm_vmid_lock); > @@ -522,7 +522,7 @@ static void update_vttbr(struct kvm *kvm) > pgd_phys = virt_to_phys(kvm->arch.pgd); > BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); > vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); > - kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid; > + kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid | cnp; > > write_unlock(&kvm_vmid_lock); > } -- Catalin ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] arm64: KVM: Enable Common Not Private translations 2018-05-18 10:07 ` [PATCH v4 2/3] arm64: KVM: Enable " Vladimir Murzin 2018-05-23 17:11 ` Catalin Marinas @ 2018-06-08 17:44 ` James Morse 1 sibling, 0 replies; 10+ messages in thread From: James Morse @ 2018-06-08 17:44 UTC (permalink / raw) To: linux-arm-kernel Hi Vladimir, On 18/05/18 11:07, Vladimir Murzin wrote: > We rely on cpufeature framework to detect and enable CNP so for KVM we > need to patch hyp to set CNP bit just before TTBR0_EL2 gets written. > > For the guest we encode CNP bit while building vttbr, so we don't need > to bother with that in a world switch. With the bare-constant fix suggested by Catalin, Reviewed-by: James Morse <james.morse@arm.com> Thanks, James ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP 2018-05-18 10:06 [PATCH v4 0/3] Support Common Not Private translations Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 1/3] arm64: mm: " Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 2/3] arm64: KVM: Enable " Vladimir Murzin @ 2018-05-18 10:07 ` Vladimir Murzin 2018-05-23 17:17 ` Catalin Marinas 2 siblings, 1 reply; 10+ messages in thread From: Vladimir Murzin @ 2018-05-18 10:07 UTC (permalink / raw) To: linux-arm-kernel There are cases when activating of Common Not Private (CNP) feature might not be desirable; this patch allows to forcefully disable CNP even it is supported by hardware. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> --- Documentation/admin-guide/kernel-parameters.txt | 4 ++++ arch/arm64/kernel/cpufeature.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 11fc28e..8f59d47 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2636,6 +2636,10 @@ noclflush [BUGS=X86] Don't use the CLFLUSH instruction + nocnp [ARM64] + Disable CNP (Common not Private translations) + even if it is supported by processor. + nodelayacct [KNL] Disable per-task delay accounting nodsp [SH] Disable hardware DSP at boot time. diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 199e9dd..eee6a31 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -860,6 +860,15 @@ static bool has_cache_dic(const struct arm64_cpu_capabilities *entry, return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT); } +static bool nocnp; + +static int __init early_nocnp(char *p) +{ + nocnp = true; + return 0; +} +early_param("nocnp", early_nocnp); + static bool __maybe_unused has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) { @@ -867,7 +876,7 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) if (elfcorehdr_size) return false; #endif - return has_cpuid_feature(entry, scope); + return has_cpuid_feature(entry, scope) && !nocnp; } #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -- 2.0.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP 2018-05-18 10:07 ` [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP Vladimir Murzin @ 2018-05-23 17:17 ` Catalin Marinas 2018-05-24 8:20 ` Vladimir Murzin 0 siblings, 1 reply; 10+ messages in thread From: Catalin Marinas @ 2018-05-23 17:17 UTC (permalink / raw) To: linux-arm-kernel On Fri, May 18, 2018 at 11:07:02AM +0100, Vladimir Murzin wrote: > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index 11fc28e..8f59d47 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -2636,6 +2636,10 @@ > > noclflush [BUGS=X86] Don't use the CLFLUSH instruction > > + nocnp [ARM64] > + Disable CNP (Common not Private translations) > + even if it is supported by processor. > + > nodelayacct [KNL] Disable per-task delay accounting > > nodsp [SH] Disable hardware DSP at boot time. Do we actually have a use-case for this command line option? I'm not considering hardware errata as these are handled separately in the kernel. -- Catalin ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP 2018-05-23 17:17 ` Catalin Marinas @ 2018-05-24 8:20 ` Vladimir Murzin 2018-06-08 17:44 ` James Morse 0 siblings, 1 reply; 10+ messages in thread From: Vladimir Murzin @ 2018-05-24 8:20 UTC (permalink / raw) To: linux-arm-kernel On 23/05/18 18:17, Catalin Marinas wrote: > On Fri, May 18, 2018 at 11:07:02AM +0100, Vladimir Murzin wrote: >> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt >> index 11fc28e..8f59d47 100644 >> --- a/Documentation/admin-guide/kernel-parameters.txt >> +++ b/Documentation/admin-guide/kernel-parameters.txt >> @@ -2636,6 +2636,10 @@ >> >> noclflush [BUGS=X86] Don't use the CLFLUSH instruction >> >> + nocnp [ARM64] >> + Disable CNP (Common not Private translations) >> + even if it is supported by processor. >> + >> nodelayacct [KNL] Disable per-task delay accounting >> >> nodsp [SH] Disable hardware DSP at boot time. > > Do we actually have a use-case for this command line option? I'm not > considering hardware errata as these are handled separately in the > kernel. > Well, I cannot count all cases, yet we might see CnP support advertised by CPU via ID register (where CPU meant to be part of bL) but not really doing optimisations in hardware. Probably, some userspace (benchmarks) might not benefit of CnP; otoh maybe better way for such case would be user-space asking kernel to {dis,en}able CnP... I have no strong opinion on patch, so I'm fine to drop it and come back when/if we get results from real hardware. Cheers Vladimir ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP 2018-05-24 8:20 ` Vladimir Murzin @ 2018-06-08 17:44 ` James Morse 0 siblings, 0 replies; 10+ messages in thread From: James Morse @ 2018-06-08 17:44 UTC (permalink / raw) To: linux-arm-kernel Hi Vladimir, Catalin, On 24/05/18 09:20, Vladimir Murzin wrote: > On 23/05/18 18:17, Catalin Marinas wrote: >> On Fri, May 18, 2018 at 11:07:02AM +0100, Vladimir Murzin wrote: >>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt >>> index 11fc28e..8f59d47 100644 >>> --- a/Documentation/admin-guide/kernel-parameters.txt >>> +++ b/Documentation/admin-guide/kernel-parameters.txt >>> @@ -2636,6 +2636,10 @@ >>> + nocnp [ARM64] >>> + Disable CNP (Common not Private translations) >>> + even if it is supported by processor. >> Do we actually have a use-case for this command line option? I'm not >> considering hardware errata as these are handled separately in the >> kernel. > Well, I cannot count all cases, yet we might see CnP support advertised > by CPU via ID register (where CPU meant to be part of bL) but not really > doing optimisations in hardware. > > Probably, some userspace (benchmarks) might not benefit of CnP; otoh maybe > better way for such case would be user-space asking kernel to {dis,en}able > CnP... > > I have no strong opinion on patch, so I'm fine to drop it and come back > when/if we get results from real hardware. We may want to disable CNP without rebuilding the kernel, which would also have the affect of code-layout changes... Thanks, James ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-06-08 17:44 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-05-18 10:06 [PATCH v4 0/3] Support Common Not Private translations Vladimir Murzin 2018-05-18 10:07 ` [PATCH v4 1/3] arm64: mm: " Vladimir Murzin 2018-06-08 17:44 ` James Morse 2018-05-18 10:07 ` [PATCH v4 2/3] arm64: KVM: Enable " Vladimir Murzin 2018-05-23 17:11 ` Catalin Marinas 2018-06-08 17:44 ` James Morse 2018-05-18 10:07 ` [PATCH v4 3/3] arm64: Introduce command line parameter to disable CNP Vladimir Murzin 2018-05-23 17:17 ` Catalin Marinas 2018-05-24 8:20 ` Vladimir Murzin 2018-06-08 17:44 ` James Morse
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.