blob: ca72e3a472a37e3877e3ab95964bd746d71fe3fe [file] [log] [blame]
#pragma once
#include <ros/vmm.h>
#include <arch/vmm/intel/vmx.h>
static inline int cpu_has_vmx(void)
{
unsigned long ecx = cpuid_ecx(1);
return ecx & (1<<5); /* CPUID.1:ECX.VMX[bit 5] -> VT */
}
/* maybe someday, not today. */
static inline int cpu_has_svm(const char **msg)
{
return 0;
}
#define VMM_VMEXIT_NR_TYPES 65
struct vmm {
spinlock_t lock; /* protects guest_pcore assignment */
qlock_t qlock;
// always false.
int amd;
// true if this is a VMMCP.
bool vmmcp;
int flags;
// Number of cores in this VMMCP.
int nr_guest_pcores;
// The VMCS is intel-specific. But, maybe, someday, AMD will
// be back. Just make this an anon union and we'll work it
// all out later. Again, remember, we're compiling in support
// for both architectures to ensure that we can correctly
// figure out at boot time what we're on and what we should
// do. This avoids the problem seen years ago with RH6 where
// you could install a kernel from the ISO, but the kernel it
// installed would GPF on a K7.
union {
void *svm;
struct vmx_vmm vmx;
};
struct guest_pcore **guest_pcores;
size_t gpc_array_elem;
unsigned long vmexits[VMM_VMEXIT_NR_TYPES];
};
void vmm_init(void);
void vmm_pcpu_init(void);
void __vmm_struct_init(struct proc *p);
void __vmm_add_gpcs(struct proc *p, unsigned int nr_more_gpcs,
struct vmm_gpcore_init *u_gpcis);
void __vmm_struct_cleanup(struct proc *p);
int vmm_poke_guest(struct proc *p, int guest_pcoreid);
struct guest_pcore *create_guest_pcore(struct proc *p,
struct vmm_gpcore_init *gpci);
void destroy_guest_pcore(struct guest_pcore *vcpu);
uint64_t construct_eptp(physaddr_t root_hpa);
void ept_flush(uint64_t eptp);
struct guest_pcore *lookup_guest_pcore(struct proc *p, int guest_pcoreid);
struct guest_pcore *load_guest_pcore(struct proc *p, int guest_pcoreid);
void unload_guest_pcore(struct proc *p, int guest_pcoreid);
#define VMM_MSR_EMU_READ 1
#define VMM_MSR_EMU_WRITE 2
bool vmm_emulate_msr(struct vm_trapframe *vm_tf, int op);