diff options
author | Babu Moger <babu.moger@amd.com> | 2020-09-11 14:27:58 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-09-28 07:57:13 -0400 |
commit | c45ad7229d139ad48e894a271f8df6975e53d12e (patch) | |
tree | 0211835bcbb626176211c45fe36a2c33ac155c2b | |
parent | a90c1ed9f11dbc3d37664a8561e50e3f3695c539 (diff) | |
download | linux-c45ad7229d139ad48e894a271f8df6975e53d12e.tar.bz2 |
KVM: SVM: Introduce vmcb_(set_intercept/clr_intercept/_is_intercept)
This is in preparation for the future intercept vector additions.
Add new functions vmcb_set_intercept, vmcb_clr_intercept and vmcb_is_intercept
using kernel APIs __set_bit, __clear_bit and test_bit espectively.
Signed-off-by: Babu Moger <babu.moger@amd.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Message-Id: <159985247876.11252.16039238014239824460.stgit@bmoger-ubuntu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/include/asm/svm.h | 9 | ||||
-rw-r--r-- | arch/x86/kvm/svm/nested.c | 12 | ||||
-rw-r--r-- | arch/x86/kvm/svm/svm.h | 18 |
3 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index cf13f9e78585..debe71f0226c 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -4,6 +4,14 @@ #include <uapi/asm/svm.h> +/* + * 32-bit intercept words in the VMCB Control Area, starting + * at Byte offset 000h. + */ + +enum intercept_words { + MAX_INTERCEPT, +}; enum { INTERCEPT_INTR, @@ -57,6 +65,7 @@ enum { struct __attribute__ ((__packed__)) vmcb_control_area { + u32 intercepts[MAX_INTERCEPT]; u32 intercept_cr; u32 intercept_dr; u32 intercept_exceptions; diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index c10a9a80022e..69dfd7c1a5b7 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -98,6 +98,7 @@ static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu) void recalc_intercepts(struct vcpu_svm *svm) { struct vmcb_control_area *c, *h, *g; + unsigned int i; vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS); @@ -108,6 +109,9 @@ void recalc_intercepts(struct vcpu_svm *svm) h = &svm->nested.hsave->control; g = &svm->nested.ctl; + for (i = 0; i < MAX_INTERCEPT; i++) + c->intercepts[i] = h->intercepts[i]; + c->intercept_cr = h->intercept_cr; c->intercept_dr = h->intercept_dr; c->intercept_exceptions = h->intercept_exceptions; @@ -129,6 +133,9 @@ void recalc_intercepts(struct vcpu_svm *svm) /* We don't want to see VMMCALLs from a nested guest */ c->intercept &= ~(1ULL << INTERCEPT_VMMCALL); + for (i = 0; i < MAX_INTERCEPT; i++) + c->intercepts[i] |= g->intercepts[i]; + c->intercept_cr |= g->intercept_cr; c->intercept_dr |= g->intercept_dr; c->intercept_exceptions |= g->intercept_exceptions; @@ -138,6 +145,11 @@ void recalc_intercepts(struct vcpu_svm *svm) static void copy_vmcb_control_area(struct vmcb_control_area *dst, struct vmcb_control_area *from) { + unsigned int i; + + for (i = 0; i < MAX_INTERCEPT; i++) + dst->intercepts[i] = from->intercepts[i]; + dst->intercept_cr = from->intercept_cr; dst->intercept_dr = from->intercept_dr; dst->intercept_exceptions = from->intercept_exceptions; diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index e3aca71b24ab..83202c40857e 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -213,6 +213,24 @@ static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) return svm->vmcb; } +static inline void vmcb_set_intercept(struct vmcb_control_area *control, u32 bit) +{ + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + __set_bit(bit, (unsigned long *)&control->intercepts); +} + +static inline void vmcb_clr_intercept(struct vmcb_control_area *control, u32 bit) +{ + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + __clear_bit(bit, (unsigned long *)&control->intercepts); +} + +static inline bool vmcb_is_intercept(struct vmcb_control_area *control, u32 bit) +{ + WARN_ON_ONCE(bit >= 32 * MAX_INTERCEPT); + return test_bit(bit, (unsigned long *)&control->intercepts); +} + static inline void set_cr_intercept(struct vcpu_svm *svm, int bit) { struct vmcb *vmcb = get_host_vmcb(svm); |