[RFC PATCH part-2 01/17] pkvm: x86: Introduce CONFIG_PKVM_INTEL

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

 



Add CONFIG_PKVM_INTEL configuration to enable or disable pKVM feature on
x86 platform (starting from Intel platform), and do pkvm_init as
an extension of KVM. Now pkvm_init only reserves memory for pkvm data
structure and does a quick setup for num_cpus.

New pKVM on Intel platform files are placed under arch/x86/kvm/vmx/pkvm.

Signed-off-by: Jason Chen CJ <jason.cj.chen@xxxxxxxxx>
---
 arch/x86/include/asm/kvm_host.h      |  1 +
 arch/x86/kvm/Kconfig                 | 13 +++++++++++
 arch/x86/kvm/Makefile                |  1 +
 arch/x86/kvm/vmx/pkvm/Makefile       |  7 ++++++
 arch/x86/kvm/vmx/pkvm/include/pkvm.h | 15 ++++++++++++
 arch/x86/kvm/vmx/pkvm/pkvm_host.c    | 34 ++++++++++++++++++++++++++++
 arch/x86/kvm/vmx/vmx.c               |  3 +++
 arch/x86/kvm/vmx/vmx.h               |  4 ++++
 arch/x86/kvm/x86.c                   |  5 ++++
 9 files changed, 83 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 6aaae18f1854..c3cf849a1370 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1731,6 +1731,7 @@ struct kvm_x86_nested_ops {
 };
 
 struct kvm_x86_init_ops {
+	int (*pkvm_init)(void);
 	int (*cpu_has_kvm_support)(void);
 	int (*disabled_by_bios)(void);
 	int (*check_processor_compatibility)(void);
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index fbeaa9ddef59..5a8ae5f80849 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -87,6 +87,19 @@ config KVM_INTEL
 	  To compile this as a module, choose M here: the module
 	  will be called kvm-intel.
 
+config PKVM_INTEL
+	bool "pKVM for Intel processors support"
+	depends on KVM_INTEL=y
+	depends on X86_64
+	help
+	  Provides support for pKVM on Intel processors.
+
+	  This will deprivilege the host as a VM running in non-root VMX
+	  operation mode, and pKVM hypervisor will run in root VMX
+	  operation mode.
+
+	  If unsure, say N.
+
 config X86_SGX_KVM
 	bool "Software Guard eXtensions (SGX) Virtualization"
 	depends on X86_SGX && KVM_INTEL
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 80e3fe184d17..7fbca5cc7c1d 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -35,6 +35,7 @@ endif
 
 obj-$(CONFIG_KVM)	+= kvm.o
 obj-$(CONFIG_KVM_INTEL)	+= kvm-intel.o
+obj-$(CONFIG_PKVM_INTEL) += vmx/pkvm/
 obj-$(CONFIG_KVM_AMD)	+= kvm-amd.o
 
 AFLAGS_svm/vmenter.o    := -iquote $(obj)
diff --git a/arch/x86/kvm/vmx/pkvm/Makefile b/arch/x86/kvm/vmx/pkvm/Makefile
new file mode 100644
index 000000000000..493bec8501c9
--- /dev/null
+++ b/arch/x86/kvm/vmx/pkvm/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+ccflags-y += -I $(srctree)/arch/x86/kvm/vmx/pkvm/include
+
+pkvm-obj		:= pkvm_host.o
+
+obj-$(CONFIG_PKVM_INTEL)	+= $(pkvm-obj)
diff --git a/arch/x86/kvm/vmx/pkvm/include/pkvm.h b/arch/x86/kvm/vmx/pkvm/include/pkvm.h
new file mode 100644
index 000000000000..3fb76665e785
--- /dev/null
+++ b/arch/x86/kvm/vmx/pkvm/include/pkvm.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#ifndef _PKVM_H_
+#define _PKVM_H_
+
+struct pkvm_hyp {
+	int num_cpus;
+};
+
+#define PKVM_PAGES (ALIGN(sizeof(struct pkvm_hyp), PAGE_SIZE) >> PAGE_SHIFT)
+
+#endif
diff --git a/arch/x86/kvm/vmx/pkvm/pkvm_host.c b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
new file mode 100644
index 000000000000..7677df6a2b34
--- /dev/null
+++ b/arch/x86/kvm/vmx/pkvm/pkvm_host.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <pkvm.h>
+
+MODULE_LICENSE("GPL");
+
+static struct pkvm_hyp *pkvm;
+
+static void *pkvm_early_alloc_contig(int pages)
+{
+	return alloc_pages_exact(pages << PAGE_SHIFT, GFP_KERNEL | __GFP_ZERO);
+}
+
+__init int pkvm_init(void)
+{
+	int ret = 0;
+
+	pkvm = pkvm_early_alloc_contig(PKVM_PAGES);
+	if (!pkvm) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pkvm->num_cpus = num_possible_cpus();
+
+out:
+	return ret;
+}
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 7eec0226d56a..1e55bde497f8 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -8467,6 +8467,9 @@ static __init int hardware_setup(void)
 }
 
 static struct kvm_x86_init_ops vmx_init_ops __initdata = {
+#ifdef CONFIG_PKVM_INTEL
+	.pkvm_init = pkvm_init,
+#endif
 	.cpu_has_kvm_support = cpu_has_kvm_support,
 	.disabled_by_bios = vmx_disabled_by_bios,
 	.check_processor_compatibility = vmx_check_processor_compat,
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index a3da84f4ea45..8b2c4f1f4c8e 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -752,4 +752,8 @@ static inline bool guest_cpuid_has_evmcs(struct kvm_vcpu *vcpu)
 	       to_vmx(vcpu)->nested.enlightened_vmcs_enabled;
 }
 
+#ifdef CONFIG_PKVM_INTEL
+int __init pkvm_init(void);
+#endif
+
 #endif /* __KVM_X86_VMX_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a2c299d47e69..84ddeabbf94b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9312,6 +9312,11 @@ int kvm_arch_init(void *opaque)
 		return -EOPNOTSUPP;
 	}
 
+	if (ops->pkvm_init && ops->pkvm_init()) {
+		pr_err_ratelimited("kvm: pkvm init fail\n");
+		return -EOPNOTSUPP;
+	}
+
 	/*
 	 * KVM explicitly assumes that the guest has an FPU and
 	 * FXSAVE/FXRSTOR. For example, the KVM_GET_FPU explicitly casts the
-- 
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