summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2012-09-25 19:08:51 +0000
committerneel <neel@FreeBSD.org>2012-09-25 19:08:51 +0000
commitebdd69568d7fa97153aa47a86afe367476a0a1de (patch)
treeb73faadf3ccee979f76090f7f988fe5e700627d7 /sys/amd64
parentc34be7b811ad199e64f66db339e7f64c773ca0a7 (diff)
downloadFreeBSD-src-ebdd69568d7fa97153aa47a86afe367476a0a1de.zip
FreeBSD-src-ebdd69568d7fa97153aa47a86afe367476a0a1de.tar.gz
Add ioctls to control the X2APIC capability exposed by the virtual machine to
the guest. At the moment this simply sets the state in the 'vcpu' instance but there is no code that acts upon these settings.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/include/vmm.h11
-rw-r--r--sys/amd64/include/vmm_dev.h11
-rw-r--r--sys/amd64/vmm/vmm.c27
-rw-r--r--sys/amd64/vmm/vmm_dev.c12
4 files changed, 61 insertions, 0 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index e841963..0b3a29c 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -40,6 +40,8 @@ struct vm_exit;
struct vm_run;
struct vlapic;
+enum x2apic_state;
+
typedef int (*vmm_init_func_t)(void);
typedef int (*vmm_cleanup_func_t)(void);
typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */
@@ -109,6 +111,8 @@ uint64_t *vm_guest_msrs(struct vm *vm, int cpu);
struct vlapic *vm_lapic(struct vm *vm, int cpu);
int vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
int vm_set_capability(struct vm *vm, int vcpu, int type, int val);
+int vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state);
+int vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state);
void vm_activate_cpu(struct vm *vm, int vcpu);
cpuset_t vm_active_cpus(struct vm *vm);
struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
@@ -205,6 +209,13 @@ enum vm_cap_type {
VM_CAP_MAX
};
+enum x2apic_state {
+ X2APIC_ENABLED,
+ X2APIC_AVAILABLE,
+ X2APIC_DISABLED,
+ X2APIC_STATE_LAST
+};
+
/*
* The 'access' field has the format specified in Table 21-2 of the Intel
* Architecture Manual vol 3b.
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index d1a50d6..fc64fd8 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -136,6 +136,11 @@ struct vm_stat_desc {
char desc[128]; /* out */
};
+struct vm_x2apic {
+ int cpuid;
+ enum x2apic_state state;
+};
+
enum {
IOCNUM_RUN,
IOCNUM_SET_PINNING,
@@ -158,6 +163,8 @@ enum {
IOCNUM_INJECT_NMI,
IOCNUM_VM_STATS,
IOCNUM_VM_STAT_DESC,
+ IOCNUM_SET_X2APIC_STATE,
+ IOCNUM_GET_X2APIC_STATE,
};
#define VM_RUN \
@@ -202,4 +209,8 @@ enum {
_IOWR('v', IOCNUM_VM_STATS, struct vm_stats)
#define VM_STAT_DESC \
_IOWR('v', IOCNUM_VM_STAT_DESC, struct vm_stat_desc)
+#define VM_SET_X2APIC_STATE \
+ _IOW('v', IOCNUM_SET_X2APIC_STATE, struct vm_x2apic)
+#define VM_GET_X2APIC_STATE \
+ _IOWR('v', IOCNUM_GET_X2APIC_STATE, struct vm_x2apic)
#endif
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index d896f6d..29dbe67 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -73,6 +73,7 @@ struct vcpu {
struct savefpu *guestfpu; /* guest fpu state */
void *stats;
struct vm_exit exitinfo;
+ enum x2apic_state x2apic_state;
};
#define VCPU_F_PINNED 0x0001
#define VCPU_F_RUNNING 0x0002
@@ -163,6 +164,7 @@ vcpu_init(struct vm *vm, uint32_t vcpu_id)
vcpu->guestfpu = fpu_save_area_alloc();
fpu_save_area_reset(vcpu->guestfpu);
vcpu->stats = vmm_stat_alloc();
+ vcpu->x2apic_state = X2APIC_ENABLED;
}
struct vm_exit *
@@ -745,3 +747,28 @@ vcpu_stats(struct vm *vm, int vcpuid)
return (vm->vcpu[vcpuid].stats);
}
+
+int
+vm_get_x2apic_state(struct vm *vm, int vcpuid, enum x2apic_state *state)
+{
+ if (vcpuid < 0 || vcpuid >= VM_MAXCPU)
+ return (EINVAL);
+
+ *state = vm->vcpu[vcpuid].x2apic_state;
+
+ return (0);
+}
+
+int
+vm_set_x2apic_state(struct vm *vm, int vcpuid, enum x2apic_state state)
+{
+ if (vcpuid < 0 || vcpuid >= VM_MAXCPU)
+ return (EINVAL);
+
+ if (state < 0 || state >= X2APIC_STATE_LAST)
+ return (EINVAL);
+
+ vm->vcpu[vcpuid].x2apic_state = state;
+
+ return (0);
+}
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index 116b5f1..686ddec 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -163,6 +163,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct vm_nmi *vmnmi;
struct vm_stats *vmstats;
struct vm_stat_desc *statdesc;
+ struct vm_x2apic *x2apic;
mtx_lock(&vmmdev_mtx);
sc = vmmdev_lookup2(cdev);
@@ -185,6 +186,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case VM_GET_CAPABILITY:
case VM_SET_CAPABILITY:
case VM_PPTDEV_MSI:
+ case VM_SET_X2APIC_STATE:
/*
* XXX fragile, handle with care
* Assumes that the first field of the ioctl data is the vcpu.
@@ -335,6 +337,16 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
vmcap->captype,
vmcap->capval);
break;
+ case VM_SET_X2APIC_STATE:
+ x2apic = (struct vm_x2apic *)data;
+ error = vm_set_x2apic_state(sc->vm,
+ x2apic->cpuid, x2apic->state);
+ break;
+ case VM_GET_X2APIC_STATE:
+ x2apic = (struct vm_x2apic *)data;
+ error = vm_get_x2apic_state(sc->vm,
+ x2apic->cpuid, &x2apic->state);
+ break;
default:
error = ENOTTY;
break;
OpenPOWER on IntegriCloud