[RFC PATCH part-5 21/22] pkvm: x86: Initialize msr_bitmap for vmsr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Introduce enable_msr_interception API to init msr_bitmap, based on it
pKVM can setup the virtual MSR list which need to be trapped and
emulated in the hypervisor.

Signed-off-by: Chuanxiao Dong <chuanxiao.dong@xxxxxxxxx>
Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx>
---
 arch/x86/kvm/vmx/pkvm/hyp/Makefile   |  2 +-
 arch/x86/kvm/vmx/pkvm/hyp/vmexit.c   | 13 +----
 arch/x86/kvm/vmx/pkvm/hyp/vmsr.c     | 73 ++++++++++++++++++++++++++++
 arch/x86/kvm/vmx/pkvm/hyp/vmsr.h     | 11 +++++
 arch/x86/kvm/vmx/pkvm/include/pkvm.h |  2 +
 arch/x86/kvm/vmx/pkvm/pkvm_host.c    |  1 +
 6 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kvm/vmx/pkvm/hyp/Makefile b/arch/x86/kvm/vmx/pkvm/hyp/Makefile
index ca6d43509ddc..fc75cdd9fc79 100644
--- a/arch/x86/kvm/vmx/pkvm/hyp/Makefile
+++ b/arch/x86/kvm/vmx/pkvm/hyp/Makefile
@@ -12,7 +12,7 @@ ccflags-y += -D__PKVM_HYP__
 virt-dir	:= ../../../../../../$(KVM_PKVM)
 
 pkvm-hyp-y	:= vmx_asm.o vmexit.o memory.o early_alloc.o pgtable.o mmu.o pkvm.o \
-		   init_finalise.o ept.o idt.o irq.o nested.o vmx.o
+		   init_finalise.o ept.o idt.o irq.o nested.o vmx.o vmsr.o
 
 ifndef CONFIG_PKVM_INTEL_DEBUG
 lib-dir		:= lib
diff --git a/arch/x86/kvm/vmx/pkvm/hyp/vmexit.c b/arch/x86/kvm/vmx/pkvm/hyp/vmexit.c
index 8e7392010887..307514f44ec9 100644
--- a/arch/x86/kvm/vmx/pkvm/hyp/vmexit.c
+++ b/arch/x86/kvm/vmx/pkvm/hyp/vmexit.c
@@ -9,6 +9,7 @@
 #include "vmexit.h"
 #include "ept.h"
 #include "pkvm_hyp.h"
+#include "vmsr.h"
 #include "nested.h"
 #include "debug.h"
 
