Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164058603
D9930.id26094.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D9930.id26094.diff
View Options
Index: lib/libvmmapi/vmmapi.h
===================================================================
--- lib/libvmmapi/vmmapi.h
+++ lib/libvmmapi/vmmapi.h
@@ -209,6 +209,9 @@
int vm_suspended_cpus(struct vmctx *ctx, cpuset_t *cpus);
int vm_activate_cpu(struct vmctx *ctx, int vcpu);
+/* Set cpu topology */
+int vm_set_topology(struct vmctx *ctx, uint64_t sockets, uint64_t cores, uint64_t threads, uint64_t maxcpus);
+
/*
* FreeBSD specific APIs
*/
Index: lib/libvmmapi/vmmapi.c
===================================================================
--- lib/libvmmapi/vmmapi.c
+++ lib/libvmmapi/vmmapi.c
@@ -1418,6 +1418,19 @@
}
int
+vm_set_topology(struct vmctx *ctx, uint64_t sockets, uint64_t cores, uint64_t threads, uint64_t maxcpus)
+{
+ struct vm_cpu_topology topology;
+
+ bzero(&topology, sizeof (struct vm_cpu_topology));
+ topology.sockets = sockets;
+ topology.cores = cores;
+ topology.threads = threads;
+ topology.maxcpus = maxcpus;
+ return (ioctl(ctx->fd, VM_SET_TOPOLOGY, &topology));
+}
+
+int
vm_get_device_fd(struct vmctx *ctx)
{
@@ -1444,7 +1457,7 @@
VM_GET_HPET_CAPABILITIES, VM_GET_GPA_PMAP, VM_GLA2GPA,
VM_ACTIVATE_CPU, VM_GET_CPUS, VM_SET_INTINFO, VM_GET_INTINFO,
VM_RTC_WRITE, VM_RTC_READ, VM_RTC_SETTIME, VM_RTC_GETTIME,
- VM_RESTART_INSTRUCTION };
+ VM_RESTART_INSTRUCTION, VM_SET_TOPOLOGY, VM_GET_TOPOLOGY };
if (len == NULL) {
cmds = malloc(sizeof(vm_ioctl_cmds));
Index: sys/amd64/include/vmm.h
===================================================================
--- sys/amd64/include/vmm.h
+++ sys/amd64/include/vmm.h
@@ -174,6 +174,10 @@
void vm_destroy(struct vm *vm);
int vm_reinit(struct vm *vm);
const char *vm_name(struct vm *vm);
+void vm_get_topology(struct vm *vm, uint64_t *sockets, uint64_t *cores,
+ uint64_t *threads, uint64_t *maxcpus);
+void vm_set_topology(struct vm *vm, uint64_t *sockets, uint64_t *cores,
+ uint64_t *threads, uint64_t *maxcpus);
/*
* APIs that modify the guest memory map require all vcpus to be frozen.
Index: sys/amd64/include/vmm_dev.h
===================================================================
--- sys/amd64/include/vmm_dev.h
+++ sys/amd64/include/vmm_dev.h
@@ -216,6 +216,13 @@
uint8_t value;
};
+struct vm_cpu_topology {
+ uint64_t sockets;
+ uint64_t cores;
+ uint64_t threads;
+ uint64_t maxcpus;
+};
+
enum {
/* general routines */
IOCNUM_ABIVERS = 0,
@@ -286,6 +293,10 @@
IOCNUM_RTC_WRITE = 101,
IOCNUM_RTC_SETTIME = 102,
IOCNUM_RTC_GETTIME = 103,
+
+ /* CPU Topology */
+ IOCNUM_SET_TOPOLOGY = 104,
+ IOCNUM_GET_TOPOLOGY = 105,
};
#define VM_RUN \
@@ -382,4 +393,8 @@
_IOR('v', IOCNUM_RTC_GETTIME, struct vm_rtc_time)
#define VM_RESTART_INSTRUCTION \
_IOW('v', IOCNUM_RESTART_INSTRUCTION, int)
+#define VM_SET_TOPOLOGY \
+ _IOW('v', IOCNUM_SET_TOPOLOGY, struct vm_cpu_topology)
+#define VM_GET_TOPOLOGY \
+ _IOR('v', IOCNUM_GET_TOPOLOGY, struct vm_cpu_topology)
#endif
Index: sys/amd64/vmm/vmm.c
===================================================================
--- sys/amd64/vmm/vmm.c
+++ sys/amd64/vmm/vmm.c
@@ -162,6 +162,11 @@
struct vmspace *vmspace; /* (o) guest's address space */
char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
struct vcpu vcpu[VM_MAXCPU]; /* (i) guest vcpus */
+ /* The following describe the vm cpu topology */
+ uint64_t sockets; /* (o) number of sockets */
+ uint64_t cores; /* (o) number of cores/socket */
+ uint64_t threads; /* (o) number of threads/core */
+ uint64_t maxcpus; /* (o) max pluggable cpus */
};
static int vmm_initialized;
@@ -419,6 +424,9 @@
vcpu_init(vm, i, create);
}
+extern u_int cores_per_package;
+extern u_int threads_per_core;
+
int
vm_create(const char *name, struct vm **retvm)
{
@@ -443,6 +451,10 @@
strcpy(vm->name, name);
vm->vmspace = vmspace;
mtx_init(&vm->rendezvous_mtx, "vm rendezvous lock", 0, MTX_DEF);
+ vm->sockets=1; /* XXX not implemented */
+ vm->cores=cores_per_package; /* XXX should come from userland */
+ vm->threads=threads_per_core; /* XXX should come from userland */
+ vm->maxcpus=0; /* XXX not implemented */
vm_init(vm, true);
@@ -450,6 +462,26 @@
return (0);
}
+void
+vm_get_topology(struct vm *vm, uint64_t *sockets, uint64_t *cores,
+ uint64_t *threads, uint64_t *maxcpus)
+{
+ *sockets=vm->sockets;
+ *cores=vm->cores;
+ *threads=vm->threads;
+ *maxcpus=vm->maxcpus;
+}
+
+void
+vm_set_topology(struct vm *vm, uint64_t *sockets, uint64_t *cores,
+ uint64_t *threads, uint64_t *maxcpus)
+{
+ vm->sockets=*sockets;
+ vm->cores=*cores;
+ vm->threads=*threads;
+ vm->maxcpus=*maxcpus;
+}
+
static void
vm_cleanup(struct vm *vm, bool destroy)
{
Index: sys/amd64/vmm/vmm_dev.c
===================================================================
--- sys/amd64/vmm/vmm_dev.c
+++ sys/amd64/vmm/vmm_dev.c
@@ -313,6 +313,7 @@
struct vm_rtc_time *rtctime;
struct vm_rtc_data *rtcdata;
struct vm_memmap *mm;
+ struct vm_cpu_topology *topology;
sc = vmmdev_lookup2(cdev);
if (sc == NULL)
@@ -640,6 +641,13 @@
case VM_RESTART_INSTRUCTION:
error = vm_restart_instruction(sc->vm, vcpu);
break;
+ case VM_SET_TOPOLOGY:
+ topology = (struct vm_cpu_topology *)data;
+ vm_set_topology(sc->vm, &topology->sockets, &topology->cores, &topology->threads, &topology->maxcpus);
+ break;
+ case VM_GET_TOPOLOGY:
+ break;
+
default:
error = ENOTTY;
break;
Index: sys/amd64/vmm/x86.c
===================================================================
--- sys/amd64/vmm/x86.c
+++ sys/amd64/vmm/x86.c
@@ -61,12 +61,12 @@
/*
* The default CPU topology is a single thread per package.
*/
-static u_int threads_per_core = 1;
-SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RDTUN,
+u_int threads_per_core = 1;
+SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RW,
&threads_per_core, 0, NULL);
-static u_int cores_per_package = 1;
-SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, cores_per_package, CTLFLAG_RDTUN,
+u_int cores_per_package = 1;
+SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, cores_per_package, CTLFLAG_RW,
&cores_per_package, 0, NULL);
static int cpuid_leaf_b = 1;
@@ -89,7 +89,7 @@
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
const struct xsave_limits *limits;
- uint64_t cr4;
+ uint64_t cores, cr4, maxcpus, sockets, threads;
int error, enable_invpcid, level, width, x2apic_id;
unsigned int func, regs[4], logical_cpus;
enum x2apic_state x2apic_state;
@@ -140,11 +140,12 @@
*
* However this matches the logical cpus as
* advertised by leaf 0x1 and will work even
- * if the 'threads_per_core' tunable is set
- * incorrectly on an AMD host.
+ * if threads is set incorrectly on an AMD host.
*/
- logical_cpus = threads_per_core *
- cores_per_package;
+ vm_get_topology(vm, &sockets, &cores, &threads,
+ &maxcpus);
+ logical_cpus = threads *
+ cores;
regs[2] = logical_cpus - 1;
}
break;
@@ -300,7 +301,9 @@
*/
regs[3] |= (CPUID_MCA | CPUID_MCE | CPUID_MTRR);
- logical_cpus = threads_per_core * cores_per_package;
+ vm_get_topology(vm, &sockets, &cores, &threads,
+ &maxcpus);
+ logical_cpus = threads * cores;
regs[1] &= ~CPUID_HTT_CORES;
regs[1] |= (logical_cpus & 0xff) << 16;
regs[3] |= CPUID_HTT;
@@ -310,8 +313,10 @@
cpuid_count(*eax, *ecx, regs);
if (regs[0] || regs[1] || regs[2] || regs[3]) {
+ vm_get_topology(vm, &sockets, &cores, &threads,
+ &maxcpus);
regs[0] &= 0x3ff;
- regs[0] |= (cores_per_package - 1) << 26;
+ regs[0] |= (cores - 1) << 26;
/*
* Cache topology:
* - L1 and L2 are shared only by the logical
@@ -319,10 +324,10 @@
* - L3 and above are shared by all logical
* processors in the package.
*/
- logical_cpus = threads_per_core;
+ logical_cpus = threads;
level = (regs[0] >> 5) & 0x7;
if (level >= 3)
- logical_cpus *= cores_per_package;
+ logical_cpus *= cores;
regs[0] |= (logical_cpus - 1) << 14;
}
break;
@@ -385,7 +390,9 @@
* Processor topology enumeration
*/
if (*ecx == 0) {
- logical_cpus = threads_per_core;
+ vm_get_topology(vm, &sockets, &cores, &threads,
+ &maxcpus);
+ logical_cpus = threads;
width = log2(logical_cpus);
level = CPUID_TYPE_SMT;
x2apic_id = vcpu_id;
@@ -392,8 +399,8 @@
}
if (*ecx == 1) {
- logical_cpus = threads_per_core *
- cores_per_package;
+ logical_cpus = threads *
+ cores;
width = log2(logical_cpus);
level = CPUID_TYPE_CORE;
x2apic_id = vcpu_id;
Index: usr.sbin/bhyve/bhyverun.c
===================================================================
--- usr.sbin/bhyve/bhyverun.c
+++ usr.sbin/bhyve/bhyverun.c
@@ -91,6 +91,11 @@
char *vmname;
int guest_ncpus;
+uint64_t sockets;
+uint64_t cores;
+uint64_t threads;
+uint64_t maxcpus;
+
char *guest_uuid_str;
static int guest_vmexit_on_hlt, guest_vmexit_on_pause;
@@ -163,6 +168,45 @@
}
static int
+topology_parse(const char *opt)
+{
+ char *cp, *str;
+ int i, tmp;
+
+ str = strdup(opt);
+ if ((cp = strchr(str, ',')) != NULL) {
+ for (i = 0; str; i++) {
+ if (sscanf(str, "cpus=%d", &tmp) == 1)
+ guest_ncpus = tmp;
+ else if (sscanf(str, "cores=%d", &tmp) == 1)
+ cores = tmp;
+ else if (sscanf(str, "threads=%d", &tmp) == 1)
+ threads = tmp;
+ else if (sscanf(str, "sockets=%d", &tmp) == 1)
+ sockets = tmp;
+ else if (sscanf(str, "maxcpus=%d", &tmp) == 1)
+ maxcpus = tmp;
+ else
+ return (-1);
+ if (cp == NULL)
+ str = NULL;
+ else {
+ str = ++cp;
+ cp = strchr(str, ',');
+ }
+ }
+ } else {
+ if (sscanf(str, "cpus=%d", &tmp) == 1)
+ guest_ncpus = tmp;
+ else if (sscanf(str, "%d", &tmp) == 1)
+ guest_ncpus = tmp;
+ else
+ return (-1);
+ }
+ return(0);
+}
+
+static int
pincpu_parse(const char *opt)
{
int vcpu, pcpu;
@@ -781,6 +825,7 @@
exit(1);
}
}
+ vm_set_topology(ctx, sockets, cores, threads, maxcpus);
return (ctx);
}
@@ -799,6 +844,8 @@
progname = basename(argv[0]);
gdb_port = 0;
guest_ncpus = 1;
+ sockets = cores = threads = 1;
+ maxcpus = 0;
memsize = 256 * MB;
mptgen = 1;
rtc_localtime = 1;
@@ -823,7 +870,10 @@
}
break;
case 'c':
- guest_ncpus = atoi(optarg);
+ if (topology_parse(optarg) !=0) {
+ errx(EX_USAGE, "invalid cpu topology "
+ "'%s'", optarg);
+ }
break;
case 'C':
memflags |= VM_MEM_F_INCORE;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 29, 8:56 AM (8 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35691581
Default Alt Text
D9930.id26094.diff (10 KB)
Attached To
Mode
D9930: Bhyve cpu topology control
Attached
Detach File
Event Timeline
Log In to Comment