6
6
* Copyright (c) 2008, Citrix Systems, Inc.
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms and conditions of the GNU General Public License,
10
* version 2, as published by the Free Software Foundation.
12
* This program is distributed in the hope it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
* You should have received a copy of the GNU General Public License along with
18
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19
* Place - Suite 330, Boston, MA 02111-1307 USA.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation;
11
* version 2.1 of the License.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
23
#include <stdlib.h>
31
32
#define DEF_MAX_BASE 0x0000000du
32
33
#define DEF_MAX_EXT 0x80000008u
34
static int hypervisor_is_64bit(int xc)
35
static int hypervisor_is_64bit(xc_interface *xch)
36
37
xen_capabilities_info_t xen_caps = "";
37
return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
38
return ((xc_version(xch, XENVER_capabilities, &xen_caps) == 0) &&
38
39
(strstr(xen_caps, "x86_64") != NULL));
77
78
static void amd_xc_cpuid_policy(
78
int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
79
xc_interface *xch, domid_t domid,
80
const unsigned int *input, unsigned int *regs,
81
83
switch ( input[0] )
95
97
/* Filter all other features according to a whitelist. */
96
98
regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) |
97
99
bitmaskof(X86_FEATURE_CMP_LEGACY) |
98
bitmaskof(X86_FEATURE_ALTMOVCR) |
100
bitmaskof(X86_FEATURE_CR8_LEGACY) |
99
101
bitmaskof(X86_FEATURE_ABM) |
100
102
bitmaskof(X86_FEATURE_SSE4A) |
101
103
bitmaskof(X86_FEATURE_MISALIGNSSE) |
102
bitmaskof(X86_FEATURE_3DNOWPF));
104
bitmaskof(X86_FEATURE_3DNOWPREFETCH) |
105
bitmaskof(X86_FEATURE_XOP) |
106
bitmaskof(X86_FEATURE_FMA4) |
107
bitmaskof(X86_FEATURE_TBM));
103
108
regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
104
109
(is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
105
110
(is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
125
130
static void intel_xc_cpuid_policy(
126
int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
131
xc_interface *xch, domid_t domid,
132
const unsigned int *input, unsigned int *regs,
129
135
switch ( input[0] )
170
#define XSAVEOPT (1 << 0)
171
/* Configure extended state enumeration leaves (0x0000000D for xsave) */
172
static void xc_cpuid_config_xsave(
173
xc_interface *xch, domid_t domid, uint64_t xfeature_mask,
174
const unsigned int *input, unsigned int *regs)
176
if ( xfeature_mask == 0 )
178
regs[0] = regs[1] = regs[2] = regs[3] = 0;
185
/* EAX: low 32bits of xfeature_enabled_mask */
186
regs[0] = xfeature_mask & 0xFFFFFFFF;
187
/* EDX: high 32bits of xfeature_enabled_mask */
188
regs[3] = (xfeature_mask >> 32) & 0xFFFFFFFF;
189
/* ECX: max size required by all HW features */
191
unsigned int _input[2] = {0xd, 0x0}, _regs[4];
193
for ( _input[1] = 2; _input[1] < 64; _input[1]++ )
195
cpuid(_input, _regs);
196
if ( (_regs[0] + _regs[1]) > regs[2] )
197
regs[2] = _regs[0] + _regs[1];
200
/* EBX: max size required by enabled features.
201
* This register contains a dynamic value, which varies when a guest
202
* enables or disables XSTATE features (via xsetbv). The default size
203
* after reset is 576. */
204
regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
208
regs[1] = regs[2] = regs[3] = 0;
210
case 2 ... 63: /* sub-leaves */
211
if ( !(xfeature_mask & (1ULL << input[1])) )
213
regs[0] = regs[1] = regs[2] = regs[3] = 0;
216
/* Don't touch EAX, EBX. Also cleanup ECX and EDX */
217
regs[2] = regs[3] = 0;
164
222
static void xc_cpuid_hvm_policy(
165
int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
223
xc_interface *xch, domid_t domid,
224
const unsigned int *input, unsigned int *regs)
168
228
unsigned long pae;
230
uint64_t xfeature_mask;
171
xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
232
xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae);
235
/* Detecting Xen's atitude towards XSAVE */
236
memset(&domctl, 0, sizeof(domctl));
237
domctl.cmd = XEN_DOMCTL_getvcpuextstate;
238
domctl.domain = domid;
239
do_domctl(xch, &domctl);
240
xfeature_mask = domctl.u.vcpuextstate.xfeature_mask;
174
242
switch ( input[0] )
186
254
regs[1] = (regs[1] & 0x0000ffffu) | ((regs[1] & 0x007f0000u) << 1);
188
256
regs[2] &= (bitmaskof(X86_FEATURE_XMM3) |
257
bitmaskof(X86_FEATURE_PCLMULQDQ) |
189
258
bitmaskof(X86_FEATURE_SSSE3) |
190
259
bitmaskof(X86_FEATURE_CX16) |
191
260
bitmaskof(X86_FEATURE_SSE4_1) |
192
261
bitmaskof(X86_FEATURE_SSE4_2) |
193
262
bitmaskof(X86_FEATURE_POPCNT) |
194
bitmaskof(X86_FEATURE_AES));
263
bitmaskof(X86_FEATURE_AES) |
264
bitmaskof(X86_FEATURE_F16C) |
265
((xfeature_mask != 0) ?
266
(bitmaskof(X86_FEATURE_AVX) |
267
bitmaskof(X86_FEATURE_XSAVE)) : 0));
196
regs[2] |= bitmaskof(X86_FEATURE_HYPERVISOR);
269
regs[2] |= (bitmaskof(X86_FEATURE_HYPERVISOR) |
270
bitmaskof(X86_FEATURE_TSC_DEADLINE) |
271
bitmaskof(X86_FEATURE_X2APIC));
198
273
regs[3] &= (bitmaskof(X86_FEATURE_FPU) |
199
274
bitmaskof(X86_FEATURE_VME) |
266
345
xc_cpuid_brand_get(brand);
267
346
if ( strstr(brand, "AMD") )
268
amd_xc_cpuid_policy(xc, domid, input, regs, is_pae);
347
amd_xc_cpuid_policy(xch, domid, input, regs, is_pae);
270
intel_xc_cpuid_policy(xc, domid, input, regs, is_pae);
349
intel_xc_cpuid_policy(xch, domid, input, regs, is_pae);
274
353
static void xc_cpuid_pv_policy(
275
int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
354
xc_interface *xch, domid_t domid,
355
const unsigned int *input, unsigned int *regs)
278
int guest_64bit, xen_64bit = hypervisor_is_64bit(xc);
358
int guest_64bit, xsave_supported, xen_64bit = hypervisor_is_64bit(xch);
281
361
xc_cpuid_brand_get(brand);
283
363
memset(&domctl, 0, sizeof(domctl));
284
364
domctl.domain = domid;
285
365
domctl.cmd = XEN_DOMCTL_get_address_size;
286
do_domctl(xc, &domctl);
366
do_domctl(xch, &domctl);
287
367
guest_64bit = (domctl.u.address_size.size == 64);
369
/* Detecting Xen's atitude towards XSAVE */
370
memset(&domctl, 0, sizeof(domctl));
371
domctl.cmd = XEN_DOMCTL_getvcpuextstate;
372
domctl.domain = domid;
373
do_domctl(xch, &domctl);
374
xsave_supported = (domctl.u.vcpuextstate.xfeature_mask != 0);
289
376
if ( (input[0] & 0x7fffffff) == 1 )
291
378
clear_bit(X86_FEATURE_VME, regs[3]);
315
402
clear_bit(X86_FEATURE_TM2, regs[2]);
316
403
if ( !guest_64bit )
317
404
clear_bit(X86_FEATURE_CX16, regs[2]);
405
if ( !xsave_supported )
407
clear_bit(X86_FEATURE_XSAVE, regs[2]);
408
clear_bit(X86_FEATURE_AVX, regs[2]);
318
410
clear_bit(X86_FEATURE_XTPR, regs[2]);
319
411
clear_bit(X86_FEATURE_PDCM, regs[2]);
320
412
clear_bit(X86_FEATURE_DCA, regs[2]);
321
clear_bit(X86_FEATURE_XSAVE, regs[2]);
322
413
set_bit(X86_FEATURE_HYPERVISOR, regs[2]);
336
427
clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
337
428
clear_bit(X86_FEATURE_RDTSCP, regs[3]);
339
clear_bit(X86_FEATURE_SVME, regs[2]);
430
clear_bit(X86_FEATURE_SVM, regs[2]);
340
431
clear_bit(X86_FEATURE_OSVW, regs[2]);
341
432
clear_bit(X86_FEATURE_IBS, regs[2]);
342
433
clear_bit(X86_FEATURE_SKINIT, regs[2]);
343
434
clear_bit(X86_FEATURE_WDT, regs[2]);
435
clear_bit(X86_FEATURE_LWP, regs[2]);
436
clear_bit(X86_FEATURE_NODEID_MSR, regs[2]);
437
clear_bit(X86_FEATURE_TOPOEXT, regs[2]);
345
439
case 5: /* MONITOR/MWAIT */
346
440
case 0xa: /* Architectural Performance Monitor Features */
441
case 0xd: /* XSAVE */
347
442
case 0x8000000a: /* SVM revision and features */
348
443
case 0x8000001b: /* Instruction Based Sampling */
444
case 0x8000001c: /* Light Weight Profiling */
445
case 0x8000001e: /* Extended topology reporting */
349
446
regs[0] = regs[1] = regs[2] = regs[3] = 0;
354
451
static int xc_cpuid_policy(
355
int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
452
xc_interface *xch, domid_t domid,
453
const unsigned int *input, unsigned int *regs)
357
455
xc_dominfo_t info;
359
if ( xc_domain_getinfo(xc, domid, 1, &info) == 0 )
457
if ( xc_domain_getinfo(xch, domid, 1, &info) == 0 )
363
xc_cpuid_hvm_policy(xc, domid, input, regs);
461
xc_cpuid_hvm_policy(xch, domid, input, regs);
365
xc_cpuid_pv_policy(xc, domid, input, regs);
463
xc_cpuid_pv_policy(xch, domid, input, regs);
370
468
static int xc_cpuid_do_domctl(
371
int xc, domid_t domid,
469
xc_interface *xch, domid_t domid,
372
470
const unsigned int *input, const unsigned int *regs)
408
int xc_cpuid_apply_policy(int xc, domid_t domid)
506
int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
410
508
unsigned int input[2] = { 0, 0 }, regs[4];
411
509
unsigned int base_max, ext_max;
424
522
cpuid(input, regs);
425
xc_cpuid_policy(xc, domid, input, regs);
523
xc_cpuid_policy(xch, domid, input, regs);
427
525
if ( regs[0] || regs[1] || regs[2] || regs[3] )
429
rc = xc_cpuid_do_domctl(xc, domid, input, regs);
527
rc = xc_cpuid_do_domctl(xch, domid, input, regs);
433
/* Intel cache descriptor leaves. */
437
/* More to do? Then loop keeping %%eax==0x00000004. */
438
if ( (regs[0] & 0x1f) != 0 )
532
/* Intel cache descriptor leaves. */
536
/* More to do? Then loop keeping %%eax==0x00000004. */
537
if ( (regs[0] & 0x1f) != 0 )
541
/* XSAVE information, subleaves 0-63. */
542
if ( (input[0] == 0xd) && (input[1]++ < 63) )
444
input[1] = (input[0] == 4) ? 0 : XEN_CPUID_INPUT_UNUSED;
445
546
if ( !(input[0] & 0x80000000u) && (input[0] > base_max ) )
446
547
input[0] = 0x80000000u;
549
input[1] = XEN_CPUID_INPUT_UNUSED;
550
if ( (input[0] == 4) || (input[0] == 0xd) )
448
553
if ( (input[0] & 0x80000000u) && (input[0] > ext_max) )
522
627
* For 's' and 'x' the configuration is overwritten with the value applied.
524
629
int xc_cpuid_set(
525
int xc, domid_t domid, const unsigned int *input,
630
xc_interface *xch, domid_t domid, const unsigned int *input,
526
631
const char **config, char **config_transformed)
533
638
cpuid(input, regs);
535
640
memcpy(polregs, regs, sizeof(regs));
536
xc_cpuid_policy(xc, domid, input, polregs);
641
xc_cpuid_policy(xch, domid, input, polregs);
538
643
for ( i = 0; i < 4; i++ )