aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/kvm.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2014-02-20 18:52:24 +0100
committerAlexander Graf <agraf@suse.de>2014-03-05 03:07:02 +0100
commit7c43bca004afdb2a86c20ab3131ec1eb7a78d80d (patch)
tree307e01bd324b38976bf99cca15ea574974293c59 /target-ppc/kvm.c
parentf3c75d42adbba553eaf218a832d4fbea32c8f7b8 (diff)
target-ppc: Fix page table lookup with kvm enabled
With kvm enabled, we store the hash page table information in the hypervisor. Use ioctl to read the htab contents. Without this we get the below error when trying to read the guest address (gdb) x/10 do_fork 0xc000000000098660 <do_fork>: Cannot access memory at address 0xc000000000098660 (gdb) Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> [ fixes for 32 bit build (casts!), ldq_phys() API change, Greg Kurz <gkurz@linux.vnet.ibm.com ] Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/kvm.c')
-rw-r--r--target-ppc/kvm.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 969ebddd4c..e00991920a 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1788,6 +1788,11 @@ bool kvmppc_has_cap_epr(void)
return cap_epr;
}
+bool kvmppc_has_cap_htab_fd(void)
+{
+ return cap_htab_fd;
+}
+
static int kvm_ppc_register_host_cpu_type(void)
{
TypeInfo type_info = {
@@ -1938,3 +1943,52 @@ void kvm_arch_remove_all_hw_breakpoints(void)
void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
{
}
+
+struct kvm_get_htab_buf {
+ struct kvm_get_htab_header header;
+ /*
+ * We require one extra byte for read
+ */
+ target_ulong hpte[(HPTES_PER_GROUP * 2) + 1];
+};
+
+uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index)
+{
+ int htab_fd;
+ struct kvm_get_htab_fd ghf;
+ struct kvm_get_htab_buf *hpte_buf;
+
+ ghf.flags = 0;
+ ghf.start_index = pte_index;
+ htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
+ if (htab_fd < 0) {
+ goto error_out;
+ }
+
+ hpte_buf = g_malloc0(sizeof(*hpte_buf));
+ /*
+ * Read the hpte group
+ */
+ if (read(htab_fd, hpte_buf, sizeof(*hpte_buf)) < 0) {
+ goto out_close;
+ }
+
+ close(htab_fd);
+ return (uint64_t)(uintptr_t) hpte_buf->hpte;
+
+out_close:
+ g_free(hpte_buf);
+ close(htab_fd);
+error_out:
+ return 0;
+}
+
+void kvmppc_hash64_free_pteg(uint64_t token)
+{
+ struct kvm_get_htab_buf *htab_buf;
+
+ htab_buf = container_of((void *)(uintptr_t) token, struct kvm_get_htab_buf,
+ hpte);
+ g_free(htab_buf);
+ return;
+}