Re: [PATCH] microcode: Enable microcode update from SOS.


Yin, Fengwei <fengwei.yin@...>
 

On 03/14/2018 02:57 PM, Tian, Kevin wrote:
From: Dong, Eddie
Sent: Wednesday, March 14, 2018 2:50 PM

Not sure if clear bit 63 is an architectural requirement or not.

+ Kevin.
I didn't understand. In 64bit mode, all 64bits are available. If
bit63 is cleared how can you find a valid gpa for it?
Here is what I got:
bit63 of the line address is actually not used for now.
With 4-level paging, the PML4 entry is selected using:
bits 51:12 from CR3
bits 11:3 are from bits 47:39 of liner address.
bits 2:0 are all 0.

With 5-level paging, the PML5 entry is selected using:
bits 51:12 are from CR3
bits 11:3 are bits 56:48 of the line address.
bits 2:0 are all 0.

Also from "5-level paging and 5-Level EPT" White Paper:
A linear address is 48-bit canonical if bits 63:47 of the address are identical.
Similarly, an address is 57-bit canonical if bits 63:56 of the address are identical. Any
linear address is that 48-bit canonical is also 57-bit canonical.


But I do think we shouldn't clear 63bit now even it could work for now.
Will update the patch.

Regards
Yin, Fengwei



-----Original Message-----
From: Yin, Fengwei
Sent: Tuesday, March 13, 2018 10:48 PM
To: Dong, Eddie <eddie.dong@...>
Cc: acrn-dev@...
Subject: Re: [acrn-dev] [PATCH] microcode: Enable microcode update
from
SOS.

On Wed, Mar 14, 2018 at 01:38:40PM +0800, Dong, Eddie wrote:
That is stranger... We use identical mapping for VM0, right? Anyway, it
is ok
to leave as it is.
Yes. We are using identical mapping for VM0. But Linux kernel uses
vmalloc
to allocate memory to load uCode itself.

But I did try changing vmalloc to kmalloc in kernel. The uCode update still
failed.
I could test it again to double check whether the failure is related with
vmalloc.


BTW, why:
gva = v & IA32E_REF_MASK;
It clears bit 63.
Because we copy uCode per PAGE, gva is used to get the PAGE_SIZE
aligned
base address.
v is an address. So its bit 63 should be zero and we could use
IA32E_REF_MASK directly.

Regards
Yin, Fengwei


The rest is fine to me.
Thx Eddie

-----Original Message-----
From: Yin, Fengwei
Sent: Tuesday, March 13, 2018 10:12 PM
To: acrn-dev@...
Cc: Dong, Eddie <eddie.dong@...>
Subject: Re: [acrn-dev] [PATCH] microcode: Enable microcode update
from SOS.

On Wed, Mar 14, 2018 at 04:02:10AM +0000, Eddie Dong wrote:
Can we bypass the uCode update process for VM0? Why we need to
intercept?
Tried bypass the uCode update for VM0. But it doesn't work.

Regards
Yin, Fengwei


Thx Eddie

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of
fengwei.yin@...
Sent: Tuesday, March 13, 2018 7:19 PM
To: acrn-dev@...
Cc: Yin, Fengwei <fengwei.yin@...>
Subject: [acrn-dev] [PATCH] microcode: Enable microcode update
from
SOS.

From: Yin Fengwei <fengwei.yin@...>

microcode update from UOS is disabled.
microcode version checking is available for both SOS and UOS.

Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
Makefile | 1 +
arch/x86/guest/instr_emul_wrapper.h | 1 -
arch/x86/guest/ucode.c | 94
+++++++++++++++++++++++++++++++++++++
arch/x86/guest/vmsr.c | 23 +++++++++
include/arch/x86/guest/guest.h | 1 +
include/arch/x86/guest/ucode.h | 50
++++++++++++++++++++
6 files changed, 169 insertions(+), 1 deletion(-) create mode
100644 arch/x86/guest/ucode.c create mode 100644
include/arch/x86/guest/ucode.h

diff --git a/Makefile b/Makefile index c0a7d06..d65e0c1 100644
--- a/Makefile
+++ b/Makefile
@@ -128,6 +128,7 @@ C_SRCS += arch/x86/guest/vpic.c C_SRCS
+=
arch/x86/guest/vmsr.c C_SRCS += arch/x86/guest/vioapic.c
C_SRCS
+=
arch/x86/guest/instr_emul.c
+C_SRCS += arch/x86/guest/ucode.c
C_SRCS += lib/spinlock.c
C_SRCS += lib/udelay.c
C_SRCS += lib/strnlen.c
diff --git a/arch/x86/guest/instr_emul_wrapper.h
b/arch/x86/guest/instr_emul_wrapper.h
index 3581e9b..48e311f 100644
--- a/arch/x86/guest/instr_emul_wrapper.h
+++ b/arch/x86/guest/instr_emul_wrapper.h
@@ -200,4 +200,3 @@ int vm_get_seg_desc(struct vcpu *vcpu, int
reg, int vm_set_seg_desc(struct vcpu *vcpu, int reg,
struct seg_desc *desc);
int vm_restart_instruction(struct vcpu *vcpu); -void
vm_gva2gpa(struct vcpu *vcpu, uint64_t gla, uint64_t *gpa); diff
--git a/arch/x86/guest/ucode.c b/arch/x86/guest/ucode.c new file
mode 100644 index 0000000..8104e0d
--- /dev/null
+++ b/arch/x86/guest/ucode.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+without
+ * modification, are permitted provided that the following
+conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products
derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
AND
CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING,
BUT
NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND
FITNESS
+FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE
COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT,
+INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING,
BUT
NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES;
LOSS
OF
+USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED
AND ON
+ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY,
+OR
TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY
OUT OF
THE
+USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH
DAMAGE.
+ */
+
+#include <hv_lib.h>
+#include <acrn_common.h>
+#include <hv_arch.h>
+#include <hv_debug.h>
+#include <ucode.h>
+
+uint64_t get_microcode_version(void) {
+ uint64_t val;
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+ msr_write(MSR_IA32_BIOS_SIGN_ID, 0);
+ native_cpuid_count(CPUID_FEATURES, 0, &eax, &ebx, &ecx,
&edx);
+ val = msr_read(MSR_IA32_BIOS_SIGN_ID);
+
+ return val;
+}
+
+#define GET_DATA_SIZE(hdptr) ((hdptr)->data_size ? : 2000)
+void acrn_update_ucode(struct vcpu *vcpu, uint64_t v) {
+ uint64_t hva, gpa, gva;
+ struct ucode_header *uhdr;
+ int data_size, data_page_num;
+ uint8_t *ptr, *ucode_ptr;
+
+ /* gva will be used as iterator to copy uCode to HV buffer.
+ * It will be aligned to CPU_PAGE_SIZE of v, increased
+ * by CPU_PAGE_SIZE and convert to hva for each step.
+ */
+ gva = v & IA32E_REF_MASK;
+
+ vm_gva2gpa(vcpu, v, &gpa);
+ hva = (uint64_t)GPA2HVA(vcpu->vm, gpa);
+
+ /* hva is used to get uhdr here */
+ uhdr = (struct ucode_header *)(hva - sizeof(struct
+ucode_header));
+
+ data_size = GET_DATA_SIZE(uhdr) + sizeof(struct
ucode_header) +
+ ((uint64_t)uhdr & (CPU_PAGE_SIZE - 1));
+ data_page_num =
+ (data_size + CPU_PAGE_SIZE - 1) >>
CPU_PAGE_SHIFT;
+
+ ptr = ucode_ptr = alloc_pages(data_page_num);
+ if (ptr == NULL)
+ return;
+
+ hva = hva & IA32E_REF_MASK;
+ while (data_page_num--) {
+ memcpy_s(ptr, CPU_PAGE_SIZE, (void *)hva,
CPU_PAGE_SIZE);
+
+ ptr += CPU_PAGE_SIZE;
+ gva += CPU_PAGE_SIZE;
+
+ vm_gva2gpa(vcpu, gva, &gpa);
+ hva = (uint64_t)GPA2HVA(vcpu->vm, gpa);
+ }
+
+ msr_write(MSR_IA32_BIOS_UPDT_TRIG,
+ (uint64_t)ucode_ptr + (v & (CPU_PAGE_SIZE
- 1)));
+ get_microcode_version();
+
+ free(ucode_ptr);
+}
diff --git a/arch/x86/guest/vmsr.c b/arch/x86/guest/vmsr.c index
7be4a45..4bf8df3 100644
--- a/arch/x86/guest/vmsr.c
+++ b/arch/x86/guest/vmsr.c
@@ -32,10 +32,13 @@
#include <acrn_common.h>
#include <hv_arch.h>
#include <hv_debug.h>
+#include <ucode.h>

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

/* following MSR not emulated now */
/*
@@ -51,6 +54,7 @@ static const uint32_t emulated_msrs[] = {
/* the index is matched with emulated msrs array*/ enum {
IDX_TSC_DEADLINE,
+ IDX_BIOS_SIGN_ID,

IDX_MAX_MSR
};
@@ -129,6 +133,11 @@ void init_msr_emulation(struct vcpu
*vcpu)
for (i = 0; i < msrs_count; i++)
enable_msr_interception(msr_bitmap,
emulated_msrs[i]);

+ /* Only enable uCode update for SOS */
+ if (is_vm0(vcpu->vm))
+ enable_msr_interception(msr_bitmap,
+ MSR_IA32_BIOS_UPDT_TRIG);
+
/* below MSR protected from guest OS, if access to
inject
gp*/
enable_msr_interception(msr_bitmap,
MSR_IA32_MTRR_CAP);
enable_msr_interception(msr_bitmap,
MSR_IA32_MTRR_DEF_TYPE); @@ -191,6 +200,11 @@ int
rdmsr_handler(struct vcpu *vcpu)
vcpu_inject_gp(vcpu);
break;
}
+ case MSR_IA32_BIOS_SIGN_ID:
+ {
+ v = get_microcode_version();
+ break;
+ }

/* following MSR not emulated now just left for future */
case MSR_IA32_SYSENTER_CS:
@@ -281,6 +295,15 @@ int wrmsr_handler(struct vcpu *vcpu)
vcpu_inject_gp(vcpu);
break;
}
+ case MSR_IA32_BIOS_SIGN_ID:
+ {
+ break;
+ }
+ case MSR_IA32_BIOS_UPDT_TRIG:
+ {
+ acrn_update_ucode(vcpu, v);
+ break;
+ }

/* following MSR not emulated now just left for future */
case MSR_IA32_SYSENTER_CS:
diff --git a/include/arch/x86/guest/guest.h
b/include/arch/x86/guest/guest.h index 794699f..fe3be5b 100644
--- a/include/arch/x86/guest/guest.h
+++ b/include/arch/x86/guest/guest.h
@@ -76,6 +76,7 @@ bool vm_lapic_disabled(struct vm *vm);
uint64_t vcpumask2pcpumask(struct vm *vm, uint64_t vdmask);

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

struct vcpu *get_primary_vcpu(struct vm *vm); struct vcpu
*vcpu_from_vid(struct vm *vm, int vcpu_id); diff --git
a/include/arch/x86/guest/ucode.h
b/include/arch/x86/guest/ucode.h new file mode 100644 index
0000000..64df181
--- /dev/null
+++ b/include/arch/x86/guest/ucode.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+without
+ * modification, are permitted provided that the following
+conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products
derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
AND
CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING,
BUT
NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND
FITNESS
+FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE
COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT,
+INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING,
BUT
NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES;
LOSS
OF
+USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED
AND ON
+ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY,
+OR
TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY
OUT OF
THE
+USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH
DAMAGE.
+ */
+
+#ifndef _ARCH_X86_UCODE_H
+#define _ARCH_X86_UCODE_H
+
+struct ucode_header {
+ uint32_t header_ver;
+ uint32_t update_ver;
+ uint32_t data;
+ uint32_t proc_sig;
+ uint32_t checksum;
+ uint32_t loader_ver;
+ uint32_t proc_flags;
+ uint32_t data_size;
+ uint32_t total_size;
+ uint32_t reserved[3];
+};
+
+void acrn_update_ucode(struct vcpu *vcpu, uint64_t v); uint64_t
+get_microcode_version(void);
+
+#endif
--
2.7.4



Join {acrn-dev@lists.projectacrn.org to automatically receive all group messages.