x86.c (276349) | x86.c (276403) |
---|---|
1/*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: stable/10/sys/amd64/vmm/x86.c 276349 2014-12-28 21:27:13Z neel $ | 26 * $FreeBSD: stable/10/sys/amd64/vmm/x86.c 276403 2014-12-30 08:24:14Z neel $ |
27 */ 28 29#include <sys/cdefs.h> | 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: stable/10/sys/amd64/vmm/x86.c 276349 2014-12-28 21:27:13Z neel $"); | 30__FBSDID("$FreeBSD: stable/10/sys/amd64/vmm/x86.c 276403 2014-12-30 08:24:14Z neel $"); |
31 32#include <sys/param.h> 33#include <sys/pcpu.h> 34#include <sys/systm.h> 35#include <sys/cpuset.h> 36#include <sys/sysctl.h> 37 38#include <machine/clock.h> 39#include <machine/cpufunc.h> 40#include <machine/md_var.h> 41#include <machine/segments.h> 42#include <machine/specialreg.h> 43 44#include <machine/vmm.h> 45 46#include "vmm_host.h" | 31 32#include <sys/param.h> 33#include <sys/pcpu.h> 34#include <sys/systm.h> 35#include <sys/cpuset.h> 36#include <sys/sysctl.h> 37 38#include <machine/clock.h> 39#include <machine/cpufunc.h> 40#include <machine/md_var.h> 41#include <machine/segments.h> 42#include <machine/specialreg.h> 43 44#include <machine/vmm.h> 45 46#include "vmm_host.h" |
47#include "vmm_ktr.h" 48#include "vmm_util.h" |
|
47#include "x86.h" 48 49SYSCTL_DECL(_hw_vmm); 50static SYSCTL_NODE(_hw_vmm, OID_AUTO, topology, CTLFLAG_RD, 0, NULL); 51 52#define CPUID_VM_HIGH 0x40000000 53 54static const char bhyve_id[12] = "bhyve bhyve "; 55 56static uint64_t bhyve_xcpuids; | 49#include "x86.h" 50 51SYSCTL_DECL(_hw_vmm); 52static SYSCTL_NODE(_hw_vmm, OID_AUTO, topology, CTLFLAG_RD, 0, NULL); 53 54#define CPUID_VM_HIGH 0x40000000 55 56static const char bhyve_id[12] = "bhyve bhyve "; 57 58static uint64_t bhyve_xcpuids; |
59SYSCTL_ULONG(_hw_vmm, OID_AUTO, bhyve_xcpuids, CTLFLAG_RW, &bhyve_xcpuids, 0, 60 "Number of times an unknown cpuid leaf was accessed"); |
|
57 58/* 59 * The default CPU topology is a single thread per package. 60 */ 61static u_int threads_per_core = 1; 62SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RDTUN, 63 &threads_per_core, 0, NULL); 64 --- 21 unchanged lines hidden (view full) --- 86 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) 87{ 88 const struct xsave_limits *limits; 89 uint64_t cr4; 90 int error, enable_invpcid, level, width, x2apic_id; 91 unsigned int func, regs[4], logical_cpus; 92 enum x2apic_state x2apic_state; 93 | 61 62/* 63 * The default CPU topology is a single thread per package. 64 */ 65static u_int threads_per_core = 1; 66SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RDTUN, 67 &threads_per_core, 0, NULL); 68 --- 21 unchanged lines hidden (view full) --- 90 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) 91{ 92 const struct xsave_limits *limits; 93 uint64_t cr4; 94 int error, enable_invpcid, level, width, x2apic_id; 95 unsigned int func, regs[4], logical_cpus; 96 enum x2apic_state x2apic_state; 97 |
98 VCPU_CTR2(vm, vcpu_id, "cpuid %#x,%#x", *eax, *ecx); 99 |
|
94 /* 95 * Requests for invalid CPUID levels should map to the highest 96 * available level instead. 97 */ 98 if (cpu_exthigh != 0 && *eax >= 0x80000000) { 99 if (*eax > cpu_exthigh) 100 *eax = cpu_exthigh; 101 } else if (*eax >= 0x40000000) { --- 17 unchanged lines hidden (view full) --- 119 case CPUID_0000_0000: 120 case CPUID_0000_0002: 121 case CPUID_0000_0003: 122 case CPUID_8000_0000: 123 case CPUID_8000_0002: 124 case CPUID_8000_0003: 125 case CPUID_8000_0004: 126 case CPUID_8000_0006: | 100 /* 101 * Requests for invalid CPUID levels should map to the highest 102 * available level instead. 103 */ 104 if (cpu_exthigh != 0 && *eax >= 0x80000000) { 105 if (*eax > cpu_exthigh) 106 *eax = cpu_exthigh; 107 } else if (*eax >= 0x40000000) { --- 17 unchanged lines hidden (view full) --- 125 case CPUID_0000_0000: 126 case CPUID_0000_0002: 127 case CPUID_0000_0003: 128 case CPUID_8000_0000: 129 case CPUID_8000_0002: 130 case CPUID_8000_0003: 131 case CPUID_8000_0004: 132 case CPUID_8000_0006: |
133 cpuid_count(*eax, *ecx, regs); 134 break; |
|
127 case CPUID_8000_0008: 128 cpuid_count(*eax, *ecx, regs); | 135 case CPUID_8000_0008: 136 cpuid_count(*eax, *ecx, regs); |
137 if (vmm_is_amd()) { 138 /* 139 * XXX this might appear silly because AMD 140 * cpus don't have threads. 141 * 142 * However this matches the logical cpus as 143 * advertised by leaf 0x1 and will work even 144 * if the 'threads_per_core' tunable is set 145 * incorrectly on an AMD host. 146 */ 147 logical_cpus = threads_per_core * 148 cores_per_package; 149 regs[2] = logical_cpus - 1; 150 } |
|
129 break; 130 131 case CPUID_8000_0001: | 151 break; 152 153 case CPUID_8000_0001: |
154 cpuid_count(*eax, *ecx, regs); 155 |
|
132 /* | 156 /* |
157 * Hide SVM and Topology Extension features from guest. 158 */ 159 regs[2] &= ~(AMDID2_SVM | AMDID2_TOPOLOGY); 160 161 /* 162 * Don't advertise extended performance counter MSRs 163 * to the guest. 164 */ 165 regs[2] &= ~AMDID2_PCXC; 166 regs[2] &= ~AMDID2_PNXC; 167 regs[2] &= ~AMDID2_PTSCEL2I; 168 169 /* 170 * Don't advertise Instruction Based Sampling feature. 171 */ 172 regs[2] &= ~AMDID2_IBS; 173 174 /* NodeID MSR not available */ 175 regs[2] &= ~AMDID2_NODE_ID; 176 177 /* Don't advertise the OS visible workaround feature */ 178 regs[2] &= ~AMDID2_OSVW; 179 180 /* |
|
133 * Hide rdtscp/ia32_tsc_aux until we know how 134 * to deal with them. 135 */ | 181 * Hide rdtscp/ia32_tsc_aux until we know how 182 * to deal with them. 183 */ |
136 cpuid_count(*eax, *ecx, regs); | |
137 regs[3] &= ~AMDID_RDTSCP; 138 break; 139 140 case CPUID_8000_0007: | 184 regs[3] &= ~AMDID_RDTSCP; 185 break; 186 187 case CPUID_8000_0007: |
141 cpuid_count(*eax, *ecx, regs); | |
142 /* | 188 /* |
143 * If the host TSCs are not synchronized across 144 * physical cpus then we cannot advertise an 145 * invariant tsc to a vcpu. | 189 * AMD uses this leaf to advertise the processor's 190 * power monitoring and RAS capabilities. These 191 * features are hardware-specific and exposing 192 * them to a guest doesn't make a lot of sense. |
146 * | 193 * |
194 * Intel uses this leaf only to advertise the 195 * "Invariant TSC" feature with all other bits 196 * being reserved (set to zero). 197 */ 198 regs[0] = 0; 199 regs[1] = 0; 200 regs[2] = 0; 201 regs[3] = 0; 202 203 /* 204 * "Invariant TSC" can be advertised to the guest if: 205 * - host TSC frequency is invariant 206 * - host TSCs are synchronized across physical cpus 207 * |
|
147 * XXX This still falls short because the vcpu 148 * can observe the TSC moving backwards as it 149 * migrates across physical cpus. But at least 150 * it should discourage the guest from using the 151 * TSC to keep track of time. 152 */ | 208 * XXX This still falls short because the vcpu 209 * can observe the TSC moving backwards as it 210 * migrates across physical cpus. But at least 211 * it should discourage the guest from using the 212 * TSC to keep track of time. 213 */ |
153 if (!smp_tsc) 154 regs[3] &= ~AMDPM_TSC_INVARIANT; | 214 if (tsc_is_invariant && smp_tsc) 215 regs[3] |= AMDPM_TSC_INVARIANT; |
155 break; 156 157 case CPUID_0000_0001: 158 do_cpuid(1, regs); 159 160 error = vm_get_x2apic_state(vm, vcpu_id, &x2apic_state); 161 if (error) { 162 panic("x86_emulate_cpuid: error %d " --- 259 unchanged lines hidden --- | 216 break; 217 218 case CPUID_0000_0001: 219 do_cpuid(1, regs); 220 221 error = vm_get_x2apic_state(vm, vcpu_id, &x2apic_state); 222 if (error) { 223 panic("x86_emulate_cpuid: error %d " --- 259 unchanged lines hidden --- |