diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 7e2cb4b..ba1bcaf 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -56,7 +56,6 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
     va_low &= 0x7ff;
     if (v & HPTE64_V_LARGE) {
         rb |= 1;                         /* L field */
-#if 0 /* Disable that P7 specific bit for now */
         if (r & 0xff000) {
             /* non-16MB large page, must be 64k */
             /* (masks depend on page size) */
@@ -64,7 +63,6 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
             rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */
             rb |= (va_low & 0xfe);       /* AVAL field */
         }
-#endif
     } else {
         /* 4kB page */
         rb |= (va_low & 0x7ff) << 12;   /* remaining 11b of AVA */
@@ -98,14 +96,12 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     target_ulong index;
     uint64_t token;
 
-    /* only handle 4k and 16M pages for now */
+    /* Handle non-4K pages */
     if (pteh & HPTE64_V_LARGE) {
-#if 0 /* We don't support 64k pages yet */
         if ((ptel & 0xf000) == 0x1000) {
             /* 64k page */
-        } else
-#endif
-        if ((ptel & 0xff000) == 0) {
+            page_shift = 16;
+        } else if ((ptel & 0xff000) == 0) {
             /* 16M page */
             page_shift = 24;
             /* lowest AVA bit must be 0 for 16M pages */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ca6c961..3fc3e1d 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -115,16 +115,19 @@ enum powerpc_mmu_t {
 #define POWERPC_MMU_64       0x00010000
 #define POWERPC_MMU_1TSEG    0x00020000
 #define POWERPC_MMU_AMR      0x00040000
+#define POWERPC_MMU_64K      0x00080000
     /* 64 bits PowerPC MMU                                     */
     POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
     /* Architecture 2.03 and later (has LPCR) */
     POWERPC_MMU_2_03       = POWERPC_MMU_64 | 0x00000002,
     /* Architecture 2.06 variant                               */
     POWERPC_MMU_2_06       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
-                             | POWERPC_MMU_AMR | 0x00000003,
+                             | POWERPC_MMU_AMR | POWERPC_MMU_64K
+                             | 0x00000003,
     /* Architecture 2.07 variant                               */
     POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
-                             | POWERPC_MMU_AMR | 0x00000004,
+                             | POWERPC_MMU_AMR | POWERPC_MMU_64K
+                             | 0x00000004,
 #endif /* defined(TARGET_PPC64) */
 };
 
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 328998f..9071fe9 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -348,9 +348,31 @@ void ppc_hash64_stop_access(uint64_t token)
     }
 }
 
+/* Returns the effective page shift or 0. MPSS isn't supported yet so
+ * this will always be the slb_pshift or 0
+ */
+static uint32_t ppc_hash64_pte_size_decode(uint64_t pte1, uint32_t slb_pshift)
+{
+    switch(slb_pshift) {
+    case 12:
+        return 12;
+    case 16:
+        if ((pte1 & 0xf000) == 0x1000) {
+            return 16;
+        }
+        return 0;
+    case 24:
+        if ((pte1 & 0xff000) == 0) {
+            return 24;
+        }
+        return 0;
+    }
+    return 0;
+}
+
 static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash,
-                                     bool secondary, target_ulong ptem,
-                                     ppc_hash_pte64_t *pte)
+                                     uint32_t slb_pshift, bool secondary,
+                                     target_ulong ptem, ppc_hash_pte64_t *pte)
 {
     int i;
     uint64_t token;
@@ -369,6 +391,13 @@ static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash,
         if ((pte0 & HPTE64_V_VALID)
             && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
             && HPTE64_V_COMPARE(pte0, ptem)) {
+            uint32_t pshift = ppc_hash64_pte_size_decode(pte1, slb_pshift);
+            if (pshift == 0) {
+                continue;
+            }
+            /* We don't do anything with pshift yet as qemu TLB only deals
+             * with 4K pages anyway
+             */
             pte->pte0 = pte0;
             pte->pte1 = pte1;
             ppc_hash64_stop_access(token);
@@ -382,7 +411,7 @@ static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash,
     return -1;
 }
 
-static uint64_t ppc_hash64_page_shift(ppc_slb_t *slb)
+static uint64_t ppc_hash64_page_shift(CPUPPCState *env, ppc_slb_t *slb)
 {
     uint64_t epnshift;
 
@@ -392,7 +421,8 @@ static uint64_t ppc_hash64_page_shift(ppc_slb_t *slb)
      * encoded in the PTE */
     if ((slb->vsid & SLB_VSID_LLP_MASK) == SLB_VSID_4K) {
         epnshift = TARGET_PAGE_BITS;
-    } else if ((slb->vsid & SLB_VSID_LLP_MASK) == SLB_VSID_64K) {
+    } else if ((slb->vsid & SLB_VSID_LLP_MASK) == SLB_VSID_64K &&
+               (env->mmu_model & POWERPC_MMU_64K)) {
         epnshift = TARGET_PAGE_BITS_64K;
     } else {
         epnshift = TARGET_PAGE_BITS_16M;
@@ -408,7 +438,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
     hwaddr hash;
     uint64_t vsid, epnshift, epnmask, epn, ptem;
 
-    epnshift = ppc_hash64_page_shift(slb);
+    epnshift = ppc_hash64_page_shift(env, slb);
     epnmask = ~((1ULL << epnshift) - 1);
 
     if (slb->vsid & SLB_VSID_B) {
@@ -436,7 +466,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
             " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
             " hash=" TARGET_FMT_plx "\n",
             env->htab_base, env->htab_mask, vsid, ptem,  hash);
-    pte_offset = ppc_hash64_pteg_search(env, hash, 0, ptem, pte);
+    pte_offset = ppc_hash64_pteg_search(env, hash, epnshift, 0, ptem, pte);
 
     if (pte_offset == -1) {
         /* Secondary PTEG lookup */
@@ -446,14 +476,14 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                 " hash=" TARGET_FMT_plx "\n", env->htab_base,
                 env->htab_mask, vsid, ptem, ~hash);
 
-        pte_offset = ppc_hash64_pteg_search(env, ~hash, 1, ptem, pte);
+        pte_offset = ppc_hash64_pteg_search(env, ~hash, epnshift, 1, ptem, pte);
     }
 
     return pte_offset;
 }
 
-static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
-                                   target_ulong eaddr)
+static hwaddr ppc_hash64_pte_raddr(CPUPPCState *env, ppc_slb_t *slb,
+                                   ppc_hash_pte64_t pte, target_ulong eaddr)
 {
     hwaddr mask;
     int target_page_bits;
@@ -461,7 +491,7 @@ static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
     /*
      * We support 4K, 64K and 16M now
      */
-    target_page_bits = ppc_hash64_page_shift(slb);
+    target_page_bits = ppc_hash64_page_shift(env, slb);
     mask = (1ULL << target_page_bits) - 1;
     return (rpn & ~mask) | (eaddr & mask);
 }
@@ -699,7 +729,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr,
 
     /* 7. Determine the real address from the PTE */
 
-    raddr = ppc_hash64_pte_raddr(&slb, pte, eaddr);
+    raddr = ppc_hash64_pte_raddr(env, &slb, pte, eaddr);
 
     tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                  prot, mmu_idx, TARGET_PAGE_SIZE);
@@ -752,7 +782,7 @@ hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
         return -1;
     }
 
-    return ppc_hash64_pte_raddr(&slb, pte, addr) & TARGET_PAGE_MASK;
+    return ppc_hash64_pte_raddr(env, &slb, pte, addr) & TARGET_PAGE_MASK;
 }
 
 void ppc_hash64_store_hpte(CPUPPCState *env,
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 504564d..b623206 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9998,8 +9998,8 @@ static void ppc_cpu_initfn(Object *obj)
     if (pcc->sps) {
         env->sps = *pcc->sps;
     } else if (env->mmu_model & POWERPC_MMU_64) {
-        /* Use default sets of page sizes */
-        static const struct ppc_segment_page_sizes defsps = {
+	/* Use default sets of page sizes. We don't support MPSS */
+        static const struct ppc_segment_page_sizes defsps_4k = {
             .sps = {
                 { .page_shift = 12, /* 4K */
                   .slb_enc = 0,
@@ -10011,7 +10011,23 @@ static void ppc_cpu_initfn(Object *obj)
                 },
             },
         };
-        env->sps = defsps;
+        static const struct ppc_segment_page_sizes defsps_64k = {
+            .sps = {
+                { .page_shift = 12, /* 4K */
+                  .slb_enc = 0,
+                  .enc = { { .page_shift = 12, .pte_enc = 0 } }
+                },
+                { .page_shift = 16, /* 64K */
+                  .slb_enc = 0x110,
+                  .enc = { { .page_shift = 16, .pte_enc = 1 } }
+                },
+                { .page_shift = 24, /* 16M */
+                  .slb_enc = 0x100,
+                  .enc = { { .page_shift = 24, .pte_enc = 0 } }
+                },
+            },
+        };
+        env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
     }
 #endif /* defined(TARGET_PPC64) */
 
