2023-06-15 07:08:54

by Alexey Kardashevskiy

[permalink] [raw]
Subject: [PATCH kernel 0/9] KVM: SEV: Enable AMD SEV-ES DebugSwap

This is to use another AMD SEV-ES hardware assisted register swap,
more detail in 6/9. In the process it's been suggested to fix other
things, here is the attempt, with the great help of amders.

The previous conversation is here:
https://lore.kernel.org/r/[email protected]

This is based on sha1
6e2e1e779912 Ingo Molnar "Merge branch into tip/master: 'x86/sgx'".

The tree is here: https://github.com/aik/linux/tree/debugswap

Please comment. Thanks.


Alexey Kardashevskiy (6):
KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header
KVM: SEV: Move SEV's GP_VECTOR intercept setup to SEV
KVM: SEV-ES: explicitly disable debug
KVM: SVM/SEV/SEV-ES: Rework intercepts
KVM: SEV: Enable data breakpoints in SEV-ES
KVM: SEV-ES: Eliminate #DB intercept when DebugSwap enabled

Sean Christopherson (3):
KVM: SVM: Rewrite sev_es_prepare_switch_to_guest()'s comment about
swap types
KVM: SVM: Don't defer NMI unblocking until next exit for SEV-ES guests
KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI
window

arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/svm.h | 1 +
arch/x86/kvm/svm/svm.h | 42 ----------
tools/arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/kvm/svm/sev.c | 86 +++++++++++++++++---
arch/x86/kvm/svm/svm.c | 70 ++++++++++++++--
6 files changed, 137 insertions(+), 64 deletions(-)

--
2.40.1



2023-06-15 07:10:02

by Alexey Kardashevskiy

[permalink] [raw]
Subject: [PATCH kernel 1/9] KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header

Static functions set_dr_intercepts() and clr_dr_intercepts() are only
called from SVM so move them to .c.

No functional change intended.

Signed-off-by: Alexey Kardashevskiy <[email protected]>
Reviewed-by: Carlos Bilbao <[email protected]>
Reviewed-by: Tom Lendacky <[email protected]>
Reviewed-by: Santosh Shukla <[email protected]>
---
Changes:
v5:
* new in the series
---
arch/x86/kvm/svm/svm.h | 42 --------------------
arch/x86/kvm/svm/svm.c | 42 ++++++++++++++++++++
2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index f44751dd8d5d..a99f97a86c59 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -405,48 +405,6 @@ static inline bool vmcb12_is_intercept(struct vmcb_ctrl_area_cached *control, u3
return test_bit(bit, (unsigned long *)&control->intercepts);
}

-static inline void set_dr_intercepts(struct vcpu_svm *svm)
-{
- struct vmcb *vmcb = svm->vmcb01.ptr;
-
- if (!sev_es_guest(svm->vcpu.kvm)) {
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_WRITE);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_WRITE);
- }
-
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
-
- recalc_intercepts(svm);
-}
-
-static inline void clr_dr_intercepts(struct vcpu_svm *svm)
-{
- struct vmcb *vmcb = svm->vmcb01.ptr;
-
- vmcb->control.intercepts[INTERCEPT_DR] = 0;
-
- /* DR7 access must remain intercepted for an SEV-ES guest */
- if (sev_es_guest(svm->vcpu.kvm)) {
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
- vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
- }
-
- recalc_intercepts(svm);
-}
-
static inline void set_exception_intercept(struct vcpu_svm *svm, u32 bit)
{
struct vmcb *vmcb = svm->vmcb01.ptr;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 54089f990c8f..980faf460bfe 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -690,6 +690,48 @@ static int svm_cpu_init(int cpu)

}

+static void set_dr_intercepts(struct vcpu_svm *svm)
+{
+ struct vmcb *vmcb = svm->vmcb01.ptr;
+
+ if (!sev_es_guest(svm->vcpu.kvm)) {
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR0_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR1_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR2_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR3_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR4_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR5_WRITE);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR6_WRITE);
+ }
+
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
+
+ recalc_intercepts(svm);
+}
+
+static void clr_dr_intercepts(struct vcpu_svm *svm)
+{
+ struct vmcb *vmcb = svm->vmcb01.ptr;
+
+ vmcb->control.intercepts[INTERCEPT_DR] = 0;
+
+ /* DR7 access must remain intercepted for an SEV-ES guest */
+ if (sev_es_guest(svm->vcpu.kvm)) {
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
+ vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
+ }
+
+ recalc_intercepts(svm);
+}
+
static int direct_access_msr_slot(u32 msr)
{
u32 i;
--
2.40.1


2023-06-15 07:13:27

by Alexey Kardashevskiy

[permalink] [raw]
Subject: [PATCH kernel 9/9] KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI window

From: Sean Christopherson <[email protected]>

Bail early from svm_enable_nmi_window() for SEV-ES guests without trying
to enable single-step of the guest, as single-stepping an SEV-ES guest is
impossible and the guest is responsible for *telling* KVM when it is ready
for an new NMI to be injected.

Functionally, setting TF and RF in svm->vmcb->save.rflags is benign as the
field is ignored by hardware, but it's all kinds of confusing.

Signed-off-by: Sean Christopherson <[email protected]>
[aik: removed the clause about "KVM suppresses EFER.SVME (see efer_trap())"]
Signed-off-by: Alexey Kardashevskiy <[email protected]>
---
Changes:
v6:
* new to the series
---
arch/x86/kvm/svm/svm.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 52f1d88e82a0..c9837a8667b7 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3824,6 +3824,19 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu)
if (svm_get_nmi_mask(vcpu) && !svm->awaiting_iret_completion)
return; /* IRET will cause a vm exit */

+ /*
+ * SEV-ES guests are responsible for signaling when a vCPU is ready to
+ * receive a new NMI, as SEV-ES guests can't be single-stepped, i.e.
+ * KVM can't intercept and single-step IRET to detect when NMIs are
+ * unblocked (architecturally speaking). See SVM_VMGEXIT_NMI_COMPLETE.
+ *
+ * Note, GIF is guaranteed to be '1' for SEV-ES guests as hardware
+ * ignores SEV-ES guest writes to EFER.SVME *and* CLGI/STGI are not
+ * supported NAEs in the GHCB protocol.
+ */
+ if (sev_es_guest(vcpu->kvm))
+ return;
+
if (!gif_set(svm)) {
if (vgif)
svm_set_intercept(svm, INTERCEPT_STGI);
--
2.40.1


2023-06-15 07:50:17

by Alexey Kardashevskiy

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap

Ouch, forgot to mark this as "v6". Sorry...



On 15/6/23 16:37, Alexey Kardashevskiy wrote:
> This is to use another AMD SEV-ES hardware assisted register swap,
> more detail in 6/9. In the process it's been suggested to fix other
> things, here is the attempt, with the great help of amders.
>
> The previous conversation is here:
> https://lore.kernel.org/r/[email protected]
>
> This is based on sha1
> 6e2e1e779912 Ingo Molnar "Merge branch into tip/master: 'x86/sgx'".
>
> The tree is here: https://github.com/aik/linux/tree/debugswap
>
> Please comment. Thanks.
>
>
> Alexey Kardashevskiy (6):
> KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header
> KVM: SEV: Move SEV's GP_VECTOR intercept setup to SEV
> KVM: SEV-ES: explicitly disable debug
> KVM: SVM/SEV/SEV-ES: Rework intercepts
> KVM: SEV: Enable data breakpoints in SEV-ES
> KVM: SEV-ES: Eliminate #DB intercept when DebugSwap enabled
>
> Sean Christopherson (3):
> KVM: SVM: Rewrite sev_es_prepare_switch_to_guest()'s comment about
> swap types
> KVM: SVM: Don't defer NMI unblocking until next exit for SEV-ES guests
> KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI
> window
>
> arch/x86/include/asm/cpufeatures.h | 1 +
> arch/x86/include/asm/svm.h | 1 +
> arch/x86/kvm/svm/svm.h | 42 ----------
> tools/arch/x86/include/asm/cpufeatures.h | 1 +
> arch/x86/kvm/svm/sev.c | 86 +++++++++++++++++---
> arch/x86/kvm/svm/svm.c | 70 ++++++++++++++--
> 6 files changed, 137 insertions(+), 64 deletions(-)
>

--
Alexey


2023-06-23 02:05:02

by Alexey Kardashevskiy

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap

Sean, do you want me to repost with "v6" in all patches or this will do?
Thanks,


On 15/6/23 17:13, Alexey Kardashevskiy wrote:
> Ouch, forgot to mark this as "v6". Sorry...
>
>
>
> On 15/6/23 16:37, Alexey Kardashevskiy wrote:
>> This is to use another AMD SEV-ES hardware assisted register swap,
>> more detail in 6/9. In the process it's been suggested to fix other
>> things, here is the attempt, with the great help of amders.
>>
>> The previous conversation is here:
>> https://lore.kernel.org/r/[email protected]
>>
>> This is based on sha1
>> 6e2e1e779912 Ingo Molnar "Merge branch into tip/master: 'x86/sgx'".
>>
>> The tree is here: https://github.com/aik/linux/tree/debugswap
>>
>> Please comment. Thanks.
>>
>>
>> Alexey Kardashevskiy (6):
>>    KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header
>>    KVM: SEV: Move SEV's GP_VECTOR intercept setup to SEV
>>    KVM: SEV-ES: explicitly disable debug
>>    KVM: SVM/SEV/SEV-ES: Rework intercepts
>>    KVM: SEV: Enable data breakpoints in SEV-ES
>>    KVM: SEV-ES: Eliminate #DB intercept when DebugSwap enabled
>>
>> Sean Christopherson (3):
>>    KVM: SVM: Rewrite sev_es_prepare_switch_to_guest()'s comment about
>>      swap types
>>    KVM: SVM: Don't defer NMI unblocking until next exit for SEV-ES guests
>>    KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI
>>      window
>>
>>   arch/x86/include/asm/cpufeatures.h       |  1 +
>>   arch/x86/include/asm/svm.h               |  1 +
>>   arch/x86/kvm/svm/svm.h                   | 42 ----------
>>   tools/arch/x86/include/asm/cpufeatures.h |  1 +
>>   arch/x86/kvm/svm/sev.c                   | 86 +++++++++++++++++---
>>   arch/x86/kvm/svm/svm.c                   | 70 ++++++++++++++--
>>   6 files changed, 137 insertions(+), 64 deletions(-)
>>
>

--
Alexey

2023-06-23 14:42:07

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap

On Fri, Jun 23, 2023, Alexey Kardashevskiy wrote:
> Sean, do you want me to repost with "v6" in all patches or this will do?

No need on my end.

2023-06-30 02:14:56

by Alexey Kardashevskiy

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap



On 24/6/23 00:19, Sean Christopherson wrote:
> On Fri, Jun 23, 2023, Alexey Kardashevskiy wrote:
>> Sean, do you want me to repost with "v6" in all patches or this will do?
>
> No need on my end.

Cool. My colleagues are gently asking if this is any closer to getting
pulled or not just yet? :) Thanks,

--
Alexey

2023-06-30 22:14:22

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap

On Fri, Jun 30, 2023, Alexey Kardashevskiy wrote:
>
>
> On 24/6/23 00:19, Sean Christopherson wrote:
> > On Fri, Jun 23, 2023, Alexey Kardashevskiy wrote:
> > > Sean, do you want me to repost with "v6" in all patches or this will do?
> >
> > No need on my end.
>
> Cool. My colleagues are gently asking if this is any closer to getting
> pulled or not just yet? :) Thanks,

Just looked through it. A few nits, but nothing I can't fix when applying. I'm
planning on applying it for 6.6 (pending testing, etc.), though I'm out next week
so it'll be a week or three before that actually happens.

2023-07-20 19:52:34

by Alexey Kardashevskiy

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9 v6] KVM: SEV: Enable AMD SEV-ES DebugSwap



On 30/6/23 16:52, Sean Christopherson wrote:
> On Fri, Jun 30, 2023, Alexey Kardashevskiy wrote:
>>
>>
>> On 24/6/23 00:19, Sean Christopherson wrote:
>>> On Fri, Jun 23, 2023, Alexey Kardashevskiy wrote:
>>>> Sean, do you want me to repost with "v6" in all patches or this will do?
>>>
>>> No need on my end.
>>
>> Cool. My colleagues are gently asking if this is any closer to getting
>> pulled or not just yet? :) Thanks,
>
> Just looked through it. A few nits, but nothing I can't fix when applying. I'm
> planning on applying it for 6.6 (pending testing, etc.), though I'm out next week
> so it'll be a week or three before that actually happens.

Soo three it is :)


--
Alexey

2023-07-29 01:39:05

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9] KVM: SEV: Enable AMD SEV-ES DebugSwap

On Thu, 15 Jun 2023 16:37:48 +1000, Alexey Kardashevskiy wrote:
> This is to use another AMD SEV-ES hardware assisted register swap,
> more detail in 6/9. In the process it's been suggested to fix other
> things, here is the attempt, with the great help of amders.
>
> The previous conversation is here:
> https://lore.kernel.org/r/[email protected]
>
> [...]

Finally applied to kvm-x86 svm, thanks! Though I was *really* tempted to see
just how snarky the pings would get at week 5+ ;-)

[1/9] KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header
https://github.com/kvm-x86/linux/commit/b265ee7bae11
[2/9] KVM: SEV: Move SEV's GP_VECTOR intercept setup to SEV
https://github.com/kvm-x86/linux/commit/29de732cc95c
[3/9] KVM: SVM: Rewrite sev_es_prepare_switch_to_guest()'s comment about swap types
https://github.com/kvm-x86/linux/commit/f8d808ed1ba0
[4/9] KVM: SEV-ES: explicitly disable debug
https://github.com/kvm-x86/linux/commit/2837dd00f8fc
[5/9] KVM: SVM/SEV/SEV-ES: Rework intercepts
https://github.com/kvm-x86/linux/commit/5aefd3a05fe1
[6/9] KVM: SEV: Enable data breakpoints in SEV-ES
https://github.com/kvm-x86/linux/commit/fb71b1298709
[7/9] KVM: SEV-ES: Eliminate #DB intercept when DebugSwap enabled
https://github.com/kvm-x86/linux/commit/8b54cc7e1817
[8/9] KVM: SVM: Don't defer NMI unblocking until next exit for SEV-ES guests
https://github.com/kvm-x86/linux/commit/c54268e1036f
[9/9] KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI window
https://github.com/kvm-x86/linux/commit/e11f81043a12

--
https://github.com/kvm-x86/linux/tree/next
https://github.com/kvm-x86/linux/tree/fixes

2023-07-29 03:41:06

by Alexey Kardashevskiy

[permalink] [raw]
Subject: Re: [PATCH kernel 0/9] KVM: SEV: Enable AMD SEV-ES DebugSwap



On 29/7/23 09:49, Sean Christopherson wrote:
> On Thu, 15 Jun 2023 16:37:48 +1000, Alexey Kardashevskiy wrote:
>> This is to use another AMD SEV-ES hardware assisted register swap,
>> more detail in 6/9. In the process it's been suggested to fix other
>> things, here is the attempt, with the great help of amders.
>>
>> The previous conversation is here:
>> https://lore.kernel.org/r/[email protected]
>>
>> [...]
>
> Finally applied to kvm-x86 svm, thanks! Though I was *really* tempted to see
> just how snarky the pings would get at week 5+ ;-)

Thanks!
Here is a gist what it could look like:
https://www.spinics.net/lists/kvm-ppc/msg20903.html :)


>
> [1/9] KVM: SEV: move set_dr_intercepts/clr_dr_intercepts from the header
> https://github.com/kvm-x86/linux/commit/b265ee7bae11
> [2/9] KVM: SEV: Move SEV's GP_VECTOR intercept setup to SEV
> https://github.com/kvm-x86/linux/commit/29de732cc95c
> [3/9] KVM: SVM: Rewrite sev_es_prepare_switch_to_guest()'s comment about swap types
> https://github.com/kvm-x86/linux/commit/f8d808ed1ba0
> [4/9] KVM: SEV-ES: explicitly disable debug
> https://github.com/kvm-x86/linux/commit/2837dd00f8fc
> [5/9] KVM: SVM/SEV/SEV-ES: Rework intercepts
> https://github.com/kvm-x86/linux/commit/5aefd3a05fe1
> [6/9] KVM: SEV: Enable data breakpoints in SEV-ES
> https://github.com/kvm-x86/linux/commit/fb71b1298709
> [7/9] KVM: SEV-ES: Eliminate #DB intercept when DebugSwap enabled
> https://github.com/kvm-x86/linux/commit/8b54cc7e1817
> [8/9] KVM: SVM: Don't defer NMI unblocking until next exit for SEV-ES guests
> https://github.com/kvm-x86/linux/commit/c54268e1036f
> [9/9] KVM: SVM: Don't try to pointlessly single-step SEV-ES guests for NMI window
> https://github.com/kvm-x86/linux/commit/e11f81043a12
>
> --
> https://github.com/kvm-x86/linux/tree/next
> https://github.com/kvm-x86/linux/tree/fixes

--
Alexey