Commit c45ad722 authored by Babu Moger's avatar Babu Moger Committed by Paolo Bonzini

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: default avatarBabu Moger <babu.moger@amd.com>
Reviewed-by: default avatarJim Mattson <jmattson@google.com>
Message-Id: <159985247876.11252.16039238014239824460.stgit@bmoger-ubuntu>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a90c1ed9
...@@ -4,6 +4,14 @@ ...@@ -4,6 +4,14 @@
#include <uapi/asm/svm.h> #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 { enum {
INTERCEPT_INTR, INTERCEPT_INTR,
...@@ -57,6 +65,7 @@ enum { ...@@ -57,6 +65,7 @@ enum {
struct __attribute__ ((__packed__)) vmcb_control_area { struct __attribute__ ((__packed__)) vmcb_control_area {
u32 intercepts[MAX_INTERCEPT];
u32 intercept_cr; u32 intercept_cr;
u32 intercept_dr; u32 intercept_dr;
u32 intercept_exceptions; u32 intercept_exceptions;
......
...@@ -98,6 +98,7 @@ static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu) ...@@ -98,6 +98,7 @@ static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu)
void recalc_intercepts(struct vcpu_svm *svm) void recalc_intercepts(struct vcpu_svm *svm)
{ {
struct vmcb_control_area *c, *h, *g; struct vmcb_control_area *c, *h, *g;
unsigned int i;
vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS); vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
...@@ -108,6 +109,9 @@ void recalc_intercepts(struct vcpu_svm *svm) ...@@ -108,6 +109,9 @@ void recalc_intercepts(struct vcpu_svm *svm)
h = &svm->nested.hsave->control; h = &svm->nested.hsave->control;
g = &svm->nested.ctl; 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_cr = h->intercept_cr;
c->intercept_dr = h->intercept_dr; c->intercept_dr = h->intercept_dr;
c->intercept_exceptions = h->intercept_exceptions; c->intercept_exceptions = h->intercept_exceptions;
...@@ -129,6 +133,9 @@ void recalc_intercepts(struct vcpu_svm *svm) ...@@ -129,6 +133,9 @@ void recalc_intercepts(struct vcpu_svm *svm)
/* We don't want to see VMMCALLs from a nested guest */ /* We don't want to see VMMCALLs from a nested guest */
c->intercept &= ~(1ULL << INTERCEPT_VMMCALL); 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_cr |= g->intercept_cr;
c->intercept_dr |= g->intercept_dr; c->intercept_dr |= g->intercept_dr;
c->intercept_exceptions |= g->intercept_exceptions; c->intercept_exceptions |= g->intercept_exceptions;
...@@ -138,6 +145,11 @@ void recalc_intercepts(struct vcpu_svm *svm) ...@@ -138,6 +145,11 @@ void recalc_intercepts(struct vcpu_svm *svm)
static void copy_vmcb_control_area(struct vmcb_control_area *dst, static void copy_vmcb_control_area(struct vmcb_control_area *dst,
struct vmcb_control_area *from) 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_cr = from->intercept_cr;
dst->intercept_dr = from->intercept_dr; dst->intercept_dr = from->intercept_dr;
dst->intercept_exceptions = from->intercept_exceptions; dst->intercept_exceptions = from->intercept_exceptions;
......
...@@ -213,6 +213,24 @@ static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) ...@@ -213,6 +213,24 @@ static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm)
return svm->vmcb; 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) static inline void set_cr_intercept(struct vcpu_svm *svm, int bit)
{ {
struct vmcb *vmcb = get_host_vmcb(svm); struct vmcb *vmcb = get_host_vmcb(svm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment