svn commit: r240922 - in projects/bhyve: lib/libvmmapi
sys/amd64/include sys/amd64/vmm usr.sbin/vmmctl
Neel Natu
neel at FreeBSD.org
Tue Sep 25 19:08:53 UTC 2012
Author: neel
Date: Tue Sep 25 19:08:51 2012
New Revision: 240922
URL: http://svn.freebsd.org/changeset/base/240922
Log:
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.
Modified:
projects/bhyve/lib/libvmmapi/vmmapi.c
projects/bhyve/lib/libvmmapi/vmmapi.h
projects/bhyve/sys/amd64/include/vmm.h
projects/bhyve/sys/amd64/include/vmm_dev.h
projects/bhyve/sys/amd64/vmm/vmm.c
projects/bhyve/sys/amd64/vmm/vmm_dev.c
projects/bhyve/usr.sbin/vmmctl/vmmctl.c
Modified: projects/bhyve/lib/libvmmapi/vmmapi.c
==============================================================================
--- projects/bhyve/lib/libvmmapi/vmmapi.c Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/lib/libvmmapi/vmmapi.c Tue Sep 25 19:08:51 2012 (r240922)
@@ -537,6 +537,35 @@ vm_get_stat_desc(struct vmctx *ctx, int
return (NULL);
}
+int
+vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *state)
+{
+ int error;
+ struct vm_x2apic x2apic;
+
+ bzero(&x2apic, sizeof(x2apic));
+ x2apic.cpuid = vcpu;
+
+ error = ioctl(ctx->fd, VM_GET_X2APIC_STATE, &x2apic);
+ *state = x2apic.state;
+ return (error);
+}
+
+int
+vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state)
+{
+ int error;
+ struct vm_x2apic x2apic;
+
+ bzero(&x2apic, sizeof(x2apic));
+ x2apic.cpuid = vcpu;
+ x2apic.state = state;
+
+ error = ioctl(ctx->fd, VM_SET_X2APIC_STATE, &x2apic);
+
+ return (error);
+}
+
/*
* From Intel Vol 3a:
* Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT
Modified: projects/bhyve/lib/libvmmapi/vmmapi.h
==============================================================================
--- projects/bhyve/lib/libvmmapi/vmmapi.h Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/lib/libvmmapi/vmmapi.h Tue Sep 25 19:08:51 2012 (r240922)
@@ -30,6 +30,7 @@
#define _VMMAPI_H_
struct vmctx;
+enum x2apic_state;
int vm_create(const char *name);
struct vmctx *vm_open(const char *name);
@@ -90,6 +91,9 @@ uint64_t *vm_get_stats(struct vmctx *ctx
int *ret_entries);
const char *vm_get_stat_desc(struct vmctx *ctx, int index);
+int vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *s);
+int vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state s);
+
/* Reset vcpu register state */
int vcpu_reset(struct vmctx *ctx, int vcpu);
Modified: projects/bhyve/sys/amd64/include/vmm.h
==============================================================================
--- projects/bhyve/sys/amd64/include/vmm.h Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/sys/amd64/include/vmm.h Tue Sep 25 19:08:51 2012 (r240922)
@@ -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, i
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.
Modified: projects/bhyve/sys/amd64/include/vmm_dev.h
==============================================================================
--- projects/bhyve/sys/amd64/include/vmm_dev.h Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/sys/amd64/include/vmm_dev.h Tue Sep 25 19:08:51 2012 (r240922)
@@ -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
Modified: projects/bhyve/sys/amd64/vmm/vmm.c
==============================================================================
--- projects/bhyve/sys/amd64/vmm/vmm.c Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/sys/amd64/vmm/vmm.c Tue Sep 25 19:08:51 2012 (r240922)
@@ -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_i
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);
+}
Modified: projects/bhyve/sys/amd64/vmm/vmm_dev.c
==============================================================================
--- projects/bhyve/sys/amd64/vmm/vmm_dev.c Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/sys/amd64/vmm/vmm_dev.c Tue Sep 25 19:08:51 2012 (r240922)
@@ -163,6 +163,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c
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 c
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 c
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;
Modified: projects/bhyve/usr.sbin/vmmctl/vmmctl.c
==============================================================================
--- projects/bhyve/usr.sbin/vmmctl/vmmctl.c Tue Sep 25 14:55:46 2012 (r240921)
+++ projects/bhyve/usr.sbin/vmmctl/vmmctl.c Tue Sep 25 19:08:51 2012 (r240922)
@@ -185,6 +185,8 @@ usage(void)
" [--get-vmcs-interruptibility]\n"
" [--set-pinning=<host_cpuid>]\n"
" [--get-pinning]\n"
+ " [--set-x2apic-state=<state>]\n"
+ " [--get-x2apic-state]\n"
" [--set-lowmem=<memory below 4GB in units of MB>]\n"
" [--get-lowmem]\n"
" [--set-highmem=<memory above 4GB in units of MB>]\n"
@@ -217,6 +219,8 @@ static int set_desc_ldtr, get_desc_ldtr;
static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;
static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;
static int set_pinning, get_pinning, pincpu;
+static int set_x2apic_state, get_x2apic_state;
+enum x2apic_state x2apic_state;
static int run;
/*
@@ -371,6 +375,7 @@ enum {
SET_TR,
SET_LDTR,
SET_PINNING,
+ SET_X2APIC_STATE,
SET_VMCS_EXCEPTION_BITMAP,
SET_VMCS_ENTRY_INTERRUPTION_INFO,
SET_CAP,
@@ -419,6 +424,7 @@ main(int argc, char *argv[])
{ "set-tr", REQ_ARG, 0, SET_TR },
{ "set-ldtr", REQ_ARG, 0, SET_LDTR },
{ "set-pinning",REQ_ARG, 0, SET_PINNING },
+ { "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE },
{ "set-vmcs-exception-bitmap",
REQ_ARG, 0, SET_VMCS_EXCEPTION_BITMAP },
{ "set-vmcs-entry-interruption-info",
@@ -547,6 +553,7 @@ main(int argc, char *argv[])
{ "get-vmcs-interruptibility",
NO_ARG, &get_vmcs_interruptibility, 1 },
{ "get-pinning",NO_ARG, &get_pinning, 1 },
+ { "get-x2apic-state",NO_ARG, &get_x2apic_state, 1 },
{ "get-all", NO_ARG, &get_all, 1 },
{ "run", NO_ARG, &run, 1 },
{ "create", NO_ARG, &create, 1 },
@@ -656,6 +663,10 @@ main(int argc, char *argv[])
pincpu = strtol(optarg, NULL, 0);
set_pinning = 1;
break;
+ case SET_X2APIC_STATE:
+ x2apic_state = strtol(optarg, NULL, 0);
+ set_x2apic_state = 1;
+ break;
case SET_VMCS_EXCEPTION_BITMAP:
exception_bitmap = strtoul(optarg, NULL, 0);
set_exception_bitmap = 1;
@@ -804,6 +815,9 @@ main(int argc, char *argv[])
if (!error && set_pinning)
error = vm_set_pinning(ctx, vcpu, pincpu);
+ if (!error && set_x2apic_state)
+ error = vm_set_x2apic_state(ctx, vcpu, x2apic_state);
+
if (!error && set_exception_bitmap) {
error = vm_set_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP,
exception_bitmap);
@@ -1129,6 +1143,12 @@ main(int argc, char *argv[])
}
}
+ if (!error && (get_x2apic_state || get_all)) {
+ error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state);
+ if (error == 0)
+ printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state);
+ }
+
if (!error && (get_pinbased_ctls || get_all)) {
error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl);
if (error == 0)
More information about the svn-src-projects
mailing list