Message ID | 159597948692.12744.7037992839778140055.stgit@bmoger-ubuntu (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | SVM cleanup and INVPCID support for the AMD guests | expand |
On Tue, Jul 28, 2020 at 4:38 PM Babu Moger <babu.moger@amd.com> wrote: > > Modify intercept_dr to generic intercepts in vmcb_control_area. > Use generic __set_intercept, __clr_intercept and __is_intercept > to set/clear/test the intercept_dr bits. > > Signed-off-by: Babu Moger <babu.moger@amd.com> > --- > arch/x86/include/asm/svm.h | 36 ++++++++++++++++++------------------ > arch/x86/kvm/svm/nested.c | 6 +----- > arch/x86/kvm/svm/svm.c | 4 ++-- > arch/x86/kvm/svm/svm.h | 34 +++++++++++++++++----------------- > 4 files changed, 38 insertions(+), 42 deletions(-) > > diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h > index d4739f4eae63..ffc89d8e4fcb 100644 > --- a/arch/x86/include/asm/svm.h > +++ b/arch/x86/include/asm/svm.h > @@ -11,6 +11,7 @@ > > enum vector_offset { > CR_VECTOR = 0, > + DR_VECTOR, > MAX_VECTORS, > }; > > @@ -34,6 +35,23 @@ enum { > INTERCEPT_CR6_WRITE, > INTERCEPT_CR7_WRITE, > INTERCEPT_CR8_WRITE, > + /* Byte offset 004h (Vector 1) */ > + INTERCEPT_DR0_READ = 32, > + INTERCEPT_DR1_READ, > + INTERCEPT_DR2_READ, > + INTERCEPT_DR3_READ, > + INTERCEPT_DR4_READ, > + INTERCEPT_DR5_READ, > + INTERCEPT_DR6_READ, > + INTERCEPT_DR7_READ, > + INTERCEPT_DR0_WRITE = 48, > + INTERCEPT_DR1_WRITE, > + INTERCEPT_DR2_WRITE, > + INTERCEPT_DR3_WRITE, > + INTERCEPT_DR4_WRITE, > + INTERCEPT_DR5_WRITE, > + INTERCEPT_DR6_WRITE, > + INTERCEPT_DR7_WRITE, > }; > > enum { > @@ -89,7 +107,6 @@ enum { > > struct __attribute__ ((__packed__)) vmcb_control_area { > u32 intercepts[MAX_VECTORS]; > - u32 intercept_dr; > u32 intercept_exceptions; > u64 intercept; > u8 reserved_1[40]; > @@ -271,23 +288,6 @@ struct __attribute__ ((__packed__)) vmcb { > #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK > #define SVM_SELECTOR_CODE_MASK (1 << 3) > > -#define INTERCEPT_DR0_READ 0 > -#define INTERCEPT_DR1_READ 1 > -#define INTERCEPT_DR2_READ 2 > -#define INTERCEPT_DR3_READ 3 > -#define INTERCEPT_DR4_READ 4 > -#define INTERCEPT_DR5_READ 5 > -#define INTERCEPT_DR6_READ 6 > -#define INTERCEPT_DR7_READ 7 > -#define INTERCEPT_DR0_WRITE (16 + 0) > -#define INTERCEPT_DR1_WRITE (16 + 1) > -#define INTERCEPT_DR2_WRITE (16 + 2) > -#define INTERCEPT_DR3_WRITE (16 + 3) > -#define INTERCEPT_DR4_WRITE (16 + 4) > -#define INTERCEPT_DR5_WRITE (16 + 5) > -#define INTERCEPT_DR6_WRITE (16 + 6) > -#define INTERCEPT_DR7_WRITE (16 + 7) > - > #define SVM_EVTINJ_VEC_MASK 0xff > > #define SVM_EVTINJ_TYPE_SHIFT 8 > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c > index 46f5c82d9b45..71ca89afb2a3 100644 > --- a/arch/x86/kvm/svm/nested.c > +++ b/arch/x86/kvm/svm/nested.c > @@ -121,7 +121,6 @@ void recalc_intercepts(struct vcpu_svm *svm) > for (i = 0; i < MAX_VECTORS; i++) > c->intercepts[i] = h->intercepts[i]; > > - c->intercept_dr = h->intercept_dr; > c->intercept_exceptions = h->intercept_exceptions; > c->intercept = h->intercept; > > @@ -144,7 +143,6 @@ void recalc_intercepts(struct vcpu_svm *svm) > for (i = 0; i < MAX_VECTORS; i++) > c->intercepts[i] |= g->intercepts[i]; > > - c->intercept_dr |= g->intercept_dr; > c->intercept_exceptions |= g->intercept_exceptions; > c->intercept |= g->intercept; > } > @@ -157,7 +155,6 @@ static void copy_vmcb_control_area(struct vmcb_control_area *dst, > for (i = 0; i < MAX_VECTORS; i++) > dst->intercepts[i] = from->intercepts[i]; > > - dst->intercept_dr = from->intercept_dr; > dst->intercept_exceptions = from->intercept_exceptions; > dst->intercept = from->intercept; > dst->iopm_base_pa = from->iopm_base_pa; > @@ -717,8 +714,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm) > break; > } > case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { > - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); > - if (svm->nested.ctl.intercept_dr & bit) > + if (__is_intercept(&svm->nested.ctl.intercepts, exit_code)) Can I assume that all of these __<function> calls will become <function> calls when the grand unification is done? (Maybe I should just look ahead.)
> -----Original Message----- > From: Jim Mattson <jmattson@google.com> > Sent: Tuesday, July 28, 2020 6:59 PM > To: Moger, Babu <Babu.Moger@amd.com> > Cc: Paolo Bonzini <pbonzini@redhat.com>; Vitaly Kuznetsov > <vkuznets@redhat.com>; Wanpeng Li <wanpengli@tencent.com>; Sean > Christopherson <sean.j.christopherson@intel.com>; kvm list > <kvm@vger.kernel.org>; Joerg Roedel <joro@8bytes.org>; the arch/x86 > maintainers <x86@kernel.org>; LKML <linux-kernel@vger.kernel.org>; Ingo > Molnar <mingo@redhat.com>; Borislav Petkov <bp@alien8.de>; H . Peter Anvin > <hpa@zytor.com>; Thomas Gleixner <tglx@linutronix.de> > Subject: Re: [PATCH v3 03/11] KVM: SVM: Change intercept_dr to generic > intercepts > > On Tue, Jul 28, 2020 at 4:38 PM Babu Moger <babu.moger@amd.com> wrote: > > > > Modify intercept_dr to generic intercepts in vmcb_control_area. > > Use generic __set_intercept, __clr_intercept and __is_intercept to > > set/clear/test the intercept_dr bits. > > > > Signed-off-by: Babu Moger <babu.moger@amd.com> > > --- > > arch/x86/include/asm/svm.h | 36 ++++++++++++++++++------------------ > > arch/x86/kvm/svm/nested.c | 6 +----- > > arch/x86/kvm/svm/svm.c | 4 ++-- > > arch/x86/kvm/svm/svm.h | 34 +++++++++++++++++----------------- > > 4 files changed, 38 insertions(+), 42 deletions(-) > > > > diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h > > index d4739f4eae63..ffc89d8e4fcb 100644 > > --- a/arch/x86/include/asm/svm.h > > +++ b/arch/x86/include/asm/svm.h > > @@ -11,6 +11,7 @@ > > > > enum vector_offset { > > CR_VECTOR = 0, > > + DR_VECTOR, > > MAX_VECTORS, > > }; > > > > @@ -34,6 +35,23 @@ enum { > > INTERCEPT_CR6_WRITE, > > INTERCEPT_CR7_WRITE, > > INTERCEPT_CR8_WRITE, > > + /* Byte offset 004h (Vector 1) */ > > + INTERCEPT_DR0_READ = 32, > > + INTERCEPT_DR1_READ, > > + INTERCEPT_DR2_READ, > > + INTERCEPT_DR3_READ, > > + INTERCEPT_DR4_READ, > > + INTERCEPT_DR5_READ, > > + INTERCEPT_DR6_READ, > > + INTERCEPT_DR7_READ, > > + INTERCEPT_DR0_WRITE = 48, > > + INTERCEPT_DR1_WRITE, > > + INTERCEPT_DR2_WRITE, > > + INTERCEPT_DR3_WRITE, > > + INTERCEPT_DR4_WRITE, > > + INTERCEPT_DR5_WRITE, > > + INTERCEPT_DR6_WRITE, > > + INTERCEPT_DR7_WRITE, > > }; > > > > enum { > > @@ -89,7 +107,6 @@ enum { > > > > struct __attribute__ ((__packed__)) vmcb_control_area { > > u32 intercepts[MAX_VECTORS]; > > - u32 intercept_dr; > > u32 intercept_exceptions; > > u64 intercept; > > u8 reserved_1[40]; > > @@ -271,23 +288,6 @@ struct __attribute__ ((__packed__)) vmcb { > > #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK #define > > SVM_SELECTOR_CODE_MASK (1 << 3) > > > > -#define INTERCEPT_DR0_READ 0 > > -#define INTERCEPT_DR1_READ 1 > > -#define INTERCEPT_DR2_READ 2 > > -#define INTERCEPT_DR3_READ 3 > > -#define INTERCEPT_DR4_READ 4 > > -#define INTERCEPT_DR5_READ 5 > > -#define INTERCEPT_DR6_READ 6 > > -#define INTERCEPT_DR7_READ 7 > > -#define INTERCEPT_DR0_WRITE (16 + 0) > > -#define INTERCEPT_DR1_WRITE (16 + 1) > > -#define INTERCEPT_DR2_WRITE (16 + 2) > > -#define INTERCEPT_DR3_WRITE (16 + 3) > > -#define INTERCEPT_DR4_WRITE (16 + 4) > > -#define INTERCEPT_DR5_WRITE (16 + 5) > > -#define INTERCEPT_DR6_WRITE (16 + 6) > > -#define INTERCEPT_DR7_WRITE (16 + 7) > > - > > #define SVM_EVTINJ_VEC_MASK 0xff > > > > #define SVM_EVTINJ_TYPE_SHIFT 8 > > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c > > index 46f5c82d9b45..71ca89afb2a3 100644 > > --- a/arch/x86/kvm/svm/nested.c > > +++ b/arch/x86/kvm/svm/nested.c > > @@ -121,7 +121,6 @@ void recalc_intercepts(struct vcpu_svm *svm) > > for (i = 0; i < MAX_VECTORS; i++) > > c->intercepts[i] = h->intercepts[i]; > > > > - c->intercept_dr = h->intercept_dr; > > c->intercept_exceptions = h->intercept_exceptions; > > c->intercept = h->intercept; > > > > @@ -144,7 +143,6 @@ void recalc_intercepts(struct vcpu_svm *svm) > > for (i = 0; i < MAX_VECTORS; i++) > > c->intercepts[i] |= g->intercepts[i]; > > > > - c->intercept_dr |= g->intercept_dr; > > c->intercept_exceptions |= g->intercept_exceptions; > > c->intercept |= g->intercept; > > } > > @@ -157,7 +155,6 @@ static void copy_vmcb_control_area(struct > vmcb_control_area *dst, > > for (i = 0; i < MAX_VECTORS; i++) > > dst->intercepts[i] = from->intercepts[i]; > > > > - dst->intercept_dr = from->intercept_dr; > > dst->intercept_exceptions = from->intercept_exceptions; > > dst->intercept = from->intercept; > > dst->iopm_base_pa = from->iopm_base_pa; > > @@ -717,8 +714,7 @@ static int nested_svm_intercept(struct vcpu_svm > *svm) > > break; > > } > > case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { > > - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); > > - if (svm->nested.ctl.intercept_dr & bit) > > + if (__is_intercept(&svm->nested.ctl.intercepts, > > + exit_code)) > > Can I assume that all of these __<function> calls will become <function> calls > when the grand unification is done? (Maybe I should just look ahead.) There are two types of calls here. 1. Calls like set_cr_intercept, clr_cr_intercept, set_dr_intercept, clr_dr_intercept, set_exception_intercept, clr_exception_intercept. These calls pass svm data structure. I replaced these calls with either set_intercept or clr_intercept because we have combined all the intercept vectors into one 32 bit array. 2. Some calls sets or clears the bit directly like c->intercept_cr &= ~(1U << INTERCEPT_CR8_READ); Replaced these with __clr_intercept or __set_intercepts. There is a scope to make all these calls set_intercept or clr_intercept. These calls use another call get_host_vmcb to get the address. We can take that up as next cleanup.
On 29/07/20 01:59, Jim Mattson wrote: >> case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { >> - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); >> - if (svm->nested.ctl.intercept_dr & bit) >> + if (__is_intercept(&svm->nested.ctl.intercepts, exit_code)) > Can I assume that all of these __<function> calls will become > <function> calls when the grand unification is done? (Maybe I should > just look ahead.) > The <function> calls are reserved for the active VMCB while these take a vector. Probably it would be nicer to call them vmcb_{set,clr,is}_intercept and make them take a struct vmcb_control_area*, but apart from that the concept is fine Once we do the vmcb01/vmcb02/vmcb12 work, there will not be anymore &svm->nested.ctl (replaced by &svm->nested.vmcb12->ctl) and we will be able to change them to take a struct vmcb*. Then is_intercept would for example be simply: return vmcb_is_intercept(svm->vmcb, nr); as expected. Paolo
> -----Original Message----- > From: Paolo Bonzini <pbonzini@redhat.com> > Sent: Wednesday, July 29, 2020 6:12 PM > To: Jim Mattson <jmattson@google.com>; Moger, Babu > <Babu.Moger@amd.com> > Cc: Vitaly Kuznetsov <vkuznets@redhat.com>; Wanpeng Li > <wanpengli@tencent.com>; Sean Christopherson > <sean.j.christopherson@intel.com>; kvm list <kvm@vger.kernel.org>; Joerg > Roedel <joro@8bytes.org>; the arch/x86 maintainers <x86@kernel.org>; LKML > <linux-kernel@vger.kernel.org>; Ingo Molnar <mingo@redhat.com>; Borislav > Petkov <bp@alien8.de>; H . Peter Anvin <hpa@zytor.com>; Thomas Gleixner > <tglx@linutronix.de> > Subject: Re: [PATCH v3 03/11] KVM: SVM: Change intercept_dr to generic > intercepts > > On 29/07/20 01:59, Jim Mattson wrote: > >> case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { > >> - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); > >> - if (svm->nested.ctl.intercept_dr & bit) > >> + if (__is_intercept(&svm->nested.ctl.intercepts, > >> + exit_code)) > > Can I assume that all of these __<function> calls will become > > <function> calls when the grand unification is done? (Maybe I should > > just look ahead.) > > > > The <function> calls are reserved for the active VMCB while these take a vector. > Probably it would be nicer to call them vmcb_{set,clr,is}_intercept and make > them take a struct vmcb_control_area*, but apart from that the concept is fine > > Once we do the vmcb01/vmcb02/vmcb12 work, there will not be anymore > &svm->nested.ctl (replaced by &svm->nested.vmcb12->ctl) and we will be able > to change them to take a struct vmcb*. Then is_intercept would for example be > simply: Yea. True. It makes the code even cleaner. Also we can avoid calling recalc_intercepts every time we set or clear a bit inside the same function(like init_vmcb). Let me try to understand. vmcb01 is &svm->vmcb->control;l vmcb02 is &svm->nested.hsave->control vmcb12 is &svm->nested.ctl; The functions set_intercept and clr_intercept calls get_host_vmcb to get the vmcb address. static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) { if (is_guest_mode(&svm->vcpu)) return svm->nested.hsave; else return svm->vmcb; } I need to study little bit when is_guest_mode Is on or off. Let me take a look at. Thanks > > return vmcb_is_intercept(svm->vmcb, nr); > > as expected. > > Paolo
> -----Original Message----- > From: kvm-owner@vger.kernel.org <kvm-owner@vger.kernel.org> On Behalf > Of Babu Moger > Sent: Thursday, July 30, 2020 11:38 AM > To: Paolo Bonzini <pbonzini@redhat.com>; Jim Mattson > <jmattson@google.com> > Cc: Vitaly Kuznetsov <vkuznets@redhat.com>; Wanpeng Li > <wanpengli@tencent.com>; Sean Christopherson > <sean.j.christopherson@intel.com>; kvm list <kvm@vger.kernel.org>; Joerg > Roedel <joro@8bytes.org>; the arch/x86 maintainers <x86@kernel.org>; LKML > <linux-kernel@vger.kernel.org>; Ingo Molnar <mingo@redhat.com>; Borislav > Petkov <bp@alien8.de>; H . Peter Anvin <hpa@zytor.com>; Thomas Gleixner > <tglx@linutronix.de> > Subject: RE: [PATCH v3 03/11] KVM: SVM: Change intercept_dr to generic > intercepts > > > > > -----Original Message----- > > From: Paolo Bonzini <pbonzini@redhat.com> > > Sent: Wednesday, July 29, 2020 6:12 PM > > To: Jim Mattson <jmattson@google.com>; Moger, Babu > > <Babu.Moger@amd.com> > > Cc: Vitaly Kuznetsov <vkuznets@redhat.com>; Wanpeng Li > > <wanpengli@tencent.com>; Sean Christopherson > > <sean.j.christopherson@intel.com>; kvm list <kvm@vger.kernel.org>; > > Joerg Roedel <joro@8bytes.org>; the arch/x86 maintainers > > <x86@kernel.org>; LKML <linux-kernel@vger.kernel.org>; Ingo Molnar > > <mingo@redhat.com>; Borislav Petkov <bp@alien8.de>; H . Peter Anvin > > <hpa@zytor.com>; Thomas Gleixner <tglx@linutronix.de> > > Subject: Re: [PATCH v3 03/11] KVM: SVM: Change intercept_dr to generic > > intercepts > > > > On 29/07/20 01:59, Jim Mattson wrote: > > >> case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { > > >> - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); > > >> - if (svm->nested.ctl.intercept_dr & bit) > > >> + if (__is_intercept(&svm->nested.ctl.intercepts, > > >> + exit_code)) > > > Can I assume that all of these __<function> calls will become > > > <function> calls when the grand unification is done? (Maybe I should > > > just look ahead.) > > > > > > > The <function> calls are reserved for the active VMCB while these take a > vector. > > Probably it would be nicer to call them vmcb_{set,clr,is}_intercept > > and make them take a struct vmcb_control_area*, but apart from that > > the concept is fine > > > > Once we do the vmcb01/vmcb02/vmcb12 work, there will not be anymore > > &svm->nested.ctl (replaced by &svm->nested.vmcb12->ctl) and we will be > > able to change them to take a struct vmcb*. Then is_intercept would > > for example be > > simply: > Yea. True. It makes the code even cleaner. Also we can avoid calling > recalc_intercepts every time we set or clear a bit inside the same function(like > init_vmcb). > > Let me try to understand. > > vmcb01 is &svm->vmcb->control;l > vmcb02 is &svm->nested.hsave->control > vmcb12 is &svm->nested.ctl; > > The functions set_intercept and clr_intercept calls get_host_vmcb to get the > vmcb address. I will move the get_host_vmcb inside the caller and then call vmcb_set_intercept/vmcb_clr_intercept/vmcb_is_intercept directly. I will re post the series. This will change the whole series a little bit. Jim has already reviewed some of the patches. But I probably cannot use "Reviewed-by" if I change the patches too much. thanks > > static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) { > if (is_guest_mode(&svm->vcpu)) > return svm->nested.hsave; > else > return svm->vmcb; > } > > I need to study little bit when is_guest_mode Is on or off. Let me take a look at. > > Thanks > > > > > return vmcb_is_intercept(svm->vmcb, nr); > > > > as expected. > > > > Paolo
On 31/07/20 00:41, Babu Moger wrote: >> Let me try to understand. >> >> vmcb01 is &svm->vmcb->control;l >> vmcb02 is &svm->nested.hsave->control >> vmcb12 is &svm->nested.ctl; Right now we don't have a separate vmcb01/vmcb02, we have the current and hsave VMCBs. Cathy is working on it. Just do the refactoring by passing the control area to vmcb_set_intercept/vmcb_clr_intercept/vmcb_is_intercept. >> The functions set_intercept and clr_intercept calls get_host_vmcb to get the >> vmcb address. > > I will move the get_host_vmcb inside the caller and then call > vmcb_set_intercept/vmcb_clr_intercept/vmcb_is_intercept directly. Hmm no I think set_intercept and clr_intercept should remain as is. Paolo > I will re post the series. This will change the whole series a little bit.
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index d4739f4eae63..ffc89d8e4fcb 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -11,6 +11,7 @@ enum vector_offset { CR_VECTOR = 0, + DR_VECTOR, MAX_VECTORS, }; @@ -34,6 +35,23 @@ enum { INTERCEPT_CR6_WRITE, INTERCEPT_CR7_WRITE, INTERCEPT_CR8_WRITE, + /* Byte offset 004h (Vector 1) */ + INTERCEPT_DR0_READ = 32, + INTERCEPT_DR1_READ, + INTERCEPT_DR2_READ, + INTERCEPT_DR3_READ, + INTERCEPT_DR4_READ, + INTERCEPT_DR5_READ, + INTERCEPT_DR6_READ, + INTERCEPT_DR7_READ, + INTERCEPT_DR0_WRITE = 48, + INTERCEPT_DR1_WRITE, + INTERCEPT_DR2_WRITE, + INTERCEPT_DR3_WRITE, + INTERCEPT_DR4_WRITE, + INTERCEPT_DR5_WRITE, + INTERCEPT_DR6_WRITE, + INTERCEPT_DR7_WRITE, }; enum { @@ -89,7 +107,6 @@ enum { struct __attribute__ ((__packed__)) vmcb_control_area { u32 intercepts[MAX_VECTORS]; - u32 intercept_dr; u32 intercept_exceptions; u64 intercept; u8 reserved_1[40]; @@ -271,23 +288,6 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK #define SVM_SELECTOR_CODE_MASK (1 << 3) -#define INTERCEPT_DR0_READ 0 -#define INTERCEPT_DR1_READ 1 -#define INTERCEPT_DR2_READ 2 -#define INTERCEPT_DR3_READ 3 -#define INTERCEPT_DR4_READ 4 -#define INTERCEPT_DR5_READ 5 -#define INTERCEPT_DR6_READ 6 -#define INTERCEPT_DR7_READ 7 -#define INTERCEPT_DR0_WRITE (16 + 0) -#define INTERCEPT_DR1_WRITE (16 + 1) -#define INTERCEPT_DR2_WRITE (16 + 2) -#define INTERCEPT_DR3_WRITE (16 + 3) -#define INTERCEPT_DR4_WRITE (16 + 4) -#define INTERCEPT_DR5_WRITE (16 + 5) -#define INTERCEPT_DR6_WRITE (16 + 6) -#define INTERCEPT_DR7_WRITE (16 + 7) - #define SVM_EVTINJ_VEC_MASK 0xff #define SVM_EVTINJ_TYPE_SHIFT 8 diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 46f5c82d9b45..71ca89afb2a3 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -121,7 +121,6 @@ void recalc_intercepts(struct vcpu_svm *svm) for (i = 0; i < MAX_VECTORS; i++) c->intercepts[i] = h->intercepts[i]; - c->intercept_dr = h->intercept_dr; c->intercept_exceptions = h->intercept_exceptions; c->intercept = h->intercept; @@ -144,7 +143,6 @@ void recalc_intercepts(struct vcpu_svm *svm) for (i = 0; i < MAX_VECTORS; i++) c->intercepts[i] |= g->intercepts[i]; - c->intercept_dr |= g->intercept_dr; c->intercept_exceptions |= g->intercept_exceptions; c->intercept |= g->intercept; } @@ -157,7 +155,6 @@ static void copy_vmcb_control_area(struct vmcb_control_area *dst, for (i = 0; i < MAX_VECTORS; i++) dst->intercepts[i] = from->intercepts[i]; - dst->intercept_dr = from->intercept_dr; dst->intercept_exceptions = from->intercept_exceptions; dst->intercept = from->intercept; dst->iopm_base_pa = from->iopm_base_pa; @@ -717,8 +714,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm) break; } case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { - u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); - if (svm->nested.ctl.intercept_dr & bit) + if (__is_intercept(&svm->nested.ctl.intercepts, exit_code)) vmexit = NESTED_EXIT_DONE; break; } diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 334bda8b31c1..6d95025938d8 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2799,8 +2799,8 @@ static void dump_vmcb(struct kvm_vcpu *vcpu) pr_err("VMCB Control Area:\n"); pr_err("%-20s%04x\n", "cr_read:", control->intercepts[CR_VECTOR] & 0xffff); pr_err("%-20s%04x\n", "cr_write:", control->intercepts[CR_VECTOR] >> 16); - pr_err("%-20s%04x\n", "dr_read:", control->intercept_dr & 0xffff); - pr_err("%-20s%04x\n", "dr_write:", control->intercept_dr >> 16); + pr_err("%-20s%04x\n", "dr_read:", control->intercepts[DR_VECTOR] & 0xffff); + pr_err("%-20s%04x\n", "dr_write:", control->intercepts[DR_VECTOR] >> 16); pr_err("%-20s%08x\n", "exceptions:", control->intercept_exceptions); pr_err("%-20s%016llx\n", "intercepts:", control->intercept); pr_err("%-20s%d\n", "pause filter count:", control->pause_filter_count); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 89d1d91d5bc6..f33a50f92b92 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -261,22 +261,22 @@ static inline void set_dr_intercepts(struct vcpu_svm *svm) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_dr = (1 << INTERCEPT_DR0_READ) - | (1 << INTERCEPT_DR1_READ) - | (1 << INTERCEPT_DR2_READ) - | (1 << INTERCEPT_DR3_READ) - | (1 << INTERCEPT_DR4_READ) - | (1 << INTERCEPT_DR5_READ) - | (1 << INTERCEPT_DR6_READ) - | (1 << INTERCEPT_DR7_READ) - | (1 << INTERCEPT_DR0_WRITE) - | (1 << INTERCEPT_DR1_WRITE) - | (1 << INTERCEPT_DR2_WRITE) - | (1 << INTERCEPT_DR3_WRITE) - | (1 << INTERCEPT_DR4_WRITE) - | (1 << INTERCEPT_DR5_WRITE) - | (1 << INTERCEPT_DR6_WRITE) - | (1 << INTERCEPT_DR7_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR0_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR1_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR2_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR3_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR4_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR5_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR6_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR7_READ); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR0_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR1_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR2_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR3_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR4_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR5_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR6_WRITE); + __set_intercept(&vmcb->control.intercepts, INTERCEPT_DR7_WRITE); recalc_intercepts(svm); } @@ -285,7 +285,7 @@ static inline void clr_dr_intercepts(struct vcpu_svm *svm) { struct vmcb *vmcb = get_host_vmcb(svm); - vmcb->control.intercept_dr = 0; + vmcb->control.intercepts[DR_VECTOR] = 0; recalc_intercepts(svm); }
Modify intercept_dr to generic intercepts in vmcb_control_area. Use generic __set_intercept, __clr_intercept and __is_intercept to set/clear/test the intercept_dr bits. Signed-off-by: Babu Moger <babu.moger@amd.com> --- arch/x86/include/asm/svm.h | 36 ++++++++++++++++++------------------ arch/x86/kvm/svm/nested.c | 6 +----- arch/x86/kvm/svm/svm.c | 4 ++-- arch/x86/kvm/svm/svm.h | 34 +++++++++++++++++----------------- 4 files changed, 38 insertions(+), 42 deletions(-)