Add userpace tlb access (userspace)
PATCH 4/4 Add userpace tlb access (userspace)
Subject: [PATCH] [4/4] Add userpace tlb access (userspace)
From: Christian Ehrhardt <[email protected]>
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.
---
libkvm/libkvm-powerpc.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ libkvm/libkvm.h | 6 ++++ qemu/hw/ppc440_boards_kvm.c | 5 ++-- qemu/qemu-kvm-powerpc.c | 19 +++++++++++++++ qemu/qemu-kvm.h | 1 5 files changed, 82 insertions(+), 2 deletions(-)
libkvm/libkvm-powerpc.c +53 -0
@@ -25,6 +25,7 @@#include "kvm-powerpc.h" #include <errno.h> #include <stdio.h> +#include <sys/ioctl.h> int handle_dcr (struct kvm_run *run,kvm_context_t kvm) {
@@ -110,3 +111,55 @@ int kvm_arch_run(struct kvm_run *run, kv }return ret; } + +int kvm_get_tlb (kvm_context_t kvm,int vcpu,struct kvm_tlb *tlb) +{ +int r =0 ; + + r =ioctl (kvm->vcpu_fd[vcpu],KVM_GET_TLB , tlb); +if (r) { +fprintf (stderr,"%s failed (r='%d')\n" ,__func__,r); + } + +return r; +} + +int kvm_set_tlb (kvm_context_t kvm,int vcpu,struct kvm_tlb *tlb) +{ +int r =0 ; + + r =ioctl (kvm->vcpu_fd[vcpu],KVM_SET_TLB , tlb); +if (r) { +fprintf (stderr,"%s - failed (r='%d')\n" ,__func__,r); + } + +return r; +} + +static void print_tlb (struct tlbe tlb[PPC44x_TLB_SIZE],char * name,char * flag) +{ +int i; + +fprintf (stderr,"%s:\n" ,name); +fprintf (stderr,"| %2s | %8s | %8s | %8s | %8s |\n" ,"nr" ," tid " , +"word0" ,"word1" ,"word2" ); +for (i =0 ; i < PPC44x_TLB_SIZE; i++) { +if (tlb[i].word0 & PPC44x_TLB_VALID) +fprintf (stderr,"%s%2d | %08X | %08X | %08X | %08X |\n" , + flag,i, + tlb[i].tid, + tlb[i].word0, + tlb[i].word1, + tlb[i].word2); + } +fflush (stdout); +} + +void kvm_dump_tlb (kvm_context_t kvm,int vcpu) +{ +struct kvm_tlb tlb; +kvm_get_tlb (kvm, vcpu, &tlb); + +print_tlb (tlb.guest_tlb,"Guest TLB" ,"G" ); +print_tlb (tlb.shadow_tlb,"Shadow TLB" ,"S" ); +}
libkvm/libkvm.h +6 -0
@@ -556,4 +556,10 @@ int kvm_enable_vapic(kvm_context_t kvm,#endif +#if defined(__powerpc__) +int kvm_get_tlb (kvm_context_t kvm,int vcpu,struct kvm_tlb *tlb); +int kvm_set_tlb (kvm_context_t kvm,int vcpu,struct kvm_tlb *tlb); +void kvm_dump_tlb (kvm_context_t kvm,int vcpu);#endif + +#endif
qemu/hw/ppc440_boards_kvm.c +3 -2
@@ -124,7 +124,6 @@ void ppc440_init(CPUState *env,ppc_dcr_register (env,DCRN_CPR0_CFGDATA , cpr0, dcr_read_cpr0,NULL ); } - static void bambooKVM_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename,
@@ -220,7 +219,9 @@ static void bambooKVM_init(ram_addr_t ra } } -/* 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;
qemu/qemu-kvm-powerpc.c +19 -0
@@ -204,4 +204,23 @@ int handle_powerpc_dcr_write(uint32_t dc return 0; /* XXX ignore failed DCR ops */ } +void kvm_ppc440_tlb_init (CPUState *env) +{ +static struct kvm_tlb tlb; +struct tlbe *gtlbe = &(tlb.guest_tlb[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; + + gtlbe++; + 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_tlb (kvm_context, env->cpu_index, &tlb); +} +#endif
qemu/qemu-kvm.h +1 -0
@@ -51,6 +51,7 @@ int handle_tpr_access(void *opaque, int#ifdef TARGET_PPC int handle_powerpc_dcr_read (uint32_t dcrn,uint32_t *data);int handle_powerpc_dcr_write (uint32_t dcrn,uint32_t data); +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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
PATCH 4/4 Add userpace tlb access (userspace)
From: Christian Ehrhardt <[email protected]>
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.
---
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(-)
libkvm/libkvm-powerpc.c +74 -0
@@ -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); + } + } +}
libkvm/libkvm.h +7 -0
@@ -560,4 +560,11 @@ void kvm_set_guest_pvr(kvm_context_t kvmvoid 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
qemu/hw/ppc440_bamboo.c +3 -1
@@ -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;
qemu/qemu-kvm-powerpc.c +20 -0
@@ -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
qemu/qemu-kvm.h +1 -0
@@ -58,6 +58,7 @@ int handle_powerpc_dcr_read(int vcpu, uiint 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 [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel