acrn-hypervisor/hypervisor/arch/x86/guest/ucode.c
Mingqiang Chi b24a8a0f59 hv:cleanup header file for guest folder
cleanup arch/x86/guest, only include some necessary
header files, doesn't include hypervisor.h

Tracked-On: #1842
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
	modified:   arch/x86/guest/assign.c
	modified:   arch/x86/guest/ept.c
	modified:   arch/x86/guest/guest_memory.c
	modified:   arch/x86/guest/instr_emul.c
	modified:   arch/x86/guest/io_emul.c
	modified:   arch/x86/guest/pm.c
	modified:   arch/x86/guest/trusty.c
	modified:   arch/x86/guest/ucode.c
	modified:   arch/x86/guest/vcpu.c
	modified:   arch/x86/guest/vcpuid.c
	modified:   arch/x86/guest/virq.c
	modified:   arch/x86/guest/virtual_cr.c
	modified:   arch/x86/guest/vlapic.c
	modified:   arch/x86/guest/vm.c
	modified:   arch/x86/guest/vmcall.c
	modified:   arch/x86/guest/vmcs.c
	modified:   arch/x86/guest/vmexit.c
	modified:   arch/x86/guest/vmsr.c
	modified:   arch/x86/guest/vmtrr.c
	modified:   arch/x86/pm.c
	modified:   include/arch/x86/guest/assign.h
	modified:   include/arch/x86/guest/ept.h
	modified:   include/arch/x86/guest/guest_memory.h
	modified:   include/arch/x86/guest/instr_emul.h
	modified:   include/arch/x86/guest/io_emul.h
	modified:   include/arch/x86/guest/trusty.h
	modified:   include/arch/x86/guest/vcpu.h
	modified:   include/arch/x86/guest/vmcs.h
	modified:   include/arch/x86/io_req.h
	modified:   include/arch/x86/irq.h
	modified:   include/arch/x86/lapic.h
	modified:   include/arch/x86/mmu.h
	modified:   include/arch/x86/pgtable.h
	modified:   include/common/ptdev.h
	modified:   include/debug/console.h
2019-02-21 10:38:30 +08:00

83 lines
2.0 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <types.h>
#include <errno.h>
#include <spinlock.h>
#include <cpu.h>
#include <msr.h>
#include <cpuid.h>
#include <ucode.h>
#include <guest_memory.h>
#include <irq.h>
#include <logmsg.h>
#define MICRO_CODE_SIZE_MAX 0x40000U
static uint8_t micro_code[MICRO_CODE_SIZE_MAX];
static spinlock_t micro_code_lock = { .head = 0U, .tail = 0U };
uint64_t get_microcode_version(void)
{
uint64_t val;
uint32_t eax, ebx, ecx, edx;
msr_write(MSR_IA32_BIOS_SIGN_ID, 0U);
cpuid(CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
val = msr_read(MSR_IA32_BIOS_SIGN_ID);
return val;
}
/*
* According to SDM vol 3 Table 9-7. If data_size field of uCode
* header is zero, the ucode length is 2000
*/
static inline size_t get_ucode_data_size(const struct ucode_header *uhdr)
{
return ((uhdr->data_size != 0U) ? uhdr->data_size : 2000U);
}
void acrn_update_ucode(struct acrn_vcpu *vcpu, uint64_t v)
{
uint64_t gva, fault_addr = 0UL;
struct ucode_header uhdr;
size_t data_size;
int32_t err;
uint32_t err_code;
spinlock_obtain(&micro_code_lock);
gva = v - sizeof(struct ucode_header);
err_code = 0U;
err = copy_from_gva(vcpu, &uhdr, gva, sizeof(uhdr), &err_code,
&fault_addr);
if (err < 0) {
if (err == -EFAULT) {
vcpu_inject_pf(vcpu, fault_addr, err_code);
}
} else {
data_size = get_ucode_data_size(&uhdr) + sizeof(struct ucode_header);
if (data_size > MICRO_CODE_SIZE_MAX) {
pr_err("The size of microcode is greater than 0x%x",
MICRO_CODE_SIZE_MAX);
} else {
err_code = 0U;
err = copy_from_gva(vcpu, micro_code, gva, data_size, &err_code,
&fault_addr);
if (err < 0) {
if (err == -EFAULT) {
vcpu_inject_pf(vcpu, fault_addr, err_code);
}
} else {
msr_write(MSR_IA32_BIOS_UPDT_TRIG,
(uint64_t)micro_code + sizeof(struct ucode_header));
(void)get_microcode_version();
}
}
}
spinlock_release(&micro_code_lock);
}