* [RFC PATCH 0/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency
@ 2024-12-03 0:59 Kevin Loughlin
2024-12-03 0:59 ` [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions Kevin Loughlin
2024-12-03 0:59 ` [RFC PATCH 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
0 siblings, 2 replies; 9+ messages in thread
From: Kevin Loughlin @ 2024-12-03 0:59 UTC (permalink / raw)
To: linux-kernel
Cc: seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm,
thomas.lendacky, pgonda, sidtelang, mizhang, virtualization,
xen-devel, bcm-kernel-feedback-list, Kevin Loughlin
AMD CPUs currently execute WBINVD in the host when unregistering SEV
guest memory or when deactivating SEV guests. Such cache maintenance is
performed to prevent data corruption, wherein the encrypted (C=1)
version of a dirty cache line might otherwise only be written back
after the memory is written in a different context (ex: C=0), yielding
corruption. However, WBINVD is performance-costly, especially because
it invalidates processor caches.
Strictly-speaking, unless the SEV ASID is being recycled (meaning all
existing cache lines with the recycled ASID must be flushed), the
cache invalidation triggered by WBINVD is unnecessary; only the
writeback is needed to prevent data corruption in remaining scenarios.
To improve performance in these scenarios, use WBNOINVD when available
instead of WBINVD. WBNOINVD still writes back all dirty lines
(preventing host data corruption by SEV guests) but does *not*
invalidate processor caches.
First, provide helper functions to use WBINVD similar to how WBINVD is
invoked. Second, check for WBNOINVD support and execute WBNOINVD if
possible in lieu of WBINVD to avoid cache invalidations
Kevin Loughlin (2):
x86, lib, xenpv: Add WBNOINVD helper functions
KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency
arch/x86/include/asm/paravirt.h | 7 ++++++
arch/x86/include/asm/paravirt_types.h | 1 +
arch/x86/include/asm/smp.h | 7 ++++++
arch/x86/include/asm/special_insns.h | 12 ++++++++-
arch/x86/kernel/paravirt.c | 6 +++++
arch/x86/kvm/svm/sev.c | 35 +++++++++++++++++----------
arch/x86/lib/cache-smp.c | 12 +++++++++
arch/x86/xen/enlighten_pv.c | 1 +
8 files changed, 67 insertions(+), 14 deletions(-)
--
2.47.0.338.g60cca15819-goog
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 0:59 [RFC PATCH 0/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
@ 2024-12-03 0:59 ` Kevin Loughlin
2024-12-03 1:28 ` Andrew Cooper
2024-12-03 0:59 ` [RFC PATCH 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
1 sibling, 1 reply; 9+ messages in thread
From: Kevin Loughlin @ 2024-12-03 0:59 UTC (permalink / raw)
To: linux-kernel
Cc: seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm,
thomas.lendacky, pgonda, sidtelang, mizhang, virtualization,
xen-devel, bcm-kernel-feedback-list, Kevin Loughlin
In line with WBINVD usage, add WBONINVD helper functions, accounting
for kernels built with and without CONFIG_PARAVIRT_XXL.
Signed-off-by: Kevin Loughlin <kevinloughlin@google.com>
---
arch/x86/include/asm/paravirt.h | 7 +++++++
arch/x86/include/asm/paravirt_types.h | 1 +
arch/x86/include/asm/smp.h | 7 +++++++
arch/x86/include/asm/special_insns.h | 12 +++++++++++-
arch/x86/kernel/paravirt.c | 6 ++++++
arch/x86/lib/cache-smp.c | 12 ++++++++++++
arch/x86/xen/enlighten_pv.c | 1 +
7 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index d4eb9e1d61b8..c040af2d8eff 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -187,6 +187,13 @@ static __always_inline void wbinvd(void)
PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT_XEN);
}
+extern noinstr void pv_native_wbnoinvd(void);
+
+static __always_inline void wbnoinvd(void)
+{
+ PVOP_ALT_VCALL0(cpu.wbnoinvd, "wbnoinvd", ALT_NOT_XEN);
+}
+
static inline u64 paravirt_read_msr(unsigned msr)
{
return PVOP_CALL1(u64, cpu.read_msr, msr);
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 8d4fbe1be489..9a3f38ad1958 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -87,6 +87,7 @@ struct pv_cpu_ops {
#endif
void (*wbinvd)(void);
+ void (*wbnoinvd)(void);
/* cpuid emulation, mostly so that caps bits can be disabled */
void (*cpuid)(unsigned int *eax, unsigned int *ebx,
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index ca073f40698f..ecf93a243b83 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -112,6 +112,7 @@ void native_play_dead(void);
void play_dead_common(void);
void wbinvd_on_cpu(int cpu);
int wbinvd_on_all_cpus(void);
+int wbnoinvd_on_all_cpus(void);
void smp_kick_mwait_play_dead(void);
@@ -160,6 +161,12 @@ static inline int wbinvd_on_all_cpus(void)
return 0;
}
+static inline int wbnoinvd_on_all_cpus(void)
+{
+ wbnoinvd();
+ return 0;
+}
+
static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
return (struct cpumask *)cpumask_of(0);
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index aec6e2d3aa1d..c2d16ddcd79b 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -117,7 +117,12 @@ static inline void wrpkru(u32 pkru)
static __always_inline void native_wbinvd(void)
{
- asm volatile("wbinvd": : :"memory");
+ asm volatile("wbinvd" : : : "memory");
+}
+
+static __always_inline void native_wbnoinvd(void)
+{
+ asm volatile("wbnoinvd" : : : "memory");
}
static inline unsigned long __read_cr4(void)
@@ -173,6 +178,11 @@ static __always_inline void wbinvd(void)
native_wbinvd();
}
+static __always_inline void wbnoinvd(void)
+{
+ native_wbnoinvd();
+}
+
#endif /* CONFIG_PARAVIRT_XXL */
static __always_inline void clflush(volatile void *__p)
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index fec381533555..a66b708d8a1e 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -121,6 +121,11 @@ noinstr void pv_native_wbinvd(void)
native_wbinvd();
}
+noinstr void pv_native_wbnoinvd(void)
+{
+ native_wbnoinvd();
+}
+
static noinstr void pv_native_safe_halt(void)
{
native_safe_halt();
@@ -149,6 +154,7 @@ struct paravirt_patch_template pv_ops = {
.cpu.write_cr0 = native_write_cr0,
.cpu.write_cr4 = native_write_cr4,
.cpu.wbinvd = pv_native_wbinvd,
+ .cpu.wbnoinvd = pv_native_wbnoinvd,
.cpu.read_msr = native_read_msr,
.cpu.write_msr = native_write_msr,
.cpu.read_msr_safe = native_read_msr_safe,
diff --git a/arch/x86/lib/cache-smp.c b/arch/x86/lib/cache-smp.c
index 7af743bd3b13..7ac5cca53031 100644
--- a/arch/x86/lib/cache-smp.c
+++ b/arch/x86/lib/cache-smp.c
@@ -20,3 +20,15 @@ int wbinvd_on_all_cpus(void)
return 0;
}
EXPORT_SYMBOL(wbinvd_on_all_cpus);
+
+static void __wbnoinvd(void *dummy)
+{
+ wbnoinvd();
+}
+
+int wbnoinvd_on_all_cpus(void)
+{
+ on_each_cpu(__wbnoinvd, NULL, 1);
+ return 0;
+}
+EXPORT_SYMBOL(wbnoinvd_on_all_cpus);
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index d6818c6cafda..a5c76a6f8976 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1162,6 +1162,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
.write_cr4 = xen_write_cr4,
.wbinvd = pv_native_wbinvd,
+ .wbnoinvd = pv_native_wbnoinvd,
.read_msr = xen_read_msr,
.write_msr = xen_write_msr,
--
2.47.0.338.g60cca15819-goog
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC PATCH 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency
2024-12-03 0:59 [RFC PATCH 0/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2024-12-03 0:59 ` [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions Kevin Loughlin
@ 2024-12-03 0:59 ` Kevin Loughlin
1 sibling, 0 replies; 9+ messages in thread
From: Kevin Loughlin @ 2024-12-03 0:59 UTC (permalink / raw)
To: linux-kernel
Cc: seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm,
thomas.lendacky, pgonda, sidtelang, mizhang, virtualization,
xen-devel, bcm-kernel-feedback-list, Kevin Loughlin
AMD CPUs currently execute WBINVD in the host when unregistering SEV
guest memory or when deactivating SEV guests. Such cache maintenance is
performed to prevent data corruption, wherein the encrypted (C=1)
version of a dirty cache line might otherwise only be written back
after the memory is written in a different context (ex: C=0), yielding
corruption. However, WBINVD is performance-costly, especially because
it invalidates processor caches.
Strictly-speaking, unless the SEV ASID is being recycled (meaning all
existing cache lines with the recycled ASID must be flushed), the
cache invalidation triggered by WBINVD is unnecessary; only the
writeback is needed to prevent data corruption in remaining scenarios.
To improve performance in these scenarios, use WBNOINVD when available
instead of WBINVD. WBNOINVD still writes back all dirty lines
(preventing host data corruption by SEV guests) but does *not*
invalidate processor caches.
Signed-off-by: Kevin Loughlin <kevinloughlin@google.com>
---
arch/x86/kvm/svm/sev.c | 35 ++++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 943bd074a5d3..dbe40f728c4b 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -116,6 +116,7 @@ static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid)
*/
down_write(&sev_deactivate_lock);
+ /* SNP firmware expects WBINVD before SNP_DF_FLUSH, so do *not* use WBNOINVD */
wbinvd_on_all_cpus();
if (sev_snp_enabled)
@@ -710,6 +711,14 @@ static void sev_clflush_pages(struct page *pages[], unsigned long npages)
}
}
+static void sev_wb_on_all_cpus(void)
+{
+ if (boot_cpu_has(X86_FEATURE_WBNOINVD))
+ wbnoinvd_on_all_cpus();
+ else
+ wbinvd_on_all_cpus();
+}
+
static unsigned long get_num_contig_pages(unsigned long idx,
struct page **inpages, unsigned long npages)
{
@@ -2774,11 +2783,11 @@ int sev_mem_enc_unregister_region(struct kvm *kvm,
}
/*
- * Ensure that all guest tagged cache entries are flushed before
- * releasing the pages back to the system for use. CLFLUSH will
- * not do this, so issue a WBINVD.
+ * Ensure that all dirty guest tagged cache entries are written back
+ * before releasing the pages back to the system for use. CLFLUSH will
+ * not do this without SME_COHERENT, so issue a WB[NO]INVD.
*/
- wbinvd_on_all_cpus();
+ sev_wb_on_all_cpus();
__unregister_enc_region_locked(kvm, region);
@@ -2900,11 +2909,11 @@ void sev_vm_destroy(struct kvm *kvm)
}
/*
- * Ensure that all guest tagged cache entries are flushed before
- * releasing the pages back to the system for use. CLFLUSH will
- * not do this, so issue a WBINVD.
+ * Ensure that all dirty guest tagged cache entries are written back
+ * before releasing the pages back to the system for use. CLFLUSH will
+ * not do this without SME_COHERENT, so issue a WB[NO]INVD.
*/
- wbinvd_on_all_cpus();
+ sev_wb_on_all_cpus();
/*
* if userspace was terminated before unregistering the memory regions
@@ -3130,12 +3139,12 @@ static void sev_flush_encrypted_page(struct kvm_vcpu *vcpu, void *va)
* by leaving stale encrypted data in the cache.
*/
if (WARN_ON_ONCE(wrmsrl_safe(MSR_AMD64_VM_PAGE_FLUSH, addr | asid)))
- goto do_wbinvd;
+ goto do_wb_on_all_cpus;
return;
-do_wbinvd:
- wbinvd_on_all_cpus();
+do_wb_on_all_cpus:
+ sev_wb_on_all_cpus();
}
void sev_guest_memory_reclaimed(struct kvm *kvm)
@@ -3149,7 +3158,7 @@ void sev_guest_memory_reclaimed(struct kvm *kvm)
if (!sev_guest(kvm) || sev_snp_guest(kvm))
return;
- wbinvd_on_all_cpus();
+ sev_wb_on_all_cpus();
}
void sev_free_vcpu(struct kvm_vcpu *vcpu)
@@ -3858,7 +3867,7 @@ static int __sev_snp_update_protected_guest_state(struct kvm_vcpu *vcpu)
* guest-mapped page rather than the initial one allocated
* by KVM in svm->sev_es.vmsa. In theory, svm->sev_es.vmsa
* could be free'd and cleaned up here, but that involves
- * cleanups like wbinvd_on_all_cpus() which would ideally
+ * cleanups like sev_wb_on_all_cpus() which would ideally
* be handled during teardown rather than guest boot.
* Deferring that also allows the existing logic for SEV-ES
* VMSAs to be re-used with minimal SNP-specific changes.
--
2.47.0.338.g60cca15819-goog
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 0:59 ` [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions Kevin Loughlin
@ 2024-12-03 1:28 ` Andrew Cooper
2024-12-03 1:44 ` Kevin Loughlin
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Cooper @ 2024-12-03 1:28 UTC (permalink / raw)
To: Kevin Loughlin, linux-kernel
Cc: seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa, kvm,
thomas.lendacky, pgonda, sidtelang, mizhang, virtualization,
xen-devel, bcm-kernel-feedback-list
On 03/12/2024 12:59 am, Kevin Loughlin wrote:
> diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
> index d4eb9e1d61b8..c040af2d8eff 100644
> --- a/arch/x86/include/asm/paravirt.h
> +++ b/arch/x86/include/asm/paravirt.h
> @@ -187,6 +187,13 @@ static __always_inline void wbinvd(void)
> PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT_XEN);
> }
>
> +extern noinstr void pv_native_wbnoinvd(void);
> +
> +static __always_inline void wbnoinvd(void)
> +{
> + PVOP_ALT_VCALL0(cpu.wbnoinvd, "wbnoinvd", ALT_NOT_XEN);
> +}
Given this, ...
> diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
> index fec381533555..a66b708d8a1e 100644
> --- a/arch/x86/kernel/paravirt.c
> +++ b/arch/x86/kernel/paravirt.c
> @@ -149,6 +154,7 @@ struct paravirt_patch_template pv_ops = {
> .cpu.write_cr0 = native_write_cr0,
> .cpu.write_cr4 = native_write_cr4,
> .cpu.wbinvd = pv_native_wbinvd,
> + .cpu.wbnoinvd = pv_native_wbnoinvd,
> .cpu.read_msr = native_read_msr,
> .cpu.write_msr = native_write_msr,
> .cpu.read_msr_safe = native_read_msr_safe,
this, and ...
> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
> index d6818c6cafda..a5c76a6f8976 100644
> --- a/arch/x86/xen/enlighten_pv.c
> +++ b/arch/x86/xen/enlighten_pv.c
> @@ -1162,6 +1162,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
> .write_cr4 = xen_write_cr4,
>
> .wbinvd = pv_native_wbinvd,
> + .wbnoinvd = pv_native_wbnoinvd,
>
> .read_msr = xen_read_msr,
> .write_msr = xen_write_msr,
this, what is the point having a paravirt hook which is wired to
native_wbnoinvd() in all cases?
That just seems like overhead for overhead sake.
~Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 1:28 ` Andrew Cooper
@ 2024-12-03 1:44 ` Kevin Loughlin
2024-12-03 4:09 ` Xin Li
0 siblings, 1 reply; 9+ messages in thread
From: Kevin Loughlin @ 2024-12-03 1:44 UTC (permalink / raw)
To: Andrew Cooper
Cc: linux-kernel, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86,
hpa, kvm, thomas.lendacky, pgonda, sidtelang, mizhang,
virtualization, xen-devel, bcm-kernel-feedback-list
On Mon, Dec 2, 2024 at 5:28 PM Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>
> On 03/12/2024 12:59 am, Kevin Loughlin wrote:
> > diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
> > index d4eb9e1d61b8..c040af2d8eff 100644
> > --- a/arch/x86/include/asm/paravirt.h
> > +++ b/arch/x86/include/asm/paravirt.h
> > @@ -187,6 +187,13 @@ static __always_inline void wbinvd(void)
> > PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT_XEN);
> > }
> >
> > +extern noinstr void pv_native_wbnoinvd(void);
> > +
> > +static __always_inline void wbnoinvd(void)
> > +{
> > + PVOP_ALT_VCALL0(cpu.wbnoinvd, "wbnoinvd", ALT_NOT_XEN);
> > +}
>
> Given this, ...
>
> > diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
> > index fec381533555..a66b708d8a1e 100644
> > --- a/arch/x86/kernel/paravirt.c
> > +++ b/arch/x86/kernel/paravirt.c
> > @@ -149,6 +154,7 @@ struct paravirt_patch_template pv_ops = {
> > .cpu.write_cr0 = native_write_cr0,
> > .cpu.write_cr4 = native_write_cr4,
> > .cpu.wbinvd = pv_native_wbinvd,
> > + .cpu.wbnoinvd = pv_native_wbnoinvd,
> > .cpu.read_msr = native_read_msr,
> > .cpu.write_msr = native_write_msr,
> > .cpu.read_msr_safe = native_read_msr_safe,
>
> this, and ...
>
> > diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
> > index d6818c6cafda..a5c76a6f8976 100644
> > --- a/arch/x86/xen/enlighten_pv.c
> > +++ b/arch/x86/xen/enlighten_pv.c
> > @@ -1162,6 +1162,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
> > .write_cr4 = xen_write_cr4,
> >
> > .wbinvd = pv_native_wbinvd,
> > + .wbnoinvd = pv_native_wbnoinvd,
> >
> > .read_msr = xen_read_msr,
> > .write_msr = xen_write_msr,
>
> this, what is the point having a paravirt hook which is wired to
> native_wbnoinvd() in all cases?
>
> That just seems like overhead for overhead sake.
I'm mirroring what's done for WBINVD here, which was changed to a
paravirt hook in 10a099405fdf ("cpuidle, xenpv: Make more PARAVIRT_XXL
noinstr clean") in order to avoid calls out to instrumented code as
described in the commit message in more detail. I believe a hook is
similarly required for WBNOINVD, but please let me know if you
disagree. Thanks!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 1:44 ` Kevin Loughlin
@ 2024-12-03 4:09 ` Xin Li
2024-12-03 6:47 ` Juergen Gross
0 siblings, 1 reply; 9+ messages in thread
From: Xin Li @ 2024-12-03 4:09 UTC (permalink / raw)
To: Kevin Loughlin, Andrew Cooper
Cc: linux-kernel, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86,
hpa, kvm, thomas.lendacky, pgonda, sidtelang, mizhang,
virtualization, xen-devel, bcm-kernel-feedback-list
On 12/2/2024 5:44 PM, Kevin Loughlin wrote:
> On Mon, Dec 2, 2024 at 5:28 PM Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>>
>> On 03/12/2024 12:59 am, Kevin Loughlin wrote:
>>> diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
>>> index d4eb9e1d61b8..c040af2d8eff 100644
>>> --- a/arch/x86/include/asm/paravirt.h
>>> +++ b/arch/x86/include/asm/paravirt.h
>>> @@ -187,6 +187,13 @@ static __always_inline void wbinvd(void)
>>> PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT_XEN);
>>> }
>>>
>>> +extern noinstr void pv_native_wbnoinvd(void);
>>> +
>>> +static __always_inline void wbnoinvd(void)
>>> +{
>>> + PVOP_ALT_VCALL0(cpu.wbnoinvd, "wbnoinvd", ALT_NOT_XEN);
>>> +}
>>
>> Given this, ...
>>
>>> diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
>>> index fec381533555..a66b708d8a1e 100644
>>> --- a/arch/x86/kernel/paravirt.c
>>> +++ b/arch/x86/kernel/paravirt.c
>>> @@ -149,6 +154,7 @@ struct paravirt_patch_template pv_ops = {
>>> .cpu.write_cr0 = native_write_cr0,
>>> .cpu.write_cr4 = native_write_cr4,
>>> .cpu.wbinvd = pv_native_wbinvd,
>>> + .cpu.wbnoinvd = pv_native_wbnoinvd,
>>> .cpu.read_msr = native_read_msr,
>>> .cpu.write_msr = native_write_msr,
>>> .cpu.read_msr_safe = native_read_msr_safe,
>>
>> this, and ...
>>
>>> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
>>> index d6818c6cafda..a5c76a6f8976 100644
>>> --- a/arch/x86/xen/enlighten_pv.c
>>> +++ b/arch/x86/xen/enlighten_pv.c
>>> @@ -1162,6 +1162,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
>>> .write_cr4 = xen_write_cr4,
>>>
>>> .wbinvd = pv_native_wbinvd,
>>> + .wbnoinvd = pv_native_wbnoinvd,
>>>
>>> .read_msr = xen_read_msr,
>>> .write_msr = xen_write_msr,
>>
>> this, what is the point having a paravirt hook which is wired to
>> native_wbnoinvd() in all cases?
>>
>> That just seems like overhead for overhead sake.
>
> I'm mirroring what's done for WBINVD here, which was changed to a
> paravirt hook in 10a099405fdf ("cpuidle, xenpv: Make more PARAVIRT_XXL
> noinstr clean") in order to avoid calls out to instrumented code as
> described in the commit message in more detail. I believe a hook is
> similarly required for WBNOINVD, but please let me know if you
> disagree. Thanks!
Then the question is why we need to add WBINVD/WBNOINVD to the paravirt
hooks.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 4:09 ` Xin Li
@ 2024-12-03 6:47 ` Juergen Gross
2024-12-03 8:10 ` Xin Li
0 siblings, 1 reply; 9+ messages in thread
From: Juergen Gross @ 2024-12-03 6:47 UTC (permalink / raw)
To: Xin Li, Kevin Loughlin, Andrew Cooper
Cc: linux-kernel, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86,
hpa, kvm, thomas.lendacky, pgonda, sidtelang, mizhang,
virtualization, xen-devel, bcm-kernel-feedback-list
On 03.12.24 05:09, Xin Li wrote:
> On 12/2/2024 5:44 PM, Kevin Loughlin wrote:
>> On Mon, Dec 2, 2024 at 5:28 PM Andrew Cooper <andrew.cooper3@citrix.com> wrote:
>>>
>>> On 03/12/2024 12:59 am, Kevin Loughlin wrote:
>>>> diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
>>>> index d4eb9e1d61b8..c040af2d8eff 100644
>>>> --- a/arch/x86/include/asm/paravirt.h
>>>> +++ b/arch/x86/include/asm/paravirt.h
>>>> @@ -187,6 +187,13 @@ static __always_inline void wbinvd(void)
>>>> PVOP_ALT_VCALL0(cpu.wbinvd, "wbinvd", ALT_NOT_XEN);
>>>> }
>>>>
>>>> +extern noinstr void pv_native_wbnoinvd(void);
>>>> +
>>>> +static __always_inline void wbnoinvd(void)
>>>> +{
>>>> + PVOP_ALT_VCALL0(cpu.wbnoinvd, "wbnoinvd", ALT_NOT_XEN);
>>>> +}
>>>
>>> Given this, ...
>>>
>>>> diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
>>>> index fec381533555..a66b708d8a1e 100644
>>>> --- a/arch/x86/kernel/paravirt.c
>>>> +++ b/arch/x86/kernel/paravirt.c
>>>> @@ -149,6 +154,7 @@ struct paravirt_patch_template pv_ops = {
>>>> .cpu.write_cr0 = native_write_cr0,
>>>> .cpu.write_cr4 = native_write_cr4,
>>>> .cpu.wbinvd = pv_native_wbinvd,
>>>> + .cpu.wbnoinvd = pv_native_wbnoinvd,
>>>> .cpu.read_msr = native_read_msr,
>>>> .cpu.write_msr = native_write_msr,
>>>> .cpu.read_msr_safe = native_read_msr_safe,
>>>
>>> this, and ...
>>>
>>>> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
>>>> index d6818c6cafda..a5c76a6f8976 100644
>>>> --- a/arch/x86/xen/enlighten_pv.c
>>>> +++ b/arch/x86/xen/enlighten_pv.c
>>>> @@ -1162,6 +1162,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
>>>> .write_cr4 = xen_write_cr4,
>>>>
>>>> .wbinvd = pv_native_wbinvd,
>>>> + .wbnoinvd = pv_native_wbnoinvd,
>>>>
>>>> .read_msr = xen_read_msr,
>>>> .write_msr = xen_write_msr,
>>>
>>> this, what is the point having a paravirt hook which is wired to
>>> native_wbnoinvd() in all cases?
>>>
>>> That just seems like overhead for overhead sake.
>>
>> I'm mirroring what's done for WBINVD here, which was changed to a
>> paravirt hook in 10a099405fdf ("cpuidle, xenpv: Make more PARAVIRT_XXL
>> noinstr clean") in order to avoid calls out to instrumented code as
>> described in the commit message in more detail. I believe a hook is
>> similarly required for WBNOINVD, but please let me know if you
>> disagree. Thanks!
>
> Then the question is why we need to add WBINVD/WBNOINVD to the paravirt
> hooks.
>
We don't.
The wbinvd hook is a leftover from lguest times.
I'll send a patch to remove it.
Juergen
P.S.: As the paravirt maintainer I would have preferred to be Cc-ed in the
initial patch mail.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 6:47 ` Juergen Gross
@ 2024-12-03 8:10 ` Xin Li
2024-12-03 23:42 ` Kevin Loughlin
0 siblings, 1 reply; 9+ messages in thread
From: Xin Li @ 2024-12-03 8:10 UTC (permalink / raw)
To: Juergen Gross, Kevin Loughlin, Andrew Cooper
Cc: linux-kernel, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86,
hpa, kvm, thomas.lendacky, pgonda, sidtelang, mizhang,
virtualization, xen-devel, bcm-kernel-feedback-list
On 12/2/2024 10:47 PM, Juergen Gross wrote:
> P.S.: As the paravirt maintainer I would have preferred to be Cc-ed in the
> initial patch mail.
Looks that Kevin didn't run './scripts/get_maintainer.pl'?
Thanks!
Xin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions
2024-12-03 8:10 ` Xin Li
@ 2024-12-03 23:42 ` Kevin Loughlin
0 siblings, 0 replies; 9+ messages in thread
From: Kevin Loughlin @ 2024-12-03 23:42 UTC (permalink / raw)
To: Xin Li
Cc: Juergen Gross, Andrew Cooper, linux-kernel, seanjc, pbonzini,
tglx, mingo, bp, dave.hansen, x86, hpa, kvm, thomas.lendacky,
pgonda, sidtelang, mizhang, virtualization, xen-devel,
bcm-kernel-feedback-list
On Tue, Dec 3, 2024 at 12:11 AM Xin Li <xin@zytor.com> wrote:
>
> On 12/2/2024 10:47 PM, Juergen Gross wrote:
> > P.S.: As the paravirt maintainer I would have preferred to be Cc-ed in the
> > initial patch mail.
>
> Looks that Kevin didn't run './scripts/get_maintainer.pl'?
Woops, my bad. I somehow ended up with the full maintainer list for
patch 2/2 from the script but not this one (1/2). Apologies and thanks
for the heads up.
I saw Juergen's patch [0] ("x86/paravirt: remove the wbinvd hook") to
remove the WBINVD hook, so I'll do the same for WBNOINVD in the next
version (meaning I shouldn't need to update xenpv code anymore).
[0] https://lore.kernel.org/lkml/20241203071550.26487-1-jgross@suse.com/
Thanks!
Kevin
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-12-03 23:43 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-03 0:59 [RFC PATCH 0/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
2024-12-03 0:59 ` [RFC PATCH 1/2] x86, lib, xenpv: Add WBNOINVD helper functions Kevin Loughlin
2024-12-03 1:28 ` Andrew Cooper
2024-12-03 1:44 ` Kevin Loughlin
2024-12-03 4:09 ` Xin Li
2024-12-03 6:47 ` Juergen Gross
2024-12-03 8:10 ` Xin Li
2024-12-03 23:42 ` Kevin Loughlin
2024-12-03 0:59 ` [RFC PATCH 2/2] KVM: SEV: Prefer WBNOINVD over WBINVD for cache maintenance efficiency Kevin Loughlin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox