KVM for PowerPC: simpler TLB handling, better page management
Subsystems (3)
RFC PATCH 1/1 KVM for PowerPC: simpler TLB handling, better page management
Here's the updated version of PowerPC support. Still rough, but somewhat functional and getting better. :)
Changes:
* Big simplification in the TLB context switching: I threw out all that trampoline stuff. The trampoline allowed us to consume only 1 TLB entry when the guest was running, but was also led to very convoluted code. Now we leave the kernel's pinned entries present even when the guest is running. This will make things somewhat slower, since the guest has a couple fewer entries available. We can revisit this topic if necessary when we start looking at performance issues. (As a result, we are now incompatible with CONFIG_EARLY_DEBUG_44x on the host. That option was leaking a pinned AS=1 entry into the guest.)
* Stop leaking page refcounts. Basically every mapping in the shadow TLB (approx. 60) has had get_user_pages() called for it, and now when we evict it, we actually call put_page(). It might even work with swapping and highmem, who knows...
* I've also renamed a few functions that are 440-specific in anticipation of some e500 refactoring.
Going forward, I would like to get some sort of IO working besides console before submitting this for inclusion upstream. (So far we've been getting by with an initramfs.) IO support will depend on interrupt delivery, so that's the current focus.
Once we do have IO working, I feel pretty good about submitting this for serious review. Ultimately Avi will be the final approver, but I plan to copy linuxppc-dev for architectural and design comments.
PowerPC 440 KVM implementation.
MAINTAINERS +7 -0
@@ -2219,6 +2219,13 @@ W: kvm.sourceforge.net W: kvm.sourceforge.net S: Supported +KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC +P: Hollis Blanchard +M: hollisb-r/[email protected] +L: [email protected] +W: kvm.qumranet.com +S: Supported + KEXEC P: Eric Biederman M: ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]
arch/powerpc/Kconfig +1 -0
@@ -694,3 +694,4 @@ config PPC_LIB_RHEAP config PPC_LIB_RHEAP bool +source "arch/powerpc/kvm/Kconfig"
arch/powerpc/Kconfig.debug +1 -0
@@ -151,6 +151,7 @@ config BOOTX_TEXT config PPC_EARLY_DEBUG bool "Early debugging (dangerous)" + depends on !KVM choice prompt "Early debugging console"
arch/powerpc/Makefile +1 -0
@@ -147,6 +147,7 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/platforms/ core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_KVM) += arch/powerpc/kvm/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
arch/powerpc/kernel/asm-offsets.c +27 -0
@@ -22,6 +22,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/suspend.h> +#include <linux/kvm_host.h> #ifdef CONFIG_PPC64 #include <linux/time.h> #include <linux/hardirq.h>
@@ -328,5 +329,31 @@ int main(void)DEFINE (PGD_TABLE_SIZE ,PGD_TABLE_SIZE ); +#ifdef CONFIG_KVM +DEFINE (TLBE_BYTES ,sizeof (struct tlbe )); + + DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); + DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); + DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb)); + DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb)); + DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); + DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); + DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); + DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); + DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); + DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); + DEFINE(VCPU_GUEST_MSR, offsetof(struct kvm_vcpu, arch.guest_msr)); + DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr)); + DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4)); + DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5)); + DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); + DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); + DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid)); + + DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); + DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); + DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); +#endif +return 0 ; }
arch/powerpc/kvm/44x_tlb.c new file +236 -0
236 lines not on this page · raw message
arch/powerpc/kvm/44x_tlb.h new file +91 -0
91 lines not on this page · raw message
arch/powerpc/kvm/Kconfig new file +45 -0
45 lines not on this page · raw message
arch/powerpc/kvm/Makefile new file +15 -0
@@ -0,0 +1,15 @@ +# +# Makefile for Kernel-based Virtual Machine module +# + +EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm + +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o) + +kvm-objs := $(common-objs) +obj-$(CONFIG_KVM) += kvm.o + +kvm-powerpc-objs := powerpc.o emulate.o 44x_tlb.o booke_interrupts.o +obj-$(CONFIG_KVM_POWERPC) += kvm-powerpc.o + +AFLAGS_booke_interrupts.o := -I$(obj)
arch/powerpc/kvm/booke_interrupts.S new file +430 -0
430 lines not on this page · raw message
arch/powerpc/kvm/emulate.c new file +830 -0
830 lines not on this page · raw message
arch/powerpc/kvm/powerpc.c new file +785 -0
785 lines not on this page · raw message
include/asm-powerpc/kvm.h new file +56 -0
56 lines not on this page · raw message
include/asm-powerpc/kvm_asm.h new file +53 -0
53 lines not on this page · raw message
include/asm-powerpc/kvm_host.h new file +169 -0
169 lines not on this page · raw message
include/asm-powerpc/kvm_para.h new file +38 -0
@@ -0,0 +1,38 @@ +/* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License, version 2, as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* Copyright IBM Corp. 2008 +* +* Authors: Hollis Blanchard <hollisb-r/[email protected]> +*/ + +#ifndef __POWERPC_KVM_PARA_H__ +#define __POWERPC_KVM_PARA_H__ + +#ifdef __KERNEL__ + +static inline int kvm_para_available (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_para_features (void ) +{ +return 0 ; +} + +#endif /* __KERNEL__ */ + +#endif /* __POWERPC_KVM_PARA_H__ */ +
include/asm-powerpc/mmu-44x.h +2 -0
@@ -53,6 +53,8 @@ #ifndef __ASSEMBLY__ +extern unsigned int tlb_44x_hwater; + typedef unsigned long long phys_addr_t; typedef struct {
include/linux/kvm.h +7 -0
@@ -73,6 +73,7 @@ struct kvm_irqchip {#define KVM_EXIT_INTR 10#define KVM_EXIT_SET_TPR 11#define KVM_EXIT_TPR_ACCESS 12 +#define KVM_EXIT_DCR 13/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run {
@@ -137,6 +138,12 @@ struct kvm_run {__u32 is_write;__u32 pad; } tpr_access; +/* KVM_EXIT_DCR */ +struct { +__u32 dcrn; +__u32 data; +__u8 is_write; + } dcr;/* Fix the size of the union. */ char padding[256 ]; };
Signature · 9 lines
Hollis Blanchard IBM Linux Technology Center ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 11 lines · Hollis Blanchard
arch/powerpc/kernel/asm-offsets.c +1
-0@@ -22,6 +22,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/suspend.h> +#include <linux/kvm_host.h> #ifdef CONFIG_PPC64 #include <linux/time.h> #include <linux/hardirq.h>
arch/powerpc/kernel/asm-offsets.c int main(void) · line 338
Quoted 10 lines
arch/powerpc/kernel/asm-offsets.c +7
-0@@ -328,5 +329,31 @@ int main(void)DEFINE (PGD_TABLE_SIZE ,PGD_TABLE_SIZE ); +#ifdef CONFIG_KVM +DEFINE (TLBE_BYTES ,sizeof (struct tlbe )); + + DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); + DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); + DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb)); + DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb));
I found that if CONFIG_KVM=m these definitions don't get picked up when generating asm-offsets.h, which causes the build to break:
AS arch/powerpc/kvm/booke_interrupts.oarch/powerpc/kvm/booke_interrupts.S: Assembler messages:arch/powerpc/kvm/booke_interrupts.S:347: Error: unsupported relocation against VCPU_HOST_TLB arch/powerpc/kvm/booke_interrupts.S:348: Error: unsupported relocation against VCPU_SHADOW_TLB
make[1]: *** [arch/powerpc/kvm/booke_interrupts.o] Error 1
Changing it to ifdef CONFIG_KVM_POWERPC (which is a bool) seems to do the right thing.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 34 lines · Nathan Lynch
Quoted 11 lines · Hollis Blanchard
arch/powerpc/kernel/asm-offsets.c +1
-0@@ -22,6 +22,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/suspend.h> +#include <linux/kvm_host.h> #ifdef CONFIG_PPC64 #include <linux/time.h> #include <linux/hardirq.h> arch/powerpc/kernel/asm-offsets.c int main(void) · line 338
Quoted 10 lines
arch/powerpc/kernel/asm-offsets.c +7
-0@@ -328,5 +329,31 @@ int main(void)DEFINE (PGD_TABLE_SIZE ,PGD_TABLE_SIZE ); +#ifdef CONFIG_KVM +DEFINE (TLBE_BYTES ,sizeof (struct tlbe )); + + DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); + DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); + DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb)); + DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb));I found that if
CONFIG_KVM=mthese definitions don't get picked up when generatingasm-offsets.h, which causes the build to break:AS
arch/powerpc/kvm/booke_interrupts.oarch/powerpc/kvm/booke_interrupts.S: Assembler messages:arch/powerpc/kvm/booke_interrupts.S:347: Error: unsupported relocation againstVCPU_HOST_TLBarch/powerpc/kvm/booke_interrupts.S:348: Error: unsupported relocation againstVCPU_SHADOW_TLB
make[1]: *** [arch/powerpc/kvm/booke_interrupts.o] Error 1
Quoted 2 lines
Changing it to ifdef
CONFIG_KVM_POWERPC(which is a bool) seems to do the right thing.
Hmm... building as a module is something we've struggled with in the past, so I just left KVM_POWERPC as a bool because I didn't want to mess with it.
With PowerPC's asm-offsets dependency, is it really possible to build a standalone module if the kernel didn't have KVM=y?
Signature · 8 lines
Hollis Blanchard IBM Linux Technology Center ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/