@@ -341,7 +341,7 @@ CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_DEV_VMX=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
-CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_KVM_BOOK3S_HV_POSSIBLE=y
CONFIG_VHOST_NET=m
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
@@ -61,7 +61,7 @@ CONFIG_PCCARD=y
CONFIG_ELECTRA_CF=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
-CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_KVM_BOOK3S_HV_POSSIBLE=y
CONFIG_VHOST_NET=m
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
@@ -321,7 +321,7 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
CONFIG_CRYPTO_DEV_VMX=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_BOOK3S_64=m
-CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_KVM_BOOK3S_HV_POSSIBLE=y
CONFIG_VHOST_NET=m
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
@@ -41,12 +41,43 @@ config KVM_BOOK3S_64_HANDLER
select PPC_DAWR_FORCE_ENABLE
config KVM_BOOK3S_PR_POSSIBLE
- bool
+ bool "KVM support without using hypervisor mode in host"
+ depends on KVM_BOOK3S_64 || KVM_BOOK3S_32
select KVM_MMIO
select MMU_NOTIFIER
+ help
+ Support running guest kernels in virtual machines on processors
+ without using hypervisor mode in the host, by running the
+ guest in user mode (problem state) and emulating all
+ privileged instructions and registers.
+
+ This is not as fast as using hypervisor mode, but works on
+ where hypervisor mode is not available or not usable,
+ and can emulate processors that are different from the host
+ processor, including emulating 32-bit processors on a 64-bit
+ host.
+
config KVM_BOOK3S_HV_POSSIBLE
- bool
+ bool "KVM for POWER7 and later using hypervisor mode in host"
+ depends on KVM_BOOK3S_64
+ select MMU_NOTIFIER
+ select CMA
+ help
+ Support running unmodified book3s_64 guest kernels in
+ virtual machines on POWER7 and newer processors that have
+ hypervisor mode available to the host.
+
+ If you say Y here, KVM will use the hardware virtualization
+ facilities of POWER7 (and later) processors, meaning that
+ guest operating systems will run at full hardware speed
+ using supervisor and user modes. However, this also means
+ that KVM is not usable under PowerVM (pHyp), is only usable
+ on POWER7 or later processors, and cannot emulate a
+ different processor from the host processor.
+
+ If unsure, say N.
+
config KVM_BOOK3S_32
tristate "KVM support for PowerPC book3s_32 processors"
@@ -80,43 +111,6 @@ config KVM_BOOK3S_64
If unsure, say N.
-config KVM_BOOK3S_64_HV
- tristate "KVM for POWER7 and later using hypervisor mode in host"
- depends on KVM_BOOK3S_64 && PPC_POWERNV
- select KVM_BOOK3S_HV_POSSIBLE
- select MMU_NOTIFIER
- select CMA
- help
- Support running unmodified book3s_64 guest kernels in
- virtual machines on POWER7 and newer processors that have
- hypervisor mode available to the host.
-
- If you say Y here, KVM will use the hardware virtualization
- facilities of POWER7 (and later) processors, meaning that
- guest operating systems will run at full hardware speed
- using supervisor and user modes. However, this also means
- that KVM is not usable under PowerVM (pHyp), is only usable
- on POWER7 or later processors, and cannot emulate a
- different processor from the host processor.
-
- If unsure, say N.
-
-config KVM_BOOK3S_64_PR
- tristate "KVM support without using hypervisor mode in host"
- depends on KVM_BOOK3S_64
- select KVM_BOOK3S_PR_POSSIBLE
- help
- Support running guest kernels in virtual machines on processors
- without using hypervisor mode in the host, by running the
- guest in user mode (problem state) and emulating all
- privileged instructions and registers.
-
- This is not as fast as using hypervisor mode, but works on
- machines where hypervisor mode is not available or not usable,
- and can emulate processors that are different from the host
- processor, including emulating 32-bit processors on a 64-bit
- host.
-
config KVM_BOOK3S_HV_EXIT_TIMING
bool "Detailed timing for hypervisor real-mode code"
depends on KVM_BOOK3S_HV_POSSIBLE && DEBUG_FS
@@ -108,6 +108,14 @@ kvm-book3s_64-module-objs := \
book3s_rtas.o \
$(kvm-book3s_64-objs-y)
+ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+kvm-book3s_64-module-objs += $(kvm-hv-y)
+endif
+
+ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
+kvm-book3s_64-module-objs += $(kvm-pr-y)
+endif
+
kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs)
kvm-book3s_32-objs := \
@@ -134,7 +142,4 @@ obj-$(CONFIG_KVM_E500MC) += kvm.o
obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o
obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o
-obj-$(CONFIG_KVM_BOOK3S_64_PR) += kvm-pr.o
-obj-$(CONFIG_KVM_BOOK3S_64_HV) += kvm-hv.o
-
obj-y += $(kvm-book3s_64-builtin-objs-y)
@@ -1065,6 +1065,24 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
#endif /* CONFIG_KVM_XICS */
+static int kvmppc_init(void)
+{
+ int r;
+
+ r = kvmppc_book3s_init_hv();
+ if (r)
+ pr_err("KVM-HV: could not load (%d)\n", r);
+
+ r = kvmppc_book3s_init_pr();
+ if (r)
+ pr_err("KVM-PR: could not load (%d)\n", r);
+
+ if (!kvmppc_hv_ops && !kvmppc_pr_ops)
+ return -EINVAL;
+
+ return 0;
+}
+
static int kvmppc_book3s_init(void)
{
int r;
@@ -1072,9 +1090,10 @@ static int kvmppc_book3s_init(void)
r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
if (r)
return r;
-#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
- r = kvmppc_book3s_init_pr();
-#endif
+
+ r = kvmppc_init();
+ if (r)
+ goto exit;
#ifdef CONFIG_KVM_XICS
#ifdef CONFIG_KVM_XIVE
@@ -1087,22 +1106,35 @@ static int kvmppc_book3s_init(void)
#endif
kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS);
#endif
+ return 0;
+
+exit:
+ kvm_exit();
return r;
}
static void kvmppc_book3s_exit(void)
{
-#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
kvmppc_book3s_exit_pr();
-#endif
+ kvmppc_book3s_exit_hv();
kvm_exit();
}
module_init(kvmppc_book3s_init);
module_exit(kvmppc_book3s_exit);
-/* On 32bit this is our one and only kernel module */
-#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
MODULE_ALIAS_MISCDEV(KVM_MINOR);
MODULE_ALIAS("devname:kvm");
+
+/*
+ * Whether we use KVM-HV or KVM-PR is dependent exclusively on the
+ * config options. These aliases are here only to ease the transition
+ * to the one module model we have now.
+ */
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+MODULE_ALIAS("kvm-hv");
+#endif
+
+#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
+MODULE_ALIAS("kvm-pr");
#endif
@@ -22,8 +22,27 @@ extern int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu,
int sprn, ulong spr_val);
extern int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu,
int sprn, ulong *spr_val);
+#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
extern int kvmppc_book3s_init_pr(void);
extern void kvmppc_book3s_exit_pr(void);
+#else
+static inline int kvmppc_book3s_init_pr(void)
+{
+ return 0;
+}
+static inline void kvmppc_book3s_exit_pr(void) {}
+#endif
+
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+extern int kvmppc_book3s_init_hv(void);
+extern void kvmppc_book3s_exit_hv(void);
+#else
+static inline int kvmppc_book3s_init_hv(void)
+{
+ return 0;
+}
+static inline void kvmppc_book3s_exit_hv(void) {}
+#endif
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
extern void kvmppc_emulate_tabort(struct kvm_vcpu *vcpu, int ra_val);
@@ -5941,7 +5941,7 @@ static int kvmppc_radix_possible(void)
return cpu_has_feature(CPU_FTR_ARCH_300) && radix_enabled();
}
-static int kvmppc_book3s_init_hv(void)
+int kvmppc_book3s_init_hv(void)
{
int r;
@@ -6018,7 +6018,7 @@ static int kvmppc_book3s_init_hv(void)
return r;
}
-static void kvmppc_book3s_exit_hv(void)
+void kvmppc_book3s_exit_hv(void)
{
kvmppc_uvmem_free();
kvmppc_free_host_rm_ops();
@@ -6027,9 +6027,3 @@ static void kvmppc_book3s_exit_hv(void)
kvmppc_hv_ops = NULL;
kvmhv_nested_exit();
}
-
-module_init(kvmppc_book3s_init_hv);
-module_exit(kvmppc_book3s_exit_hv);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(KVM_MINOR);
-MODULE_ALIAS("devname:kvm");
@@ -2100,16 +2100,3 @@ void kvmppc_book3s_exit_pr(void)
kvmppc_pr_ops = NULL;
kvmppc_mmu_hpte_sysexit();
}
-
-/*
- * We only support separate modules for book3s 64
- */
-#ifdef CONFIG_PPC_BOOK3S_64
-
-module_init(kvmppc_book3s_init_pr);
-module_exit(kvmppc_book3s_exit_pr);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(KVM_MINOR);
-MODULE_ALIAS("devname:kvm");
-#endif
@@ -352,7 +352,7 @@ struct irq_desc *irq_to_desc(unsigned int irq)
{
return radix_tree_lookup(&irq_desc_tree, irq);
}
-#ifdef CONFIG_KVM_BOOK3S_64_HV_MODULE
+#ifdef CONFIG_KVM_BOOK3S_64_MODULE
EXPORT_SYMBOL_GPL(irq_to_desc);
#endif
Our three virtualization modules (kvm, kvm-hv, kvm-pr) can be loaded/unloaded in such a way that could leave kvm.ko loaded without kvm-hv.ko or kvm-pr.ko. That means the userspace could continue to issue ioctls to KVM while there is no code on our side to service them. We currently select at config time which module will be built, either kvm-hv, kvm-pr or both, with the kvm module being always present. For 32 bits the kvm module is the only one present and contains the code from kvm-pr in it. We can do the same for 64 bit and keep hv and pr inside kvm.ko. With this, we do not lose the ability of running two guests at the same time, each using a different implementation (although only POWER bare-metal with Hash MMU supports HV and PR at the same time). We lose the ability of loading and unloading the code, which means any Linux installation that wants to support *both* KVM-HV guests on POWER bare-metal and KVM-PR nested guests on top of PowerVM would have a binary with a larger memory footprint (assuming PR is only used when HV is not present). This patch alters the build to output only one module at all times and relies on the Kconfig to select which implementation will be present. The module init code was rearranged to initialize and cleanup both implementations or only one of them. The Kconfig was altered to provide one boolean for each implementation (KVM_BOOK3S_PR_POSSIBLE, KVM_BOOK3S_HV_POSSIBLE), while keeping the old tristate for the kvm.ko module (KVM_BOOK3S_64). The old KVM_BOOK3S_32 already selects KVM_BOOK3S_PR_POSSIBLE, so nothing changes there. Two module aliases were created to facilitate the introduction of the new scheme so `modprobe kvm-hv`and `modprobe kvm-pr` are the same as `modprobe kvm`. The license macro was removed because it is already included by virt/kvm/kvm_main.c. Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com> --- Here's a summary of the environments that can run KVM: * 64 bit powernv w/Radix KVM-HV * 64 bit powernv w/Hash KVM-HV KVM-PR 32 bit powernv w/Hash KVM-PR 32 bit powernv w/Radix N/A * 64 bit pseries w/Radix on powernv KVM-HV nested * 64 bit pseries w/Hash on powernv KVM-PR nested 32 bit pseries w/Hash on powernv KVM-PR nested * 64 bit pseries w/Radix on PowerVM N/A * 64 bit pseries w/Hash on PowerVM KVM-PR nested Lines with an asterisk were tested with all combinations for the module and the HV/PR configs. --- arch/powerpc/configs/powernv_defconfig | 2 +- arch/powerpc/configs/ppc64_defconfig | 2 +- arch/powerpc/configs/pseries_defconfig | 2 +- arch/powerpc/kvm/Kconfig | 72 ++++++++++++-------------- arch/powerpc/kvm/Makefile | 11 ++-- arch/powerpc/kvm/book3s.c | 46 +++++++++++++--- arch/powerpc/kvm/book3s.h | 19 +++++++ arch/powerpc/kvm/book3s_hv.c | 10 +--- arch/powerpc/kvm/book3s_pr.c | 13 ----- kernel/irq/irqdesc.c | 2 +- 10 files changed, 105 insertions(+), 74 deletions(-)