diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "44x_tlb.h" @@ -578,24 +579,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu * /* Initial guest state: 16MB mapping 0 -> 0, PC = 0, MSR = 0, R1 = 16MB */ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { - struct tlbe *tlbe = &vcpu->arch.guest_tlb[0]; - - tlbe->tid = 0; - tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; - tlbe->word1 = 0; - tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; - - tlbe++; - tlbe->tid = 0; - tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; - tlbe->word1 = 0xef600000; - tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR - | PPC44x_TLB_I | PPC44x_TLB_G; - vcpu->arch.pc = 0; vcpu->arch.guest_msr = 0; vcpu->arch.shadow_msr = MSR_PR|MSR_EE|MSR_IS|MSR_DS; - vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */ /* Eye-catching number so we know if the guest takes an interrupt * before it's programmed its own IVPR. */ @@ -820,6 +806,30 @@ long kvm_arch_vcpu_ioctl(struct file *fi long r; switch (ioctl) { + case KVM_GET_TLB: { + struct kvm_vcpu *vcpu = filp->private_data; + struct kvm_tlb __user *utlb = (struct kvm_tlb __user *)arg; + + r = copy_to_user(&(utlb->guest_tlb), &(vcpu->arch.guest_tlb), sizeof(utlb->guest_tlb)); + if (r) + return r; + r = copy_to_user(&(utlb->shadow_tlb), &(vcpu->arch.shadow_tlb), sizeof(utlb->shadow_tlb)); + if (r) + return r; + break; + } + case KVM_SET_TLB: { + struct kvm_vcpu *vcpu = filp->private_data; + struct kvm_tlb __user *utlb = (struct kvm_tlb __user *)arg; + + r = copy_from_user(&(vcpu->arch.guest_tlb), &(utlb->guest_tlb), sizeof(utlb->guest_tlb)); + if (r) + return r; + r = copy_from_user(&(vcpu->arch.shadow_tlb), &(utlb->shadow_tlb), sizeof(utlb->shadow_tlb)); + if (r) + return r; + break; + } default: r = -EINVAL; } diff --git a/include/asm-powerpc/kvm.h b/include/asm-powerpc/kvm.h --- a/include/asm-powerpc/kvm.h +++ b/include/asm-powerpc/kvm.h @@ -21,6 +21,7 @@ #define __POWERPC_KVM_H__ #include +#include struct kvm_regs { __u32 pc; @@ -53,4 +54,16 @@ struct kvm_fpu { struct kvm_fpu { }; +struct tlbe { + __u32 tid; /* Only the low 8 bits are used. */ + __u32 word0; + __u32 word1; + __u32 word2; +}; + +struct kvm_tlb { + struct tlbe guest_tlb[PPC44x_TLB_SIZE]; + struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; +}; + #endif /* __POWERPC_KVM_H__ */ diff --git a/include/asm-powerpc/kvm_host.h b/include/asm-powerpc/kvm_host.h --- a/include/asm-powerpc/kvm_host.h +++ b/include/asm-powerpc/kvm_host.h @@ -39,13 +39,6 @@ struct kvm_vcpu_stat { u32 mmio_exits; u32 signal_exits; u32 light_exits; -}; - -struct tlbe { - u32 tid; /* Only the low 8 bits are used. */ - u32 word0; - u32 word1; - u32 word2; }; struct kvm_arch { @@ -127,11 +120,6 @@ struct kvm_vcpu_arch { int pending_dec; }; -struct kvm_tlb { - struct tlbe guest_tlb[PPC44x_TLB_SIZE]; - struct tlbe shadow_tlb[PPC44x_TLB_SIZE]; -}; - enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ diff --git a/include/linux/kvm.h b/include/linux/kvm.h --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -289,4 +289,7 @@ struct kvm_vapic_addr { /* Available with KVM_CAP_VAPIC */ #define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) +#define KVM_GET_TLB _IOR(KVMIO, 0x94, struct kvm_tlb) +#define KVM_SET_TLB _IOW(KVMIO, 0x95, struct kvm_tlb) + #endif