@@ -748,7 +748,13 @@ static void spapr_cpu_reset(void *opaque)
env->external_htab = (void *)1;
}
env->htab_base = -1;
- env->htab_mask = HTAB_SIZE(spapr) - 1;
+ /*
+ * htab_mask is the mask used to normalize hash value to PTEG index.
+ * htab_shift is log2 of hash table size.
+ * We have 8 hpte per group, and each hpte is 16 bytes.
+ * ie have 128 bytes per hpte entry.
+ */
+ env->htab_mask = (1ULL << ((spapr)->htab_shift - 7)) - 1;
env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
(spapr->htab_shift - 18);
}
@@ -961,6 +961,7 @@ struct CPUPPCState {
#endif
/* segment registers */
hwaddr htab_base;
+ /* mask used to normalize hash value to PTEG index */
hwaddr htab_mask;
target_ulong sr[32];
/* externally stored hash table */
@@ -1029,7 +1029,9 @@ int kvm_arch_get_registers(CPUState *cs)
return ret;
}
- ppc_store_sdr1(env, sregs.u.s.sdr1);
+ if (!env->external_htab) {
+ ppc_store_sdr1(env, sregs.u.s.sdr1);
+ }
/* Sync SLB */
#ifdef TARGET_PPC64
@@ -70,7 +70,9 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
qemu_get_betls(f, &env->pb[i]);
for (i = 0; i < 1024; i++)
qemu_get_betls(f, &env->spr[i]);
- ppc_store_sdr1(env, sdr1);
+ if (!env->external_htab) {
+ ppc_store_sdr1(env, sdr1);
+ }
qemu_get_be32s(f, &env->vscr);
qemu_get_be64s(f, &env->spe_acc);
qemu_get_be32s(f, &env->spe_fscr);
@@ -179,9 +181,10 @@ static int cpu_post_load(void *opaque, int version_id)
env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];
}
- /* Restore htab_base and htab_mask variables */
- ppc_store_sdr1(env, env->spr[SPR_SDR1]);
-
+ if (!env->external_htab) {
+ /* Restore htab_base and htab_mask variables */
+ ppc_store_sdr1(env, env->spr[SPR_SDR1]);
+ }
hreg_compute_hflags(env);
hreg_compute_mem_idx(env);
@@ -38,7 +38,9 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
void helper_store_sdr1(CPUPPCState *env, target_ulong val)
{
- ppc_store_sdr1(env, val);
+ if (!env->external_htab) {
+ ppc_store_sdr1(env, val);
+ }
}
void helper_store_hid0_601(CPUPPCState *env, target_ulong val)
@@ -2014,6 +2014,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
{
LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
+ assert(!env->external_htab);
if (env->spr[SPR_SDR1] != value) {
env->spr[SPR_SDR1] = value;
#if defined(TARGET_PPC64)
@@ -2025,7 +2026,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
" stored in SDR1\n", htabsize);
htabsize = 28;
}
- env->htab_mask = (1ULL << (htabsize + 18)) - 1;
+ env->htab_mask = (1ULL << (htabsize + 18 - 7)) - 1;
env->htab_base = value & SDR_64_HTABORG;
} else
#endif /* defined(TARGET_PPC64) */
Correctly update the htab_mask using the return value of KVM_PPC_ALLOCATE_HTAB ioctl. Also we don't update sdr1 on GET_SREGS for HV. We check for external htab and if found true, we don't need to update sdr1 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- hw/ppc/spapr.c | 8 +++++++- target-ppc/cpu.h | 1 + target-ppc/kvm.c | 4 +++- target-ppc/machine.c | 11 +++++++---- target-ppc/misc_helper.c | 4 +++- target-ppc/mmu_helper.c | 3 ++- 6 files changed, 23 insertions(+), 8 deletions(-)