From 51528d4a8107695c73f9dbf7893a11b554a4cfa8 Mon Sep 17 00:00:00 2001 From: Jason Chen CJ Date: Thu, 24 May 2018 12:52:11 +0800 Subject: [PATCH] ucode: refine acrn_update_ucode with copy_from_gva using copy_from_gva to refine function acrn_update_ucode v2: - inject #PF if copy_from_gva meet -EFAULT - remove VCPU_RETAIN_RIP when inject #PF - refine MACRO GET_DATA_SIZE Signed-off-by: Jason Chen CJ Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/ucode.c | 51 +++++++++++-------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/hypervisor/arch/x86/guest/ucode.c b/hypervisor/arch/x86/guest/ucode.c index 28dd38145..1b1e91d6f 100644 --- a/hypervisor/arch/x86/guest/ucode.c +++ b/hypervisor/arch/x86/guest/ucode.c @@ -23,28 +23,28 @@ uint64_t get_microcode_version(void) * According to SDM vol 3 Table 9-7. If data_size field of uCode * header is zero, the ucode length is 2000 */ -#define GET_DATA_SIZE(hdptr) \ - ((hdptr)->data_size ? ((hdptr)->data_size) : 2000) +#define UCODE_GET_DATA_SIZE(uhdr) \ + (uhdr.data_size ? uhdr.data_size : 2000) void acrn_update_ucode(struct vcpu *vcpu, uint64_t v) { - uint64_t hva, gpa, gva; - struct ucode_header *uhdr; + uint64_t gva; + struct ucode_header uhdr; int data_size, data_page_num; uint8_t *ucode_ptr, *ptr; - int chunk_size; - int error = 0; + int err; uint32_t err_code; gva = v - sizeof(struct ucode_header); err_code = 0; - error = vm_gva2gpa(vcpu, gva, &gpa, &err_code); - if (error) + err = copy_from_gva(vcpu, &uhdr, gva, sizeof(uhdr), &err_code); + if (err == -EFAULT) { + vcpu_inject_pf(vcpu, gva, err_code); + return; + } else if (err < 0) return; - uhdr = (struct ucode_header *)GPA2HVA(vcpu->vm, gpa); - - data_size = GET_DATA_SIZE(uhdr) + sizeof(struct ucode_header); + data_size = UCODE_GET_DATA_SIZE(uhdr) + sizeof(struct ucode_header); data_page_num = (data_size + CPU_PAGE_SIZE - 1) >> CPU_PAGE_SHIFT; @@ -52,28 +52,13 @@ void acrn_update_ucode(struct vcpu *vcpu, uint64_t v) if (ptr == NULL) return; - hva = (uint64_t)uhdr; - while (true) { - chunk_size = CPU_PAGE_SIZE - (hva & (CPU_PAGE_SIZE - 1)); - chunk_size = (chunk_size < data_size) ? chunk_size : data_size; - - memcpy_s(ucode_ptr, chunk_size, (uint8_t *)hva, chunk_size); - - data_size -= chunk_size; - if (data_size <= 0) - break; - - ucode_ptr += chunk_size; - gva += chunk_size; - - err_code = 0; - error = vm_gva2gpa(vcpu, gva, &gpa, &err_code); - if (error) { - free(ucode_ptr); - return; - } - hva = (uint64_t)GPA2HVA(vcpu->vm, gpa); - } + err_code = 0; + err = copy_from_gva(vcpu, ucode_ptr, gva, data_size, &err_code); + if (err == -EFAULT) { + vcpu_inject_pf(vcpu, gva, err_code); + return; + } else if (err < 0) + return; msr_write(MSR_IA32_BIOS_UPDT_TRIG, (uint64_t)ptr + sizeof(struct ucode_header));