#ifndef _NVMM_INTERNAL_H_
#define _NVMM_INTERNAL_H_
#include <sys/types.h>
#include <sys/lwp.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/sched.h>
#include <dev/nvmm/nvmm.h>
struct uvm_object;
struct vmspace;
#define NVMM_MAX_MACHINES 128
#define NVMM_MAX_VCPUS 256
#define NVMM_MAX_HMAPPINGS 32
#define NVMM_MAX_RAM (128ULL * (1 << 30))
struct nvmm_owner {
pid_t pid;
};
struct nvmm_cpu {
bool present;
nvmm_cpuid_t cpuid;
kmutex_t lock;
struct nvmm_comm_page *comm;
int hcpu_last;
void *cpudata;
};
struct nvmm_hmapping {
bool present;
uintptr_t hva;
size_t size;
struct uvm_object *uobj;
};
struct nvmm_machine {
bool present;
nvmm_machid_t machid;
time_t time;
struct nvmm_owner *owner;
krwlock_t lock;
struct uvm_object *commuobj;
struct vmspace *vm;
gpaddr_t gpa_begin;
gpaddr_t gpa_end;
struct nvmm_hmapping hmap[NVMM_MAX_HMAPPINGS];
volatile unsigned int ncpus;
struct nvmm_cpu cpus[NVMM_MAX_VCPUS];
void *machdata;
};
struct nvmm_impl {
const char *name;
bool (*ident)(void);
void (*init)(void);
void (*fini)(void);
void (*capability)(struct nvmm_capability *);
void (*suspend_interrupt)(void);
void (*suspend)(void);
void (*resume)(void);
size_t mach_conf_max;
const size_t *mach_conf_sizes;
size_t vcpu_conf_max;
const size_t *vcpu_conf_sizes;
size_t state_size;
void (*machine_create)(struct nvmm_machine *);
void (*machine_destroy)(struct nvmm_machine *);
int (*machine_configure)(struct nvmm_machine *, uint64_t, void *);
void (*machine_suspend)(struct nvmm_machine *);
void (*machine_resume)(struct nvmm_machine *);
int (*vcpu_create)(struct nvmm_machine *, struct nvmm_cpu *);
void (*vcpu_destroy)(struct nvmm_machine *, struct nvmm_cpu *);
int (*vcpu_configure)(struct nvmm_cpu *, uint64_t, void *);
void (*vcpu_setstate)(struct nvmm_cpu *);
void (*vcpu_getstate)(struct nvmm_cpu *);
int (*vcpu_inject)(struct nvmm_cpu *);
int (*vcpu_run)(struct nvmm_machine *, struct nvmm_cpu *,
struct nvmm_vcpu_exit *);
void (*vcpu_suspend)(struct nvmm_machine *, struct nvmm_cpu *);
void (*vcpu_resume)(struct nvmm_machine *, struct nvmm_cpu *);
};
#if defined(__x86_64__)
extern const struct nvmm_impl nvmm_x86_svm;
extern const struct nvmm_impl nvmm_x86_vmx;
#endif
extern volatile bool nvmm_suspending;
static inline bool
nvmm_return_needed(struct nvmm_cpu *vcpu, struct nvmm_vcpu_exit *exit)
{
if (__predict_false(preempt_needed())) {
exit->reason = NVMM_VCPU_EXIT_NONE;
return true;
}
if (__predict_false(curlwp->l_flag & LW_USERRET)) {
exit->reason = NVMM_VCPU_EXIT_NONE;
return true;
}
if (__predict_false(vcpu->comm->stop)) {
exit->reason = NVMM_VCPU_EXIT_STOPPED;
return true;
}
if (__predict_false(atomic_load_relaxed(&nvmm_suspending))) {
exit->reason = NVMM_VCPU_EXIT_NONE;
return true;
}
return false;
}
#endif