Deleted Added
full compact
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 ---