#ifndef _SVM_SOFTC_H_
#define _SVM_SOFTC_H_
#define SVM_IO_BITMAP_SIZE (3 * PAGE_SIZE)
#define SVM_MSR_BITMAP_SIZE (2 * PAGE_SIZE)
#include <sys/hma.h>
#include "vmcb.h"
#include "svm_pmu.h"
#define SVM_HOST_MSR_NUM 4
struct svm_vcpu {
struct vmcb vmcb;
struct svm_regctx swctx;
uint64_t vmcb_pa;
uint64_t nextrip;
int lastcpu;
uint32_t dirty;
uint64_t nptgen;
hma_svm_asid_t hma_asid;
boolean_t loaded;
struct svm_pmu_vcpu pmu;
} __aligned(PAGE_SIZE);
struct svm_softc {
uint8_t apic_page[VM_MAXCPU][PAGE_SIZE];
struct svm_vcpu vcpu[VM_MAXCPU];
uint64_t nptp;
uint8_t *iopm_bitmap;
uint8_t *msr_bitmap;
struct vm *vm;
uint64_t host_msrs[VM_MAXCPU][SVM_HOST_MSR_NUM];
svm_pmu_flavor_t pmu_flavor;
};
CTASSERT((offsetof(struct svm_softc, nptp) & PAGE_MASK) == 0);
static __inline struct svm_vcpu *
svm_get_vcpu(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu]));
}
static __inline struct vmcb *
svm_get_vmcb(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu].vmcb));
}
static __inline struct vmcb_state *
svm_get_vmcb_state(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu].vmcb.state));
}
static __inline struct vmcb_ctrl *
svm_get_vmcb_ctrl(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu].vmcb.ctrl));
}
static __inline struct svm_regctx *
svm_get_guest_regctx(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu].swctx));
}
static __inline struct svm_pmu_vcpu *
svm_get_pmu(struct svm_softc *sc, int vcpu)
{
return (&(sc->vcpu[vcpu].pmu));
}
static __inline void
svm_set_dirty(struct svm_softc *sc, int vcpu, uint32_t dirtybits)
{
struct svm_vcpu *vcpustate = svm_get_vcpu(sc, vcpu);
vcpustate->dirty |= dirtybits;
}
static __inline void
svm_apply_dirty(struct svm_softc *sc, int vcpu)
{
struct svm_vcpu *vcpustate = svm_get_vcpu(sc, vcpu);
struct vmcb_ctrl *ctrl = svm_get_vmcb_ctrl(sc, vcpu);
ctrl->vmcb_clean = ~vcpustate->dirty;
vcpustate->dirty = 0;
}
int svm_get_intercept(struct svm_softc *, int, int, uint32_t);
void svm_set_intercept(struct svm_softc *, int, int, uint32_t, int);
static __inline void
svm_disable_intercept(struct svm_softc *sc, int vcpu, int off, uint32_t bitmask)
{
svm_set_intercept(sc, vcpu, off, bitmask, 0);
}
static __inline void
svm_enable_intercept(struct svm_softc *sc, int vcpu, int off, uint32_t bitmask)
{
svm_set_intercept(sc, vcpu, off, bitmask, 1);
}
#endif