1 #include "xc_sr_common_x86.h"
2
write_x86_tsc_info(struct xc_sr_context * ctx)3 int write_x86_tsc_info(struct xc_sr_context *ctx)
4 {
5 xc_interface *xch = ctx->xch;
6 struct xc_sr_rec_x86_tsc_info tsc = {};
7 struct xc_sr_record rec = {
8 .type = REC_TYPE_X86_TSC_INFO,
9 .length = sizeof(tsc),
10 .data = &tsc,
11 };
12
13 if ( xc_domain_get_tsc_info(xch, ctx->domid, &tsc.mode,
14 &tsc.nsec, &tsc.khz, &tsc.incarnation) < 0 )
15 {
16 PERROR("Unable to obtain TSC information");
17 return -1;
18 }
19
20 return write_record(ctx, &rec);
21 }
22
handle_x86_tsc_info(struct xc_sr_context * ctx,struct xc_sr_record * rec)23 int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec)
24 {
25 xc_interface *xch = ctx->xch;
26 struct xc_sr_rec_x86_tsc_info *tsc = rec->data;
27
28 if ( rec->length != sizeof(*tsc) )
29 {
30 ERROR("X86_TSC_INFO record wrong size: length %u, expected %zu",
31 rec->length, sizeof(*tsc));
32 return -1;
33 }
34
35 if ( xc_domain_set_tsc_info(xch, ctx->domid, tsc->mode,
36 tsc->nsec, tsc->khz, tsc->incarnation) )
37 {
38 PERROR("Unable to set TSC information");
39 return -1;
40 }
41
42 return 0;
43 }
44
write_x86_cpu_policy_records(struct xc_sr_context * ctx)45 int write_x86_cpu_policy_records(struct xc_sr_context *ctx)
46 {
47 xc_interface *xch = ctx->xch;
48 struct xc_sr_record cpuid = { .type = REC_TYPE_X86_CPUID_POLICY, };
49 struct xc_sr_record msrs = { .type = REC_TYPE_X86_MSR_POLICY, };
50 uint32_t nr_leaves = 0, nr_msrs = 0;
51 int rc;
52
53 if ( xc_get_cpu_policy_size(xch, &nr_leaves, &nr_msrs) < 0 )
54 {
55 PERROR("Unable to get CPU Policy size");
56 return -1;
57 }
58
59 cpuid.data = malloc(nr_leaves * sizeof(xen_cpuid_leaf_t));
60 msrs.data = malloc(nr_msrs * sizeof(xen_msr_entry_t));
61 if ( !cpuid.data || !msrs.data )
62 {
63 ERROR("Cannot allocate memory for CPU Policy");
64 rc = -1;
65 goto out;
66 }
67
68 if ( xc_get_domain_cpu_policy(xch, ctx->domid, &nr_leaves, cpuid.data,
69 &nr_msrs, msrs.data) )
70 {
71 PERROR("Unable to get d%d CPU Policy", ctx->domid);
72 rc = -1;
73 goto out;
74 }
75
76 cpuid.length = nr_leaves * sizeof(xen_cpuid_leaf_t);
77 if ( cpuid.length )
78 {
79 rc = write_record(ctx, &cpuid);
80 if ( rc )
81 goto out;
82 }
83
84 msrs.length = nr_msrs * sizeof(xen_msr_entry_t);
85 if ( msrs.length )
86 rc = write_record(ctx, &msrs);
87
88 out:
89 free(cpuid.data);
90 free(msrs.data);
91
92 return rc;
93 }
94
handle_x86_cpuid_policy(struct xc_sr_context * ctx,struct xc_sr_record * rec)95 int handle_x86_cpuid_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
96 {
97 xc_interface *xch = ctx->xch;
98 int rc;
99
100 if ( rec->length == 0 ||
101 rec->length % sizeof(xen_cpuid_leaf_t) != 0 )
102 {
103 ERROR("X86_CPUID_POLICY size %u should be multiple of %zu",
104 rec->length, sizeof(xen_cpuid_leaf_t));
105 return -1;
106 }
107
108 rc = update_blob(&ctx->x86.restore.cpuid, rec->data, rec->length);
109 if ( rc )
110 ERROR("Unable to allocate %u bytes for X86_CPUID_POLICY", rec->length);
111
112 return rc;
113 }
114
handle_x86_msr_policy(struct xc_sr_context * ctx,struct xc_sr_record * rec)115 int handle_x86_msr_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec)
116 {
117 xc_interface *xch = ctx->xch;
118 int rc;
119
120 if ( rec->length == 0 ||
121 rec->length % sizeof(xen_msr_entry_t) != 0 )
122 {
123 ERROR("X86_MSR_POLICY size %u should be multiple of %zu",
124 rec->length, sizeof(xen_cpuid_leaf_t));
125 return -1;
126 }
127
128 rc = update_blob(&ctx->x86.restore.msr, rec->data, rec->length);
129 if ( rc )
130 ERROR("Unable to allocate %u bytes for X86_MSR_POLICY", rec->length);
131
132 return rc;
133 }
134
x86_static_data_complete(struct xc_sr_context * ctx,unsigned int * missing)135 int x86_static_data_complete(struct xc_sr_context *ctx, unsigned int *missing)
136 {
137 xc_interface *xch = ctx->xch;
138 uint32_t nr_leaves = 0, nr_msrs = 0;
139 uint32_t err_l = ~0, err_s = ~0, err_m = ~0;
140
141 if ( ctx->x86.restore.cpuid.ptr )
142 nr_leaves = ctx->x86.restore.cpuid.size / sizeof(xen_cpuid_leaf_t);
143 else
144 *missing |= XGR_SDD_MISSING_CPUID;
145
146 if ( ctx->x86.restore.msr.ptr )
147 nr_msrs = ctx->x86.restore.msr.size / sizeof(xen_msr_entry_t);
148 else
149 *missing |= XGR_SDD_MISSING_MSR;
150
151 if ( (nr_leaves || nr_msrs) &&
152 xc_set_domain_cpu_policy(xch, ctx->domid,
153 nr_leaves, ctx->x86.restore.cpuid.ptr,
154 nr_msrs, ctx->x86.restore.msr.ptr,
155 &err_l, &err_s, &err_m) )
156 {
157 PERROR("Failed to set CPUID policy: leaf %08x, subleaf %08x, msr %08x",
158 err_l, err_s, err_m);
159 return -1;
160 }
161
162 return 0;
163 }
164
165 /*
166 * Local variables:
167 * mode: C
168 * c-file-style: "BSD"
169 * c-basic-offset: 4
170 * tab-width: 4
171 * indent-tabs-mode: nil
172 * End:
173 */
174