acrn-hypervisor/hypervisor/arch/x86/guest/ucode.c
Xiangyang Wu fa26a16645 HV:treewide:rename vcpu data structure
For data structure types "struct vcpu", its name is identical
with variable name in the same scope. This is a MISRA C  violation.

Naming convention rule:If the data structure type is used by multi
modules, its corresponding logic resource is exposed to external
components (such as SOS, UOS), and its name meaning is simplistic
(such as vcpu, vm), its name needs prefix "acrn_".

The following udpates are made:
struct vcpu *vcpu-->struct acrn_vcpu *vcpu

Tracked-On: #861

Signed-off-by: Xiangyang Wu <xiangyang.wu@linux.intel.com>
2018-11-05 15:35:49 +08:00

81 lines
1.9 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hypervisor.h>
#include <ucode.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;
struct ucode_header uhdr;
size_t data_size;
int 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);
}
spinlock_release(&micro_code_lock);
return;
}
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);
spinlock_release(&micro_code_lock);
return;
}
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);
}
spinlock_release(&micro_code_lock);
return;
}
msr_write(MSR_IA32_BIOS_UPDT_TRIG,
(uint64_t)micro_code + sizeof(struct ucode_header));
(void)get_microcode_version();
spinlock_release(&micro_code_lock);
}