1 /*
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 *
4 * uefi vars device
5 */
6 #include "qemu/osdep.h"
7 #include "qemu/crc32c.h"
8 #include "system/dma.h"
9 #include "migration/vmstate.h"
10
11 #include "hw/uefi/var-service.h"
12 #include "hw/uefi/var-service-api.h"
13 #include "hw/uefi/var-service-edk2.h"
14
15 #include "trace/trace-hw_uefi.h"
16
uefi_vars_pre_load(void * opaque)17 static int uefi_vars_pre_load(void *opaque)
18 {
19 uefi_vars_state *uv = opaque;
20
21 uefi_vars_clear_all(uv);
22 uefi_vars_policies_clear(uv);
23 g_free(uv->buffer);
24 return 0;
25 }
26
uefi_vars_post_load(void * opaque,int version_id)27 static int uefi_vars_post_load(void *opaque, int version_id)
28 {
29 uefi_vars_state *uv = opaque;
30
31 uefi_vars_update_storage(uv);
32 uefi_vars_json_save(uv);
33 uv->buffer = g_malloc(uv->buf_size);
34 return 0;
35 }
36
37 const VMStateDescription vmstate_uefi_vars = {
38 .name = "uefi-vars",
39 .pre_load = uefi_vars_pre_load,
40 .post_load = uefi_vars_post_load,
41 .fields = (VMStateField[]) {
42 VMSTATE_UINT16(sts, uefi_vars_state),
43 VMSTATE_UINT32(buf_size, uefi_vars_state),
44 VMSTATE_UINT32(buf_addr_lo, uefi_vars_state),
45 VMSTATE_UINT32(buf_addr_hi, uefi_vars_state),
46 VMSTATE_UINT32(pio_xfer_offset, uefi_vars_state),
47 VMSTATE_VBUFFER_ALLOC_UINT32(pio_xfer_buffer, uefi_vars_state,
48 0, NULL, buf_size),
49 VMSTATE_BOOL(end_of_dxe, uefi_vars_state),
50 VMSTATE_BOOL(ready_to_boot, uefi_vars_state),
51 VMSTATE_BOOL(exit_boot_service, uefi_vars_state),
52 VMSTATE_BOOL(policy_locked, uefi_vars_state),
53 VMSTATE_UINT64(used_storage, uefi_vars_state),
54 VMSTATE_QTAILQ_V(variables, uefi_vars_state, 0,
55 vmstate_uefi_variable, uefi_variable, next),
56 VMSTATE_QTAILQ_V(var_policies, uefi_vars_state, 0,
57 vmstate_uefi_var_policy, uefi_var_policy, next),
58 VMSTATE_END_OF_LIST()
59 },
60 };
61
uefi_vars_cmd_mm(uefi_vars_state * uv,bool dma_mode)62 static uint32_t uefi_vars_cmd_mm(uefi_vars_state *uv, bool dma_mode)
63 {
64 hwaddr dma;
65 mm_header *mhdr;
66 uint64_t size;
67 uint32_t retval;
68
69 dma = uv->buf_addr_lo | ((hwaddr)uv->buf_addr_hi << 32);
70 mhdr = (mm_header *) uv->buffer;
71
72 if (!uv->buffer || uv->buf_size < sizeof(*mhdr)) {
73 return UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE;
74 }
75
76 /* read header */
77 if (dma_mode) {
78 dma_memory_read(&address_space_memory, dma,
79 uv->buffer, sizeof(*mhdr),
80 MEMTXATTRS_UNSPECIFIED);
81 } else {
82 memcpy(uv->buffer, uv->pio_xfer_buffer, sizeof(*mhdr));
83 }
84
85 if (uadd64_overflow(sizeof(*mhdr), mhdr->length, &size)) {
86 return UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE;
87 }
88 if (uv->buf_size < size) {
89 return UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE;
90 }
91
92 /* read buffer (excl header) */
93 if (dma_mode) {
94 dma_memory_read(&address_space_memory, dma + sizeof(*mhdr),
95 uv->buffer + sizeof(*mhdr), mhdr->length,
96 MEMTXATTRS_UNSPECIFIED);
97 } else {
98 memcpy(uv->buffer + sizeof(*mhdr),
99 uv->pio_xfer_buffer + sizeof(*mhdr),
100 mhdr->length);
101 }
102 memset(uv->buffer + size, 0, uv->buf_size - size);
103
104 /* dispatch */
105 if (qemu_uuid_is_equal(&mhdr->guid, &EfiSmmVariableProtocolGuid)) {
106 retval = uefi_vars_mm_vars_proto(uv);
107
108 } else if (qemu_uuid_is_equal(&mhdr->guid, &VarCheckPolicyLibMmiHandlerGuid)) {
109 retval = uefi_vars_mm_check_policy_proto(uv);
110
111 } else if (qemu_uuid_is_equal(&mhdr->guid, &EfiEndOfDxeEventGroupGuid)) {
112 trace_uefi_event("end-of-dxe");
113 uv->end_of_dxe = true;
114 retval = UEFI_VARS_STS_SUCCESS;
115
116 } else if (qemu_uuid_is_equal(&mhdr->guid, &EfiEventReadyToBootGuid)) {
117 trace_uefi_event("ready-to-boot");
118 uv->ready_to_boot = true;
119 retval = UEFI_VARS_STS_SUCCESS;
120
121 } else if (qemu_uuid_is_equal(&mhdr->guid, &EfiEventExitBootServicesGuid)) {
122 trace_uefi_event("exit-boot-service");
123 uv->exit_boot_service = true;
124 retval = UEFI_VARS_STS_SUCCESS;
125
126 } else {
127 retval = UEFI_VARS_STS_ERR_NOT_SUPPORTED;
128 }
129
130 /* write buffer */
131 if (dma_mode) {
132 dma_memory_write(&address_space_memory, dma,
133 uv->buffer, sizeof(*mhdr) + mhdr->length,
134 MEMTXATTRS_UNSPECIFIED);
135 } else {
136 memcpy(uv->pio_xfer_buffer + sizeof(*mhdr),
137 uv->buffer + sizeof(*mhdr),
138 sizeof(*mhdr) + mhdr->length);
139 }
140
141 return retval;
142 }
143
uefi_vars_soft_reset(uefi_vars_state * uv)144 static void uefi_vars_soft_reset(uefi_vars_state *uv)
145 {
146 g_free(uv->buffer);
147 uv->buffer = NULL;
148 uv->buf_size = 0;
149 uv->buf_addr_lo = 0;
150 uv->buf_addr_hi = 0;
151 }
152
uefi_vars_hard_reset(uefi_vars_state * uv)153 void uefi_vars_hard_reset(uefi_vars_state *uv)
154 {
155 trace_uefi_hard_reset();
156 uefi_vars_soft_reset(uv);
157
158 uv->end_of_dxe = false;
159 uv->ready_to_boot = false;
160 uv->exit_boot_service = false;
161 uv->policy_locked = false;
162
163 uefi_vars_clear_volatile(uv);
164 uefi_vars_policies_clear(uv);
165 uefi_vars_auth_init(uv);
166 }
167
uefi_vars_cmd(uefi_vars_state * uv,uint32_t cmd)168 static uint32_t uefi_vars_cmd(uefi_vars_state *uv, uint32_t cmd)
169 {
170 switch (cmd) {
171 case UEFI_VARS_CMD_RESET:
172 uefi_vars_soft_reset(uv);
173 return UEFI_VARS_STS_SUCCESS;
174 case UEFI_VARS_CMD_DMA_MM:
175 return uefi_vars_cmd_mm(uv, true);
176 case UEFI_VARS_CMD_PIO_MM:
177 return uefi_vars_cmd_mm(uv, false);
178 case UEFI_VARS_CMD_PIO_ZERO_OFFSET:
179 uv->pio_xfer_offset = 0;
180 return UEFI_VARS_STS_SUCCESS;
181 default:
182 return UEFI_VARS_STS_ERR_NOT_SUPPORTED;
183 }
184 }
185
uefi_vars_read(void * opaque,hwaddr addr,unsigned size)186 static uint64_t uefi_vars_read(void *opaque, hwaddr addr, unsigned size)
187 {
188 uefi_vars_state *uv = opaque;
189 uint64_t retval = -1;
190 void *xfer_ptr;
191
192 trace_uefi_reg_read(addr, size);
193
194 switch (addr) {
195 case UEFI_VARS_REG_MAGIC:
196 retval = UEFI_VARS_MAGIC_VALUE;
197 break;
198 case UEFI_VARS_REG_CMD_STS:
199 retval = uv->sts;
200 break;
201 case UEFI_VARS_REG_BUFFER_SIZE:
202 retval = uv->buf_size;
203 break;
204 case UEFI_VARS_REG_DMA_BUFFER_ADDR_LO:
205 retval = uv->buf_addr_lo;
206 break;
207 case UEFI_VARS_REG_DMA_BUFFER_ADDR_HI:
208 retval = uv->buf_addr_hi;
209 break;
210 case UEFI_VARS_REG_PIO_BUFFER_TRANSFER:
211 if (uv->pio_xfer_offset + size > uv->buf_size) {
212 retval = 0;
213 break;
214 }
215 xfer_ptr = uv->pio_xfer_buffer + uv->pio_xfer_offset;
216 switch (size) {
217 case 1:
218 retval = *(uint8_t *)xfer_ptr;
219 break;
220 case 2:
221 retval = *(uint16_t *)xfer_ptr;
222 break;
223 case 4:
224 retval = *(uint32_t *)xfer_ptr;
225 break;
226 case 8:
227 retval = *(uint64_t *)xfer_ptr;
228 break;
229 }
230 uv->pio_xfer_offset += size;
231 break;
232 case UEFI_VARS_REG_PIO_BUFFER_CRC32C:
233 retval = crc32c(0xffffffff, uv->pio_xfer_buffer, uv->pio_xfer_offset);
234 break;
235 case UEFI_VARS_REG_FLAGS:
236 retval = 0;
237 if (uv->use_pio) {
238 retval |= UEFI_VARS_FLAG_USE_PIO;
239 }
240 }
241 return retval;
242 }
243
uefi_vars_write(void * opaque,hwaddr addr,uint64_t val,unsigned size)244 static void uefi_vars_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
245 {
246 uefi_vars_state *uv = opaque;
247 void *xfer_ptr;
248
249 trace_uefi_reg_write(addr, val, size);
250
251 switch (addr) {
252 case UEFI_VARS_REG_CMD_STS:
253 uv->sts = uefi_vars_cmd(uv, val);
254 break;
255 case UEFI_VARS_REG_BUFFER_SIZE:
256 if (val > MAX_BUFFER_SIZE) {
257 val = MAX_BUFFER_SIZE;
258 }
259 uv->buf_size = val;
260 g_free(uv->buffer);
261 g_free(uv->pio_xfer_buffer);
262 uv->buffer = g_malloc(uv->buf_size);
263 uv->pio_xfer_buffer = g_malloc(uv->buf_size);
264 break;
265 case UEFI_VARS_REG_DMA_BUFFER_ADDR_LO:
266 uv->buf_addr_lo = val;
267 break;
268 case UEFI_VARS_REG_DMA_BUFFER_ADDR_HI:
269 uv->buf_addr_hi = val;
270 break;
271 case UEFI_VARS_REG_PIO_BUFFER_TRANSFER:
272 if (uv->pio_xfer_offset + size > uv->buf_size) {
273 break;
274 }
275 xfer_ptr = uv->pio_xfer_buffer + uv->pio_xfer_offset;
276 switch (size) {
277 case 1:
278 *(uint8_t *)xfer_ptr = val;
279 break;
280 case 2:
281 *(uint16_t *)xfer_ptr = val;
282 break;
283 case 4:
284 *(uint32_t *)xfer_ptr = val;
285 break;
286 case 8:
287 *(uint64_t *)xfer_ptr = val;
288 break;
289 }
290 uv->pio_xfer_offset += size;
291 break;
292 case UEFI_VARS_REG_PIO_BUFFER_CRC32C:
293 case UEFI_VARS_REG_FLAGS:
294 default:
295 break;
296 }
297 }
298
299 static const MemoryRegionOps uefi_vars_ops = {
300 .read = uefi_vars_read,
301 .write = uefi_vars_write,
302 .endianness = DEVICE_LITTLE_ENDIAN,
303 .impl = {
304 .min_access_size = 2,
305 .max_access_size = 4,
306 },
307 };
308
uefi_vars_init(Object * obj,uefi_vars_state * uv)309 void uefi_vars_init(Object *obj, uefi_vars_state *uv)
310 {
311 QTAILQ_INIT(&uv->variables);
312 QTAILQ_INIT(&uv->var_policies);
313 uv->jsonfd = -1;
314 memory_region_init_io(&uv->mr, obj, &uefi_vars_ops, uv,
315 "uefi-vars", UEFI_VARS_REGS_SIZE);
316 }
317
uefi_vars_realize(uefi_vars_state * uv,Error ** errp)318 void uefi_vars_realize(uefi_vars_state *uv, Error **errp)
319 {
320 uefi_vars_json_init(uv, errp);
321 uefi_vars_json_load(uv, errp);
322 }
323