From mboxrd@z Thu Jan 1 00:00:00 1970 From: ehrhardt@linux.vnet.ibm.com Date: Thu, 31 Jan 2008 14:56:36 +0000 Subject: [kvm-ppc-devel] [PATCH] [4/4] Add userpace tlb access (userspace) Message-Id: <12017914001463-git-send-email-ehrhardt@linux.vnet.ibm.com> List-Id: References: <1201696321567-git-send-email-ehrhardt@linux.vnet.ibm.com> In-Reply-To: <1201696321567-git-send-email-ehrhardt@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm-ppc@vger.kernel.org From: Christian Ehrhardt This adds userspace tlb access transporting a single tlb entry to/from userspace. It has an index variable passed with the call to specify the tlb entry to get/set. For the guest tlb get&set is supported while the shadow tlb can only be read from userspace. Signed-off-by: Christian Ehrhardt --- libkvm/libkvm-powerpc.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++-- libkvm/libkvm.h | 7 ++++ qemu/hw/ppc440_bamboo.c | 4 +- qemu/qemu-kvm-powerpc.c | 20 +++++++++++ qemu/qemu-kvm.h | 1 5 files changed, 113 insertions(+), 3 deletions(-) diff --git a/libkvm/libkvm-powerpc.c b/libkvm/libkvm-powerpc.c --- a/libkvm/libkvm-powerpc.c +++ b/libkvm/libkvm-powerpc.c @@ -137,3 +137,77 @@ int kvm_arch_run(struct kvm_run *run, kv } return ret; } + +int kvm_get_guest_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe) +{ + int r = 0; + + r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_GUEST_TLB, tlbe); + if (r) + fprintf(stderr, "%s failed (r='%d')\n", __func__, r); + + return r; +} + +int kvm_get_shadow_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe) +{ + int r = 0; + + r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_SHADOW_TLB, tlbe); + if (r) + fprintf(stderr, "%s failed (r='%d')\n", __func__, r); + + return r; +} + +int kvm_set_guest_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe) +{ + int r = 0; + + r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_GUEST_TLB, tlbe); + if (r) + fprintf(stderr, "%s - failed (r='%d')\n", __func__, r); + + return r; +} + +void kvm_dump_tlb(kvm_context_t kvm, int vcpu) +{ + int pvr = kvm_get_guest_pvr(kvm, vcpu); + + switch (pvr) { + case KVM_PPC_PVR_PPC440EP: { + struct kvm_tlbe tlbe; + struct tlbe *tlbe_ppc440 = &(tlbe.tlbe_ppc440); + + fprintf(stderr, "vcpu %d TLB dump:\n", vcpu); + fprintf(stderr, "| %2s | %8s | %8s | %8s | %8s |\n", + "nr", " tid ", "word0", "word1", "word2"); + for (tlbe.index = 0; tlbe.index < PPC44x_TLB_SIZE; + tlbe.index++) { + kvm_get_guest_tlb(kvm, vcpu, &tlbe); + if (tlbe_ppc440->word0 & PPC44x_TLB_VALID) + fprintf(stderr, + "G%2lld | %08X | %08X | %08X | %08X |\n", + tlbe.index, tlbe_ppc440->tid, + tlbe_ppc440->word0, tlbe_ppc440->word1, + tlbe_ppc440->word2); + } + for (tlbe.index = 0; tlbe.index < PPC44x_TLB_SIZE; + tlbe.index++) { + kvm_get_shadow_tlb(kvm, vcpu, &tlbe); + if (tlbe_ppc440->word0 & PPC44x_TLB_VALID) + fprintf(stderr, + "S%2lld | %08X | %08X | %08X | %08X |\n", + tlbe.index, tlbe_ppc440->tid, + tlbe_ppc440->word0, tlbe_ppc440->word1, + tlbe_ppc440->word2); + } + fflush(stdout); + break; + } + default: { + printf("%s unsupported pvr '%X'", __func__, pvr); + } + } +} diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h --- a/libkvm/libkvm.h +++ b/libkvm/libkvm.h @@ -560,4 +560,11 @@ void kvm_set_guest_pvr(kvm_context_t kvm void kvm_set_guest_pvr(kvm_context_t kvm, uint32_t guest_pvr, int vcpu); #endif +#if defined(__powerpc__) +int kvm_get_guest_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe); +int kvm_set_guest_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe); +int kvm_get_shadow_tlb(kvm_context_t kvm, int vcpu, struct kvm_tlbe *tlbe); +void kvm_dump_tlb(kvm_context_t kvm, int vcpu); #endif + +#endif diff --git a/qemu/hw/ppc440_bamboo.c b/qemu/hw/ppc440_bamboo.c --- a/qemu/hw/ppc440_bamboo.c +++ b/qemu/hw/ppc440_bamboo.c @@ -103,7 +103,9 @@ void bamboo_init(ram_addr_t ram_size, in #if USE_KVM set_guest_pvr(KVM_PPC_PVR_PPC440EP, env); - /* XXX insert TLB entries */ + /* insert initial TLB entry state */ + kvm_ppc440_tlb_init(env); + /* set up initial stack pointer */ env->gpr[1] = (16<<20) - 8; env->gpr[4] = initrd_base; env->gpr[5] = initrd_size; diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c --- a/qemu/qemu-kvm-powerpc.c +++ b/qemu/qemu-kvm-powerpc.c @@ -199,4 +199,24 @@ void set_guest_pvr(uint32_t guest_pvr, C kvm_set_guest_pvr(kvm_context, guest_pvr, env->cpu_index); } +void kvm_ppc440_tlb_init(CPUState *env) +{ + static struct kvm_tlbe tlbe; + struct tlbe *gtlbe = &(tlbe.tlbe_ppc440); + tlbe.index = 0; + gtlbe->tid = 0; + gtlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; + gtlbe->word1 = 0; + gtlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; + kvm_set_guest_tlb(kvm_context, env->cpu_index, &tlbe); + + tlbe.index++; + gtlbe->tid = 0; + gtlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; + gtlbe->word1 = 0xef600000; + gtlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR + | PPC44x_TLB_I | PPC44x_TLB_G; + kvm_set_guest_tlb(kvm_context, env->cpu_index, &tlbe); +} + #endif diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -58,6 +58,7 @@ int handle_powerpc_dcr_read(int vcpu, ui int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data); int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data); void set_guest_pvr(uint32_t guest_pvr, CPUState *env); +void kvm_ppc440_tlb_init(CPUState *env); #endif #define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) ------------------------------------------------------------------------- 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/ _______________________________________________ kvm-ppc-devel mailing list kvm-ppc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel