Skip to content

Commit 4073b37

Browse files
fyin1jren1
authored andcommitted
hv: microcode: Enable microcode update from SOS.
microcode update from UOS is disabled. microcode version checking is available for both SOS and UOS. There are two TODOs of this patch: 1. This patch only update the uCode on pCPUs SOS owned. For the pCPUs not owned by SOS, the uCode is not updated. To handle this gap, we will have SOS own all pCPUs at boot time. So all pCPUs could have uCode updated. This will be handled in the patch to enable SOS own all pCPUs at boot time. 2. gva2gpa now doesn't check possible page table walk failure. Will add the failure check in gva2gpa in different patch. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Reviewed-by: Anthony Xu (anthony.xu@intel.com) Acked-by: Eddie Dong <eddie.dong@intel.com> Acked-by: Tian, Kevin <kevin.tian@intel.com>
1 parent 4110e25 commit 4073b37

File tree

6 files changed

+172
-1
lines changed

6 files changed

+172
-1
lines changed

hypervisor/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ C_SRCS += arch/x86/guest/vpic.c
113113
C_SRCS += arch/x86/guest/vmsr.c
114114
C_SRCS += arch/x86/guest/vioapic.c
115115
C_SRCS += arch/x86/guest/instr_emul.c
116+
C_SRCS += arch/x86/guest/ucode.c
116117
C_SRCS += lib/spinlock.c
117118
C_SRCS += lib/udelay.c
118119
C_SRCS += lib/strnlen.c

hypervisor/arch/x86/guest/instr_emul_wrapper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,3 @@ int vm_get_seg_desc(struct vcpu *vcpu, int reg,
200200
int vm_set_seg_desc(struct vcpu *vcpu, int reg,
201201
struct seg_desc *desc);
202202
int vm_restart_instruction(struct vcpu *vcpu);
203-
void vm_gva2gpa(struct vcpu *vcpu, uint64_t gla, uint64_t *gpa);

hypervisor/arch/x86/guest/ucode.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in
12+
* the documentation and/or other materials provided with the
13+
* distribution.
14+
* * Neither the name of Intel Corporation nor the names of its
15+
* contributors may be used to endorse or promote products derived
16+
* from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
31+
#include <hv_lib.h>
32+
#include <acrn_common.h>
33+
#include <hv_arch.h>
34+
#include <hv_debug.h>
35+
#include <ucode.h>
36+
37+
uint64_t get_microcode_version(void)
38+
{
39+
uint64_t val;
40+
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
41+
42+
msr_write(MSR_IA32_BIOS_SIGN_ID, 0);
43+
native_cpuid_count(CPUID_FEATURES, 0, &eax, &ebx, &ecx, &edx);
44+
val = msr_read(MSR_IA32_BIOS_SIGN_ID);
45+
46+
return val;
47+
}
48+
49+
/*
50+
* According to SDM vol 3 Table 9-7. If data_size field of uCode
51+
* header is zero, the ucode length is 2000
52+
*/
53+
#define GET_DATA_SIZE(hdptr) ((hdptr)->data_size ? : 2000)
54+
void acrn_update_ucode(struct vcpu *vcpu, uint64_t v)
55+
{
56+
uint64_t hva, gpa, gva;
57+
struct ucode_header *uhdr;
58+
int data_size, data_page_num;
59+
uint8_t *ucode_ptr, *ptr;
60+
int chunk_size;
61+
62+
gva = v - sizeof(struct ucode_header);
63+
64+
vm_gva2gpa(vcpu, gva, &gpa);
65+
uhdr = (struct ucode_header *)GPA2HVA(vcpu->vm, gpa);
66+
67+
data_size = GET_DATA_SIZE(uhdr) + sizeof(struct ucode_header);
68+
data_page_num =
69+
(data_size + CPU_PAGE_SIZE - 1) >> CPU_PAGE_SHIFT;
70+
71+
ptr = ucode_ptr = alloc_pages(data_page_num);
72+
if (ptr == NULL)
73+
return;
74+
75+
hva = (uint64_t)uhdr;
76+
while (true) {
77+
chunk_size = CPU_PAGE_SIZE - (hva & (CPU_PAGE_SIZE - 1));
78+
chunk_size = (chunk_size < data_size) ? chunk_size : data_size;
79+
80+
memcpy_s(ucode_ptr, chunk_size, (uint8_t *)hva, chunk_size);
81+
82+
data_size -= chunk_size;
83+
if (data_size <= 0)
84+
break;
85+
86+
ucode_ptr += chunk_size;
87+
gva += chunk_size;
88+
89+
vm_gva2gpa(vcpu, gva, &gpa);
90+
hva = (uint64_t)GPA2HVA(vcpu->vm, gpa);
91+
}
92+
93+
msr_write(MSR_IA32_BIOS_UPDT_TRIG,
94+
(uint64_t)ptr + sizeof(struct ucode_header));
95+
get_microcode_version();
96+
97+
free(ucode_ptr);
98+
}

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@
3232
#include <acrn_common.h>
3333
#include <hv_arch.h>
3434
#include <hv_debug.h>
35+
#include <ucode.h>
3536

3637
/*MRS need to be emulated, the order in this array better as freq of ops*/
3738
static const uint32_t emulated_msrs[] = {
3839
MSR_IA32_TSC_DEADLINE, /* Enable TSC_DEADLINE VMEXIT */
40+
MSR_IA32_BIOS_UPDT_TRIG, /* Enable MSR_IA32_BIOS_UPDT_TRIG */
41+
MSR_IA32_BIOS_SIGN_ID, /* Enable MSR_IA32_BIOS_SIGN_ID */
42+
3943

4044
/* following MSR not emulated now */
4145
/*
@@ -51,6 +55,8 @@ static const uint32_t emulated_msrs[] = {
5155
/* the index is matched with emulated msrs array*/
5256
enum {
5357
IDX_TSC_DEADLINE,
58+
IDX_BIOS_UPDT_TRIG,
59+
IDX_BIOS_SIGN_ID,
5460

5561
IDX_MAX_MSR
5662
};
@@ -185,6 +191,11 @@ int rdmsr_handler(struct vcpu *vcpu)
185191
vcpu_inject_gp(vcpu);
186192
break;
187193
}
194+
case MSR_IA32_BIOS_SIGN_ID:
195+
{
196+
v = get_microcode_version();
197+
break;
198+
}
188199

189200
/* following MSR not emulated now just left for future */
190201
case MSR_IA32_SYSENTER_CS:
@@ -273,6 +284,17 @@ int wrmsr_handler(struct vcpu *vcpu)
273284
vcpu_inject_gp(vcpu);
274285
break;
275286
}
287+
case MSR_IA32_BIOS_SIGN_ID:
288+
{
289+
break;
290+
}
291+
case MSR_IA32_BIOS_UPDT_TRIG:
292+
{
293+
/* We only allow SOS to do uCode update */
294+
if (is_vm0(vcpu->vm))
295+
acrn_update_ucode(vcpu, v);
296+
break;
297+
}
276298

277299
/* following MSR not emulated now just left for future */
278300
case MSR_IA32_SYSENTER_CS:

hypervisor/include/arch/x86/guest/guest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ bool vm_lapic_disabled(struct vm *vm);
8484
uint64_t vcpumask2pcpumask(struct vm *vm, uint64_t vdmask);
8585

8686
uint64_t gva2gpa(struct vm *vm, uint64_t cr3, uint64_t gva);
87+
void vm_gva2gpa(struct vcpu *vcpu, uint64_t gla, uint64_t *gpa);
8788

8889
struct vcpu *get_primary_vcpu(struct vm *vm);
8990
struct vcpu *vcpu_from_vid(struct vm *vm, int vcpu_id);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in
12+
* the documentation and/or other materials provided with the
13+
* distribution.
14+
* * Neither the name of Intel Corporation nor the names of its
15+
* contributors may be used to endorse or promote products derived
16+
* from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
31+
#ifndef _ARCH_X86_UCODE_H
32+
#define _ARCH_X86_UCODE_H
33+
34+
struct ucode_header {
35+
uint32_t header_ver;
36+
uint32_t update_ver;
37+
uint32_t date;
38+
uint32_t proc_sig;
39+
uint32_t checksum;
40+
uint32_t loader_ver;
41+
uint32_t proc_flags;
42+
uint32_t data_size;
43+
uint32_t total_size;
44+
uint32_t reserved[3];
45+
};
46+
47+
void acrn_update_ucode(struct vcpu *vcpu, uint64_t v);
48+
uint64_t get_microcode_version(void);
49+
50+
#endif

0 commit comments

Comments
 (0)