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 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 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 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 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 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 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 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 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 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 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