~ressu/+junk/xen-debian

« back to all changes in this revision

Viewing changes to tools/libxc/xc_cpuid_x86.c

  • Committer: sami at haahtinen
  • Author(s): Bastian Blank
  • Date: 2011-03-17 14:12:45 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: sami@haahtinen.name-20110317141245-owgqox0l0p3g5857
Tags: 4.1.0~rc6-1
* New upstream release candidate.
* Build documentation using pdflatex.
* Use python 2.6. (closes: #596545)
* Fix lintian override.
* Install new tools: xl, xenpaging.
* Enable blktap2.
  - Use own md5 implementation.
  - Fix includes.
  - Fix linking of blktap2 binaries.
  - Remove optimization setting.
* Temporarily disable hvmloader, wants to download ipxe.
* Remove xenstored pid check from xl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * Copyright (c) 2008, Citrix Systems, Inc.
7
7
 *
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.
11
 
 *
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
15
 
 * more details.
16
 
 *
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.
 
12
 *
 
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.
 
17
 *
 
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
20
21
 */
21
22
 
22
23
#include <stdlib.h>
31
32
#define DEF_MAX_BASE 0x0000000du
32
33
#define DEF_MAX_EXT  0x80000008u
33
34
 
34
 
static int hypervisor_is_64bit(int xc)
 
35
static int hypervisor_is_64bit(xc_interface *xch)
35
36
{
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));
39
40
}
40
41
 
75
76
}
76
77
 
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,
79
81
    int is_pae)
80
82
{
81
83
    switch ( input[0] )
86
88
        break;
87
89
 
88
90
    case 0x80000001: {
89
 
        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
 
91
        int is_64bit = hypervisor_is_64bit(xch) && is_pae;
90
92
 
91
93
        if ( !is_pae )
92
94
            clear_bit(X86_FEATURE_PAE, regs[3]);
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) |
123
128
}
124
129
 
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,
127
133
    int is_pae)
128
134
{
129
135
    switch ( input[0] )
139
145
        break;
140
146
 
141
147
    case 0x80000001: {
142
 
        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
 
148
        int is_64bit = hypervisor_is_64bit(xch) && is_pae;
143
149
 
144
150
        /* Only a few features are advertised in Intel's 0x80000001. */
145
151
        regs[2] &= (is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0);
161
167
    }
162
168
}
163
169
 
 
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)
 
175
{
 
176
    if ( xfeature_mask == 0 )
 
177
    {
 
178
        regs[0] = regs[1] = regs[2] = regs[3] = 0;
 
179
        return;
 
180
    }
 
181
 
 
182
    switch ( input[1] )
 
183
    {
 
184
    case 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 */
 
190
        {
 
191
            unsigned int _input[2] = {0xd, 0x0}, _regs[4];
 
192
            regs[2] = 0;
 
193
            for ( _input[1] = 2; _input[1] < 64; _input[1]++ )
 
194
            {
 
195
                cpuid(_input, _regs);
 
196
                if ( (_regs[0] + _regs[1]) > regs[2] )
 
197
                    regs[2] = _regs[0] + _regs[1];
 
198
            }
 
199
        }
 
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 */
 
205
        break;
 
206
    case 1: /* leaf 1 */
 
207
        regs[0] &= XSAVEOPT;
 
208
        regs[1] = regs[2] = regs[3] = 0;
 
209
        break;
 
210
    case 2 ... 63: /* sub-leaves */
 
211
        if ( !(xfeature_mask & (1ULL << input[1])) )
 
212
        {
 
213
            regs[0] = regs[1] = regs[2] = regs[3] = 0;
 
214
            break;
 
215
        }
 
216
        /* Don't touch EAX, EBX. Also cleanup ECX and EDX */
 
217
        regs[2] = regs[3] = 0;
 
218
        break;
 
219
    }
 
220
}
 
221
 
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)
166
225
{
 
226
    DECLARE_DOMCTL;
167
227
    char brand[13];
168
228
    unsigned long pae;
169
229
    int is_pae;
 
230
    uint64_t xfeature_mask;
170
231
 
171
 
    xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
 
232
    xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae);
172
233
    is_pae = !!pae;
173
234
 
 
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;
 
241
 
174
242
    switch ( input[0] )
175
243
    {
176
244
    case 0x00000000:
186
254
        regs[1] = (regs[1] & 0x0000ffffu) | ((regs[1] & 0x007f0000u) << 1);
187
255
 
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));
195
268
 
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));
197
272
 
198
273
        regs[3] &= (bitmaskof(X86_FEATURE_FPU) |
199
274
                    bitmaskof(X86_FEATURE_VME) |
225
300
            clear_bit(X86_FEATURE_PAE, regs[3]);
226
301
        break;
227
302
 
 
303
    case 0x0000000d:
 
304
        xc_cpuid_config_xsave(xch, domid, xfeature_mask, input, regs);
 
305
        break;
 
306
 
228
307
    case 0x80000000:
229
308
        if ( regs[0] > DEF_MAX_EXT )
230
309
            regs[0] = DEF_MAX_EXT;
265
344
 
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);
269
348
    else
270
 
        intel_xc_cpuid_policy(xc, domid, input, regs, is_pae);
 
349
        intel_xc_cpuid_policy(xch, domid, input, regs, is_pae);
271
350
 
272
351
}
273
352
 
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)
276
356
{
277
357
    DECLARE_DOMCTL;
278
 
    int guest_64bit, xen_64bit = hypervisor_is_64bit(xc);
 
358
    int guest_64bit, xsave_supported, xen_64bit = hypervisor_is_64bit(xch);
279
359
    char brand[13];
280
360
 
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);
288
368
 
 
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);
 
375
 
289
376
    if ( (input[0] & 0x7fffffff) == 1 )
290
377
    {
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 )
 
406
        {
 
407
            clear_bit(X86_FEATURE_XSAVE, regs[2]);
 
408
            clear_bit(X86_FEATURE_AVX, regs[2]);
 
409
        }
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]);
323
414
        break;
324
415
    case 0x80000001:
336
427
        clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
337
428
        clear_bit(X86_FEATURE_RDTSCP, regs[3]);
338
429
 
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]);
344
438
        break;
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;
350
447
        break;
351
448
    }
352
449
}
353
450
 
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)
356
454
{
357
455
    xc_dominfo_t        info;
358
456
 
359
 
    if ( xc_domain_getinfo(xc, domid, 1, &info) == 0 )
 
457
    if ( xc_domain_getinfo(xch, domid, 1, &info) == 0 )
360
458
        return -EINVAL;
361
459
 
362
460
    if ( info.hvm )
363
 
        xc_cpuid_hvm_policy(xc, domid, input, regs);
 
461
        xc_cpuid_hvm_policy(xch, domid, input, regs);
364
462
    else
365
 
        xc_cpuid_pv_policy(xc, domid, input, regs);
 
463
        xc_cpuid_pv_policy(xch, domid, input, regs);
366
464
 
367
465
    return 0;
368
466
}
369
467
 
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)
373
471
{
374
472
    DECLARE_DOMCTL;
383
481
    domctl.u.cpuid.ecx = regs[2];
384
482
    domctl.u.cpuid.edx = regs[3];
385
483
 
386
 
    return do_domctl(xc, &domctl);
 
484
    return do_domctl(xch, &domctl);
387
485
}
388
486
 
389
487
static char *alloc_str(void)
405
503
    }
406
504
}
407
505
 
408
 
int xc_cpuid_apply_policy(int xc, domid_t domid)
 
506
int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
409
507
{
410
508
    unsigned int input[2] = { 0, 0 }, regs[4];
411
509
    unsigned int base_max, ext_max;
422
520
    for ( ; ; )
423
521
    {
424
522
        cpuid(input, regs);
425
 
        xc_cpuid_policy(xc, domid, input, regs);
 
523
        xc_cpuid_policy(xch, domid, input, regs);
426
524
 
427
525
        if ( regs[0] || regs[1] || regs[2] || regs[3] )
428
526
        {
429
 
            rc = xc_cpuid_do_domctl(xc, domid, input, regs);
 
527
            rc = xc_cpuid_do_domctl(xch, domid, input, regs);
430
528
            if ( rc )
431
529
                return rc;
432
 
 
433
 
            /* Intel cache descriptor leaves. */
434
 
            if ( input[0] == 4 )
435
 
            {
436
 
                input[1]++;
437
 
                /* More to do? Then loop keeping %%eax==0x00000004. */
438
 
                if ( (regs[0] & 0x1f) != 0 )
439
 
                    continue;
440
 
            }
441
 
        }
 
530
        }
 
531
 
 
532
        /* Intel cache descriptor leaves. */
 
533
        if ( input[0] == 4 )
 
534
        {
 
535
            input[1]++;
 
536
            /* More to do? Then loop keeping %%eax==0x00000004. */
 
537
            if ( (regs[0] & 0x1f) != 0 )
 
538
                continue;
 
539
        }
 
540
 
 
541
        /* XSAVE information, subleaves 0-63. */
 
542
        if ( (input[0] == 0xd) && (input[1]++ < 63) )
 
543
            continue;
442
544
 
443
545
        input[0]++;
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;
447
548
 
 
549
        input[1] = XEN_CPUID_INPUT_UNUSED;
 
550
        if ( (input[0] == 4) || (input[0] == 0xd) )
 
551
            input[1] = 0;
 
552
 
448
553
        if ( (input[0] & 0x80000000u) && (input[0] > ext_max) )
449
554
            break;
450
555
    }
462
567
 *  's' -> (same) must be the same
463
568
 */
464
569
int xc_cpuid_check(
465
 
    int xc, const unsigned int *input,
 
570
    xc_interface *xch, const unsigned int *input,
466
571
    const char **config,
467
572
    char **config_transformed)
468
573
{
522
627
 * For 's' and 'x' the configuration is overwritten with the value applied.
523
628
 */
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)
527
632
{
528
633
    int rc;
533
638
    cpuid(input, regs);
534
639
 
535
640
    memcpy(polregs, regs, sizeof(regs));
536
 
    xc_cpuid_policy(xc, domid, input, polregs);
 
641
    xc_cpuid_policy(xch, domid, input, polregs);
537
642
 
538
643
    for ( i = 0; i < 4; i++ )
539
644
    {
572
677
        }
573
678
    }
574
679
 
575
 
    rc = xc_cpuid_do_domctl(xc, domid, input, regs);
 
680
    rc = xc_cpuid_do_domctl(xch, domid, input, regs);
576
681
    if ( rc == 0 )
577
682
        return 0;
578
683