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

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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
+12 −0
Original line number Diff line number Diff line
@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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);