Coverage Report

Created: 2026-05-14 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xen/tools/include/xen/lib/x86/cpu-policy.h
Line
Count
Source
1
/* Common data structures and functions consumed by hypervisor and toolstack */
2
#ifndef XEN_LIB_X86_POLICIES_H
3
#define XEN_LIB_X86_POLICIES_H
4
5
#include <xen/lib/x86/cpuid-autogen.h>
6
7
0
#define FEATURESET_1d         0 /* 0x00000001.edx      */
8
0
#define FEATURESET_1c         1 /* 0x00000001.ecx      */
9
0
#define FEATURESET_e1d        2 /* 0x80000001.edx      */
10
0
#define FEATURESET_e1c        3 /* 0x80000001.ecx      */
11
0
#define FEATURESET_Da1        4 /* 0x0000000d:1.eax    */
12
0
#define FEATURESET_7b0        5 /* 0x00000007:0.ebx    */
13
0
#define FEATURESET_7c0        6 /* 0x00000007:0.ecx    */
14
0
#define FEATURESET_e7d        7 /* 0x80000007.edx      */
15
0
#define FEATURESET_e8b        8 /* 0x80000008.ebx      */
16
0
#define FEATURESET_7d0        9 /* 0x00000007:0.edx    */
17
0
#define FEATURESET_7a1       10 /* 0x00000007:1.eax    */
18
0
#define FEATURESET_e21a      11 /* 0x80000021.eax      */
19
0
#define FEATURESET_7b1       12 /* 0x00000007:1.ebx    */
20
0
#define FEATURESET_7d2       13 /* 0x00000007:2.edx    */
21
0
#define FEATURESET_7c1       14 /* 0x00000007:1.ecx    */
22
0
#define FEATURESET_7d1       15 /* 0x00000007:1.edx    */
23
0
#define FEATURESET_m10Al     16 /* 0x0000010a.eax      */
24
0
#define FEATURESET_m10Ah     17 /* 0x0000010a.edx      */
25
0
#define FEATURESET_e21c      18 /* 0x80000021.ecx      */
26
27
struct cpuid_leaf
28
{
29
    uint32_t a, b, c, d;
30
};
31
32
static inline void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *l)
33
88
{
34
88
    asm ( "cpuid"
35
88
          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
36
88
          : "a" (leaf) );
37
88
}
Unexecuted instantiation: fuzz-emul.c:cpuid_leaf
Unexecuted instantiation: x86-emulate.c:cpuid_leaf
Unexecuted instantiation: 0f01.c:cpuid_leaf
Unexecuted instantiation: 0fae.c:cpuid_leaf
Unexecuted instantiation: 0fc7.c:cpuid_leaf
Unexecuted instantiation: decode.c:cpuid_leaf
Unexecuted instantiation: fpu.c:cpuid_leaf
cpuid.c:cpuid_leaf
Line
Count
Source
33
88
{
34
88
    asm ( "cpuid"
35
88
          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
36
88
          : "a" (leaf) );
37
88
}
Unexecuted instantiation: wrappers.c:cpuid_leaf
38
39
static inline void cpuid_count_leaf(
40
    uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *l)
41
14
{
42
14
    asm ( "cpuid"
43
14
          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
44
14
          : "a" (leaf), "c" (subleaf) );
45
14
}
Unexecuted instantiation: fuzz-emul.c:cpuid_count_leaf
Unexecuted instantiation: x86-emulate.c:cpuid_count_leaf
Unexecuted instantiation: 0f01.c:cpuid_count_leaf
Unexecuted instantiation: 0fae.c:cpuid_count_leaf
Unexecuted instantiation: 0fc7.c:cpuid_count_leaf
Unexecuted instantiation: decode.c:cpuid_count_leaf
Unexecuted instantiation: fpu.c:cpuid_count_leaf
cpuid.c:cpuid_count_leaf
Line
Count
Source
41
14
{
42
14
    asm ( "cpuid"
43
14
          : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
44
14
          : "a" (leaf), "c" (subleaf) );
45
14
}
Unexecuted instantiation: wrappers.c:cpuid_count_leaf
46
47
#undef BX_CON
48
#undef XCHG
49
50
/**
51
 * Given the vendor id from CPUID leaf 0, look up Xen's internal integer
52
 * vendor ID.  Returns X86_VENDOR_UNKNOWN for any unknown vendor.
53
 */
54
unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx);
55
56
/**
57
 * Given Xen's internal vendor ID, return a string suitable for printing.
58
 * Returns "Unknown" for any unrecognised ID.
59
 */
60
const char *x86_cpuid_vendor_to_str(unsigned int vendor);
61
62
#define CPUID_GUEST_NR_BASIC      (0xdu + 1)
63
#define CPUID_GUEST_NR_CACHE      (5u + 1)
64
#define CPUID_GUEST_NR_FEAT       (2u + 1)
65
#define CPUID_GUEST_NR_TOPO       (1u + 1)
66
#define CPUID_GUEST_NR_XSTATE     (62u + 1)
67
#define CPUID_GUEST_NR_EXTD_INTEL (0x8u + 1)
68
#define CPUID_GUEST_NR_EXTD_AMD   (0x21u + 1)
69
#define CPUID_GUEST_NR_EXTD       MAX(CPUID_GUEST_NR_EXTD_INTEL, \
70
                                      CPUID_GUEST_NR_EXTD_AMD)
71
72
/*
73
 * Maximum number of leaves a struct cpu_policy turns into when serialised for
74
 * interaction with the toolstack.  (Sum of all leaves in each union, less the
75
 * entries in basic which sub-unions hang off of.)
76
 */
77
#define CPUID_MAX_SERIALISED_LEAVES             \
78
    (CPUID_GUEST_NR_BASIC +                     \
79
     CPUID_GUEST_NR_FEAT   - 1 +                \
80
     CPUID_GUEST_NR_CACHE  - 1 +                \
81
     CPUID_GUEST_NR_TOPO   - 1 +                \
82
     CPUID_GUEST_NR_XSTATE - 1 +                \
83
     CPUID_GUEST_NR_EXTD +                      \
84
     2 /* hv_limit and hv2_limit */ )
85
86
/* Maximum number of MSRs written when serialising a cpu_policy. */
87
#define MSR_MAX_SERIALISED_ENTRIES 2
88
89
struct cpu_policy
90
{
91
#define DECL_BITFIELD(word) _DECL_BITFIELD(FEATURESET_ ## word)
92
#define _DECL_BITFIELD(x)   __DECL_BITFIELD(x)
93
#define __DECL_BITFIELD(x)  CPUID_BITFIELD_ ## x
94
95
    /* Basic leaves: 0x000000xx */
96
    union {
97
        struct cpuid_leaf raw[CPUID_GUEST_NR_BASIC];
98
        struct {
99
            /* Leaf 0x0 - Max and vendor. */
100
            uint32_t max_leaf, vendor_ebx, vendor_ecx, vendor_edx;
101
102
            /* Leaf 0x1 - Family/model/stepping and features. */
103
            uint32_t raw_fms;
104
            uint8_t :8,       /* Brand ID. */
105
                clflush_size, /* Number of 8-byte blocks per cache line. */
106
                lppp,         /* Logical processors per package. */
107
                apic_id;      /* Initial APIC ID. */
108
            union {
109
                uint32_t _1c;
110
                struct { DECL_BITFIELD(1c); };
111
            };
112
            union {
113
                uint32_t _1d;
114
                struct { DECL_BITFIELD(1d); };
115
            };
116
117
            /* Leaf 0x2 - TLB/Cache/Prefetch. */
118
            uint8_t l2_nr_queries; /* Documented as fixed to 1. */
119
            uint8_t l2_desc[15];
120
121
            uint64_t :64, :64; /* Leaf 0x3 - PSN. */
122
            uint64_t :64, :64; /* Leaf 0x4 - Structured Cache. */
123
            uint64_t :64, :64; /* Leaf 0x5 - MONITOR. */
124
125
            /* Leaf 0x6 - Therm/Perf. */
126
            union {
127
                uint32_t _6a;
128
                struct {
129
                    bool digital_temp_sensor:1,
130
                        turbo_boost:1,
131
                        arat:1,
132
                        :1,
133
                        :1,
134
                        :1,
135
                        pkg_therm_mgmt:1,
136
                        hwp:1,
137
                        hwp_interrupt:1,
138
                        hwp_activity_window:1,
139
                        hwp_epp:1,
140
                        hwp_request_pkg:1,
141
                        :1,
142
                        hdc:1,
143
                        :1,
144
                        :1,
145
                        hwp_peci_override:1,
146
                        :1,
147
                        :1,
148
                        hw_feedback:1;
149
                };
150
            };
151
            uint32_t /* b */:32;
152
            union {
153
                uint32_t _6c;
154
                struct {
155
                    bool hw_feedback_cap:1; /* aperf/mperf */
156
                };
157
            };
158
            uint32_t /* d */:32;
159
160
            uint64_t :64, :64; /* Leaf 0x7 - Structured Features. */
161
            uint64_t :64, :64; /* Leaf 0x8 - rsvd */
162
            uint64_t :64, :64; /* Leaf 0x9 - DCA */
163
164
            /* Leaf 0xa - Intel PMU. */
165
            uint8_t pmu_version, _pmu[15];
166
167
            uint64_t :64, :64; /* Leaf 0xb - Topology. */
168
            uint64_t :64, :64; /* Leaf 0xc - rsvd */
169
            uint64_t :64, :64; /* Leaf 0xd - XSTATE. */
170
        };
171
    } basic;
172
173
    /* Structured cache leaf: 0x00000004[xx] */
174
    union {
175
        struct cpuid_leaf raw[CPUID_GUEST_NR_CACHE];
176
        struct cpuid_cache_leaf {
177
            uint32_t /* a */ type:5, level:3;
178
            bool self_init:1, fully_assoc:1;
179
            uint32_t :4, threads_per_cache:12, cores_per_package:6;
180
            uint32_t /* b */ line_size:12, partitions:10, ways:10;
181
            uint32_t /* c */ sets;
182
            bool /* d */ wbinvd:1, inclusive:1, complex:1;
183
        } subleaf[CPUID_GUEST_NR_CACHE];
184
    } cache;
185
186
    /* Structured feature leaf: 0x00000007[xx] */
187
    union {
188
        struct cpuid_leaf raw[CPUID_GUEST_NR_FEAT];
189
        struct {
190
            /* Subleaf 0. */
191
            uint32_t max_subleaf;
192
            union {
193
                uint32_t _7b0;
194
                struct { DECL_BITFIELD(7b0); };
195
            };
196
            union {
197
                uint32_t _7c0;
198
                struct { DECL_BITFIELD(7c0); };
199
            };
200
            union {
201
                uint32_t _7d0;
202
                struct { DECL_BITFIELD(7d0); };
203
            };
204
205
            /* Subleaf 1. */
206
            union {
207
                uint32_t _7a1;
208
                struct { DECL_BITFIELD(7a1); };
209
            };
210
            union {
211
                uint32_t _7b1;
212
                struct { DECL_BITFIELD(7b1); };
213
            };
214
            union {
215
                uint32_t _7c1;
216
                struct { DECL_BITFIELD(7c1); };
217
            };
218
            union {
219
                uint32_t _7d1;
220
                struct { DECL_BITFIELD(7d1); };
221
            };
222
223
            /* Subleaf 2. */
224
            uint32_t /* a */:32, /* b */:32, /* c */:32;
225
            union {
226
                uint32_t _7d2;
227
                struct { DECL_BITFIELD(7d2); };
228
            };
229
        };
230
    } feat;
231
232
    /* Extended topology enumeration: 0x0000000B[xx] */
233
    union {
234
        struct cpuid_leaf raw[CPUID_GUEST_NR_TOPO];
235
        struct cpuid_topo_leaf {
236
            uint32_t id_shift:5, :27;
237
            uint16_t nr_logical, :16;
238
            uint8_t level, type, :8, :8;
239
            uint32_t x2apic_id;
240
        } subleaf[CPUID_GUEST_NR_TOPO];
241
    } topo;
242
243
    /* Xstate feature leaf: 0x0000000D[xx] */
244
    union {
245
        struct cpuid_leaf raw[CPUID_GUEST_NR_XSTATE];
246
247
        struct {
248
            /* Subleaf 0. */
249
            uint32_t xcr0_low, /* b */:32, max_size, xcr0_high;
250
251
            /* Subleaf 1. */
252
            union {
253
                uint32_t Da1;
254
                struct { DECL_BITFIELD(Da1); };
255
            };
256
            uint32_t /* b */:32, xss_low, xss_high;
257
        };
258
259
        /* Per-component common state.  Valid for i >= 2. */
260
        struct xstate_component {
261
            uint32_t size, offset;
262
            bool xss:1, align:1;
263
            uint32_t _res_d;
264
        } comp[CPUID_GUEST_NR_XSTATE];
265
    } xstate;
266
267
    /* Extended leaves: 0x800000xx */
268
    union {
269
        struct cpuid_leaf raw[CPUID_GUEST_NR_EXTD];
270
        struct {
271
            /* Leaf 0x80000000 - Max and vendor. */
272
            uint32_t max_leaf, vendor_ebx, vendor_ecx, vendor_edx;
273
274
            /* Leaf 0x80000001 - Family/model/stepping and features. */
275
            uint32_t raw_fms, /* b */:32;
276
            union {
277
                uint32_t e1c;
278
                struct { DECL_BITFIELD(e1c); };
279
            };
280
            union {
281
                uint32_t e1d;
282
                struct { DECL_BITFIELD(e1d); };
283
            };
284
285
            uint64_t :64, :64; /* Brand string. */
286
            uint64_t :64, :64; /* Brand string. */
287
            uint64_t :64, :64; /* Brand string. */
288
            uint64_t :64, :64; /* L1 cache/TLB. */
289
            uint64_t :64, :64; /* L2/3 cache/TLB. */
290
291
            /* Leaf 0x80000007 - Advanced Power Management. */
292
            uint32_t /* a */:32, /* b */:32, /* c */:32;
293
            union {
294
                uint32_t e7d;
295
                struct { DECL_BITFIELD(e7d); };
296
            };
297
298
            /* Leaf 0x80000008 - Misc addr/feature info. */
299
            uint8_t maxphysaddr, maxlinaddr, :8, :8;
300
            union {
301
                uint32_t e8b;
302
                struct { DECL_BITFIELD(e8b); };
303
            };
304
            uint32_t nc:8, :4, apic_id_size:4, :16;
305
            uint32_t /* d */:32;
306
307
            uint64_t :64, :64; /* Leaf 0x80000009. */
308
            uint64_t :64, :64; /* Leaf 0x8000000a - SVM rev and features. */
309
            uint64_t :64, :64; /* Leaf 0x8000000b. */
310
            uint64_t :64, :64; /* Leaf 0x8000000c. */
311
            uint64_t :64, :64; /* Leaf 0x8000000d. */
312
            uint64_t :64, :64; /* Leaf 0x8000000e. */
313
            uint64_t :64, :64; /* Leaf 0x8000000f. */
314
            uint64_t :64, :64; /* Leaf 0x80000010. */
315
            uint64_t :64, :64; /* Leaf 0x80000011. */
316
            uint64_t :64, :64; /* Leaf 0x80000012. */
317
            uint64_t :64, :64; /* Leaf 0x80000013. */
318
            uint64_t :64, :64; /* Leaf 0x80000014. */
319
            uint64_t :64, :64; /* Leaf 0x80000015. */
320
            uint64_t :64, :64; /* Leaf 0x80000016. */
321
            uint64_t :64, :64; /* Leaf 0x80000017. */
322
            uint64_t :64, :64; /* Leaf 0x80000018. */
323
            uint64_t :64, :64; /* Leaf 0x80000019 - TLB 1GB Identifiers. */
324
            uint64_t :64, :64; /* Leaf 0x8000001a - Performance related info. */
325
            uint64_t :64, :64; /* Leaf 0x8000001b - IBS feature information. */
326
            uint64_t :64, :64; /* Leaf 0x8000001c. */
327
            uint64_t :64, :64; /* Leaf 0x8000001d - Cache properties. */
328
            uint64_t :64, :64; /* Leaf 0x8000001e - Extd APIC/Core/Node IDs. */
329
            uint64_t :64, :64; /* Leaf 0x8000001f - AMD Secure Encryption. */
330
            uint64_t :64, :64; /* Leaf 0x80000020 - Platform QoS. */
331
332
            /* Leaf 0x80000021 - Extended Feature 2 */
333
            union {
334
                uint32_t e21a;
335
                struct { DECL_BITFIELD(e21a); };
336
            };
337
            uint16_t ucode_size; /* Units of 16 bytes */
338
            uint8_t  rap_size;   /* Units of 8 entries */
339
            uint8_t  :8;
340
            union {
341
                uint32_t e21c;
342
                struct { DECL_BITFIELD(e21c); };
343
            };
344
            uint32_t /* d */:32;
345
        };
346
    } extd;
347
348
    /*
349
     * 0x000000ce - MSR_INTEL_PLATFORM_INFO
350
     *
351
     * This MSR is non-architectural, but for simplicy we allow it to be read
352
     * unconditionally.  CPUID Faulting support can be fully emulated for HVM
353
     * guests so can be offered unconditionally, while support for PV guests
354
     * is dependent on real hardware support.
355
     */
356
    union {
357
        uint32_t raw;
358
        struct {
359
            uint32_t :31;
360
            bool cpuid_faulting:1;
361
        };
362
    } platform_info;
363
364
    /*
365
     * 0x0000010a - MSR_ARCH_CAPABILITIES
366
     *
367
     * This is an Intel-only MSR, which provides miscellaneous enumeration,
368
     * including those which indicate that microarchitectrual sidechannels are
369
     * fixed in hardware.
370
     */
371
    union {
372
        uint64_t raw;
373
        struct {
374
            uint32_t lo, hi;
375
        };
376
        struct {
377
            DECL_BITFIELD(m10Al);
378
            DECL_BITFIELD(m10Ah);
379
        };
380
    } arch_caps;
381
382
#undef __DECL_BITFIELD
383
#undef _DECL_BITFIELD
384
#undef DECL_BITFIELD
385
386
    /* Toolstack selected Hypervisor max_leaf (if non-zero). */
387
    uint8_t hv_limit, hv2_limit;
388
389
    /* Value calculated from raw data above. */
390
    uint8_t x86_vendor;
391
};
392
393
struct cpu_policy_errors
394
{
395
    uint32_t leaf, subleaf;
396
    uint32_t msr;
397
};
398
399
#define INIT_CPU_POLICY_ERRORS { -1, -1, -1 }
400
401
/**
402
 * Copy the featureset words out of a cpu_policy object.
403
 */
404
void x86_cpu_policy_to_featureset(const struct cpu_policy *p,
405
                                  uint32_t fs[FEATURESET_NR_ENTRIES]);
406
407
/**
408
 * Copy the featureset words back into a cpu_policy object.
409
 */
410
void x86_cpu_featureset_to_policy(const uint32_t fs[FEATURESET_NR_ENTRIES],
411
                                  struct cpu_policy *p);
412
413
static inline uint64_t cpu_policy_xcr0_max(const struct cpu_policy *p)
414
0
{
415
0
    return ((uint64_t)p->xstate.xcr0_high << 32) | p->xstate.xcr0_low;
416
0
}
Unexecuted instantiation: fuzz-emul.c:cpu_policy_xcr0_max
Unexecuted instantiation: x86-emulate.c:cpu_policy_xcr0_max
Unexecuted instantiation: 0f01.c:cpu_policy_xcr0_max
Unexecuted instantiation: 0fae.c:cpu_policy_xcr0_max
Unexecuted instantiation: 0fc7.c:cpu_policy_xcr0_max
Unexecuted instantiation: decode.c:cpu_policy_xcr0_max
Unexecuted instantiation: fpu.c:cpu_policy_xcr0_max
Unexecuted instantiation: cpuid.c:cpu_policy_xcr0_max
Unexecuted instantiation: wrappers.c:cpu_policy_xcr0_max
417
418
static inline uint64_t cpu_policy_xstates(const struct cpu_policy *p)
419
2
{
420
2
    uint64_t val = p->xstate.xcr0_high | p->xstate.xss_high;
421
422
2
    return (val << 32) | p->xstate.xcr0_low | p->xstate.xss_low;
423
2
}
Unexecuted instantiation: fuzz-emul.c:cpu_policy_xstates
Unexecuted instantiation: x86-emulate.c:cpu_policy_xstates
Unexecuted instantiation: 0f01.c:cpu_policy_xstates
Unexecuted instantiation: 0fae.c:cpu_policy_xstates
Unexecuted instantiation: 0fc7.c:cpu_policy_xstates
Unexecuted instantiation: decode.c:cpu_policy_xstates
Unexecuted instantiation: fpu.c:cpu_policy_xstates
cpuid.c:cpu_policy_xstates
Line
Count
Source
419
2
{
420
2
    uint64_t val = p->xstate.xcr0_high | p->xstate.xss_high;
421
422
2
    return (val << 32) | p->xstate.xcr0_low | p->xstate.xss_low;
423
2
}
Unexecuted instantiation: wrappers.c:cpu_policy_xstates
424
425
/**
426
 * For a specific feature, look up the dependent features.  Returns NULL if
427
 * this feature has no dependencies.  Otherwise return a featureset of
428
 * dependent features, which has been recursively flattened.
429
 */
430
const uint32_t *x86_cpu_policy_lookup_deep_deps(uint32_t feature);
431
432
/**
433
 * Recalculate the content in a CPU policy which is derived from raw data.
434
 */
435
void x86_cpu_policy_recalc_synth(struct cpu_policy *p);
436
437
/**
438
 * Fill CPU policy using the native CPUID/RDMSR instruction.
439
 *
440
 * No sanitisation is performed, but synthesised values are calculated.
441
 * Values may be influenced by a hypervisor or from masking/faulting
442
 * configuration.
443
 */
444
void x86_cpu_policy_fill_native(struct cpu_policy *p);
445
446
/**
447
 * Clear leaf data beyond the policies max leaf/subleaf settings.
448
 *
449
 * Policy serialisation purposefully omits out-of-range leaves, because there
450
 * are a large number of them due to vendor differences.  However, when
451
 * constructing new policies (e.g. levelling down), it is possible to end up
452
 * with out-of-range leaves with stale content in them.  This helper clears
453
 * them.
454
 */
455
void x86_cpu_policy_clear_out_of_range_leaves(struct cpu_policy *p);
456
457
#ifdef __XEN__
458
#include <public/xen.h>
459
typedef XEN_GUEST_HANDLE_64(xen_cpuid_leaf_t) cpuid_leaf_buffer_t;
460
typedef XEN_GUEST_HANDLE_64(xen_msr_entry_t) msr_entry_buffer_t;
461
#else
462
#include <xen/arch-x86/xen.h>
463
typedef xen_cpuid_leaf_t cpuid_leaf_buffer_t[];
464
typedef xen_msr_entry_t msr_entry_buffer_t[];
465
#endif
466
467
/**
468
 * Serialise the CPUID leaves of a cpu_policy object into an array of cpuid
469
 * leaves.
470
 *
471
 * @param p            The cpu_policy to serialise.
472
 * @param leaves       The array of leaves to serialise into.
473
 * @param nr_entries_p The number of entries in 'leaves'.
474
 * @returns -errno
475
 *
476
 * Writes at most CPUID_MAX_SERIALISED_LEAVES.  May fail with -ENOBUFS if the
477
 * leaves array is too short.  On success, nr_entries is updated with the
478
 * actual number of leaves written.
479
 */
480
int x86_cpuid_copy_to_buffer(const struct cpu_policy *p,
481
                             cpuid_leaf_buffer_t leaves,
482
                             uint32_t *nr_entries_p);
483
484
/**
485
 * Unserialise the CPUID leaves of a cpu_policy object into an array of cpuid
486
 * leaves.
487
 *
488
 * @param p           The cpu_policy to unserialise into.
489
 * @param leaves      The array of leaves to unserialise from.
490
 * @param nr_entries  The number of entries in 'leaves'.
491
 * @param err_leaf    Optional hint for error diagnostics.
492
 * @param err_subleaf Optional hint for error diagnostics.
493
 * @returns -errno
494
 *
495
 * Reads at most CPUID_MAX_SERIALISED_LEAVES.  May return -ERANGE if an
496
 * incoming leaf is out of range of cpu_policy, in which case the optional
497
 * err_* pointers will identify the out-of-range indicies.
498
 *
499
 * No content validation of in-range leaves is performed.  Synthesised data is
500
 * recalculated.
501
 */
502
int x86_cpuid_copy_from_buffer(struct cpu_policy *p,
503
                               const cpuid_leaf_buffer_t leaves,
504
                               uint32_t nr_entries, uint32_t *err_leaf,
505
                               uint32_t *err_subleaf);
506
507
/**
508
 * Serialise the MSRs of a cpu_policy object into an array.
509
 *
510
 * @param p            The cpu_policy to serialise.
511
 * @param msrs         The array of msrs to serialise into.
512
 * @param nr_entries_p The number of entries in 'msrs'.
513
 * @returns -errno
514
 *
515
 * Writes at most MSR_MAX_SERIALISED_ENTRIES.  May fail with -ENOBUFS if the
516
 * buffer array is too short.  On success, nr_entries is updated with the
517
 * actual number of msrs written.
518
 */
519
int x86_msr_copy_to_buffer(const struct cpu_policy *p,
520
                           msr_entry_buffer_t msrs, uint32_t *nr_entries_p);
521
522
/**
523
 * Unserialise the MSRs of a cpu_policy object from an array of msrs.
524
 *
525
 * @param p          The cpu_policy object to unserialise into.
526
 * @param msrs       The array of msrs to unserialise from.
527
 * @param nr_entries The number of entries in 'msrs'.
528
 * @param err_msr    Optional hint for error diagnostics.
529
 * @returns -errno
530
 *
531
 * Reads at most MSR_MAX_SERIALISED_ENTRIES.  May fail for a number of reasons
532
 * based on the content in an individual 'msrs' entry, including the MSR index
533
 * not being valid in the policy, the flags field being nonzero, or if the
534
 * value provided would truncate when stored in the policy.  In such cases,
535
 * the optional err_* pointer will identify the problematic MSR.
536
 *
537
 * No content validation is performed on the data stored in the policy object.
538
 */
539
int x86_msr_copy_from_buffer(struct cpu_policy *p,
540
                             const msr_entry_buffer_t msrs, uint32_t nr_entries,
541
                             uint32_t *err_msr);
542
543
/**
544
 * Calculate whether two policies are compatible.
545
 *
546
 * i.e. Can a VM configured with @guest run on a CPU supporting @host.
547
 *
548
 * @param host     A cpu_policy describing the hardware capabilities.
549
 * @param guest    A cpu_policy describing the intended VM configuration.
550
 * @param err      Optional hint for error diagnostics.
551
 * @returns -errno
552
 *
553
 * For typical usage, @host should be a system policy.  In the case that an
554
 * incompatibility is detected, the optional err pointer may identify the
555
 * problematic leaf/subleaf and/or MSR.
556
 */
557
int x86_cpu_policies_are_compatible(const struct cpu_policy *host,
558
                                    const struct cpu_policy *guest,
559
                                    struct cpu_policy_errors *err);
560
561
#endif /* !XEN_LIB_X86_POLICIES_H */
562
563
/*
564
 * Local variables:
565
 * mode: C
566
 * c-file-style: "BSD"
567
 * c-basic-offset: 4
568
 * tab-width: 4
569
 * indent-tabs-mode: nil
570
 * End:
571
 */