@@ -109,18 +110,6 @@ static unsigned long handle_vmcall(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
-static void handle_read_msr(struct kvm_vcpu *vcpu)
-{
-	/* simply return 0 for non-supported MSRs */
-	vcpu->arch.regs[VCPU_REGS_RAX] = 0;
-	vcpu->arch.regs[VCPU_REGS_RDX] = 0;
-}
-
-static void handle_write_msr(struct kvm_vcpu *vcpu)
-{
-	/*No emulation for msr write now*/
-}
-
 static void handle_xsetbv(struct kvm_vcpu *vcpu)
 {
 	u32 eax = (u32)(vcpu->arch.regs[VCPU_REGS_RAX] & -1u);
diff --git a/arch/x86/kvm/vmx/pkvm/hyp/vmsr.c b/arch/x86/kvm/vmx/pkvm/hyp/vmsr.c
new file mode 100644
index 000000000000..360b0333b84f
--- /dev/null
+++ b/arch/x86/kvm/vmx/pkvm/hyp/vmsr.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/*
+ * Copyright (C) 2018-2022 Intel Corporation
+ */
+
+#include <pkvm.h>
+#include "cpu.h"
+#include "debug.h"
+
+#define INTERCEPT_DISABLE		(0U)
+#define INTERCEPT_READ			(1U << 0U)
+#define INTERCEPT_WRITE			(1U << 1U)
+#define INTERCEPT_READ_WRITE		(INTERCEPT_READ | INTERCEPT_WRITE)
+
+static unsigned int emulated_ro_guest_msrs[] = {
+	/* DUMMY */
+};
+
+static void enable_msr_interception(u8 *bitmap, unsigned int msr_arg, unsigned int mode)
+{
+	unsigned int read_offset = 0U;
+	unsigned int write_offset = 2048U;
+	unsigned int msr = msr_arg;
+	u8 msr_bit;
+	unsigned int msr_index;
+
+	if ((msr <= 0x1FFFU) || ((msr >= 0xc0000000U) && (msr <= 0xc0001fffU))) {
+		if ((msr & 0xc0000000U) != 0U) {
+			read_offset = read_offset + 1024U;
+			write_offset = write_offset + 1024U;
+		}
+
+		msr &= 0x1FFFU;
+		msr_bit = (u8)(1U << (msr & 0x7U));
+		msr_index = msr >> 3U;
+
+		if ((mode & INTERCEPT_READ) == INTERCEPT_READ)
+			bitmap[read_offset + msr_index] |= msr_bit;
+		else
+			bitmap[read_offset + msr_index] &= ~msr_bit;
+
+		if ((mode & INTERCEPT_WRITE) == INTERCEPT_WRITE)
+			bitmap[write_offset + msr_index] |= msr_bit;
+		else
+			bitmap[write_offset + msr_index] &= ~msr_bit;
+	} else {
+		pkvm_err("%s, Invalid MSR: 0x%x", __func__, msr);
+	}
+}
+
+int handle_read_msr(struct kvm_vcpu *vcpu)
+{
+	/* simply return 0 for non-supported MSRs */
+	vcpu->arch.regs[VCPU_REGS_RAX] = 0;
+	vcpu->arch.regs[VCPU_REGS_RDX] = 0;
+
+	return 0;
+}
+
+int handle_write_msr(struct kvm_vcpu *vcpu)
+{
+	/*No emulation for msr write now*/
+	return 0;
+}
+
+void init_msr_emulation(struct vcpu_vmx *vmx)
+{
+	int i;
+	u8 *bitmap = (u8 *)vmx->loaded_vmcs->msr_bitmap;
+
+	for (i = 0; i < ARRAY_SIZE(emulated_ro_guest_msrs); i++)
+		enable_msr_interception(bitmap, emulated_ro_guest_msrs[i], INTERCEPT_READ);
+}
diff --git a/arch/x86/kvm/vmx/pkvm/hyp/vmsr.h b/arch/x86/kvm/vmx/pkvm/hyp/vmsr.h
new file mode 100644
index 000000000000..1f39a37996f4
--- /dev/null
+++ b/arch/x86/kvm/vmx/pkvm/hyp/vmsr.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Intel Corporation
+ */
+#ifndef _PKVM_VMSR_H_
+#define _PKVM_VMSR_H_
+
+int handle_read_msr(struct kvm_vcpu *vcpu);
+int handle_write_msr(struct kvm_vcpu *vcpu);
+
+#endif
diff --git a/arch/x86/kvm/vmx/pkvm/include/pkvm.h b/arch/x86/kvm/vmx/pkvm/include/pkvm.h
index 9b45627853b3..59bbe645baaa 100644
--- a/arch/x86/kvm/vmx/pkvm/include/pkvm.h
+++ b/arch/x86/kvm/vmx/pkvm/include/pkvm.h
@@ -106,6 +106,8 @@ PKVM_DECLARE(void *, pkvm_early_alloc_contig(unsigned int nr_pages));
 PKVM_DECLARE(void *, pkvm_early_alloc_page(void));
 PKVM_DECLARE(void, pkvm_early_alloc_init(void *virt, unsigned long size));
 
+PKVM_DECLARE(void, init_msr_emulation(struct vcpu_vmx *vmx));
+
 PKVM_DECLARE(void, noop_handler(void));
 PKVM_DECLARE(void, nmi_handler(void));
 
diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
index cbba3033ba63..90d7cddde9ef 100644
--- a/arch/x86/kvm/vmx/pkvm/pkvm_host.c
+++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
@@ -280,6 +280,7 @@ static __init void init_execution_control(struct vcpu_vmx *vmx,
 	/* guest handles exception directly */
 	vmcs_write32(EXCEPTION_BITMAP, 0);
 
+	pkvm_sym(init_msr_emulation(vmx));
 	vmcs_write64(MSR_BITMAP, __pa(vmx->vmcs01.msr_bitmap));
 
 	/*
-- 
2.25.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux