From owner-svn-src-head@FreeBSD.ORG Sun Aug 24 01:10:06 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D94D8538; Sun, 24 Aug 2014 01:10:06 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C619332F0; Sun, 24 Aug 2014 01:10:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7O1A6Qv062582; Sun, 24 Aug 2014 01:10:06 GMT (envelope-from neel@FreeBSD.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7O1A67G062581; Sun, 24 Aug 2014 01:10:06 GMT (envelope-from neel@FreeBSD.org) Message-Id: <201408240110.s7O1A67G062581@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: neel set sender to neel@FreeBSD.org using -f From: Neel Natu Date: Sun, 24 Aug 2014 01:10:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r270437 - head/sys/amd64/vmm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Aug 2014 01:10:07 -0000 Author: neel Date: Sun Aug 24 01:10:06 2014 New Revision: 270437 URL: http://svnweb.freebsd.org/changeset/base/270437 Log: Add "hw.vmm.topology.threads_per_core" and "hw.vmm.topology.cores_per_package" tunables to modify the default cpu topology advertised by bhyve. Also add a tunable "hw.vmm.topology.cpuid_leaf_b" to disable the CPUID leaf 0xb. This is intended for testing guest behavior when it falls back on using CPUID leaf 0x4 to deduce CPU topology. The default behavior is to advertise each vcpu as a core in a separate soket. Modified: head/sys/amd64/vmm/x86.c Modified: head/sys/amd64/vmm/x86.c ============================================================================== --- head/sys/amd64/vmm/x86.c Sat Aug 23 22:44:31 2014 (r270436) +++ head/sys/amd64/vmm/x86.c Sun Aug 24 01:10:06 2014 (r270437) @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -45,20 +46,49 @@ __FBSDID("$FreeBSD$"); #include "vmm_host.h" #include "x86.h" +SYSCTL_DECL(_hw_vmm); +static SYSCTL_NODE(_hw_vmm, OID_AUTO, topology, CTLFLAG_RD, 0, NULL); + #define CPUID_VM_HIGH 0x40000000 static const char bhyve_id[12] = "bhyve bhyve "; static uint64_t bhyve_xcpuids; +/* + * 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, + &threads_per_core, 0, NULL); + +static u_int cores_per_package = 1; +SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, cores_per_package, CTLFLAG_RDTUN, + &cores_per_package, 0, NULL); + +static int cpuid_leaf_b = 1; +SYSCTL_INT(_hw_vmm_topology, OID_AUTO, cpuid_leaf_b, CTLFLAG_RDTUN, + &cpuid_leaf_b, 0, NULL); + +/* + * Round up to the next power of two, if necessary, and then take log2. + * Returns -1 if argument is zero. + */ +static __inline int +log2(u_int x) +{ + + return (fls(x << (1 - powerof2(x))) - 1); +} + int x86_emulate_cpuid(struct vm *vm, int vcpu_id, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { const struct xsave_limits *limits; uint64_t cr4; - int error, enable_invpcid; - unsigned int func, regs[4]; + int error, enable_invpcid, level, width, x2apic_id; + unsigned int func, regs[4], logical_cpus; enum x2apic_state x2apic_state; /* @@ -207,30 +237,31 @@ x86_emulate_cpuid(struct vm *vm, int vcp */ regs[3] &= ~CPUID_DS; - /* - * Disable multi-core. - */ + logical_cpus = threads_per_core * cores_per_package; regs[1] &= ~CPUID_HTT_CORES; - regs[3] &= ~CPUID_HTT; + regs[1] |= (logical_cpus & 0xff) << 16; + regs[3] |= CPUID_HTT; break; case CPUID_0000_0004: cpuid_count(*eax, *ecx, regs); - /* - * Do not expose topology. - * - * The maximum number of processor cores in - * this physical processor package and the - * maximum number of threads sharing this - * cache are encoded with "plus 1" encoding. - * Adding one to the value in this register - * field to obtains the actual value. - * - * Therefore 0 for both indicates 1 core per - * package and no cache sharing. - */ - regs[0] &= 0x3ff; + if (regs[0] || regs[1] || regs[2] || regs[3]) { + regs[0] &= 0x3ff; + regs[0] |= (cores_per_package - 1) << 26; + /* + * Cache topology: + * - L1 and L2 are shared only by the logical + * processors in a single core. + * - L3 and above are shared by all logical + * processors in the package. + */ + logical_cpus = threads_per_core; + level = (regs[0] >> 5) & 0x7; + if (level >= 3) + logical_cpus *= cores_per_package; + regs[0] |= (logical_cpus - 1) << 14; + } break; case CPUID_0000_0007: @@ -284,10 +315,32 @@ x86_emulate_cpuid(struct vm *vm, int vcp /* * Processor topology enumeration */ - regs[0] = 0; - regs[1] = 0; - regs[2] = *ecx & 0xff; - regs[3] = vcpu_id; + if (*ecx == 0) { + logical_cpus = threads_per_core; + width = log2(logical_cpus); + level = CPUID_TYPE_SMT; + x2apic_id = vcpu_id; + } + + if (*ecx == 1) { + logical_cpus = threads_per_core * + cores_per_package; + width = log2(logical_cpus); + level = CPUID_TYPE_CORE; + x2apic_id = vcpu_id; + } + + if (!cpuid_leaf_b || *ecx >= 2) { + width = 0; + logical_cpus = 0; + level = 0; + x2apic_id = 0; + } + + regs[0] = width & 0x1f; + regs[1] = logical_cpus & 0xffff; + regs[2] = (level << 8) | (*ecx & 0xff); + regs[3] = x2apic_id; break; case CPUID_0000_000D: