On Thu, Feb 23, 2017 at 04:37:00PM +1100, Suraj Jitindar Singh wrote: > On Thu, 2017-02-23 at 13:09 +1100, David Gibson wrote: > > Accesses to the hashed page table (HPT) are complicated by the fact > > that > > the HPT could be in one of three places: > > 1) Within guest memory - when we're emulating a full guest CPU at > > the > > hardware level (e.g. powernv, mac99, g3beige) > > 2) Within qemu, but outside guest memory - when we're emulating > > user and > > supervisor instructions within TCG, but instead of emulating > > the CPU's hypervisor mode, we just emulate a hypervisor's > > behaviour > > (pseries in TCG) > > 3) Within KVM - a pseries machine using KVM acceleration. Mostly > > accesses to the HPT are handled by KVM, but there are a few > > cases > > where qemu needs to access it via a special fd for the purpose. > > Should you clarify that this is the case for KVM-HV with KVM-PR the > same as (2)?
Ah, good idea. > > > > > In order to batch accesses to the fd in case (3), we use a somewhat > > awkward > > ppc_hash64_start_access() / ppc_hash64_stop_access() pair, which for > > case > > (3) reads / releases a whole PTEG from the kernel. For cases (1) & > > (2) > > it just returns an address value. The actual HPTE load helpers then > > need > > to interpret the returned token differently in the 3 cases. > > > > This patch keeps the same basic structure, but simplfiies the > > details. > > First start_access() / stop_access() are renamed to get_pteg() and > > put_pteg() to make their operation more obvious. Second, read_pteg() > > Here you say they've been renamed to get/put/read_pteg, but in the code > they're called map/unmap_hptes and it looks like map_hptes does both > the get and the read? Oops, I'll update. > > > now > > always returns a qemu pointer, which can always be used in the same > > way > > by the load_hpte() helpers. In case (1) it comes from > > address_space_map() > > in case (2) directly from qemu's HPT buffer and in case (3) from a > > temporary buffer read from the KVM fd. > > > > While we're at it, make things a bit more consistent in terms of > > types and > > variable names: avoid variables named 'index' (it shadows index(3) > > which > > can lead to confusing results), use 'hwaddr ptex' for HPTE indices > > and > > uint64_t for each of the HPTE words, use ptex throughout the call > > stack > > instead of pte_offset in some places (we still need that at the > > bottom > > layer, but nowhere else). > > > > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> > > Other than the commit message: > > Reviewed-by: Suraj Jitindar Singh <sjitindarsi...@gmail.com> > > > --- > > hw/ppc/spapr_hcall.c | 36 +++++++++--------- > > target/ppc/cpu.h | 3 +- > > target/ppc/kvm.c | 25 ++++++------- > > target/ppc/kvm_ppc.h | 43 ++++++++++------------ > > target/ppc/mmu-hash64.c | 98 ++++++++++++++++++++++++++------------- > > ---------- > > target/ppc/mmu-hash64.h | 46 ++++++++--------------- > > 6 files changed, 119 insertions(+), 132 deletions(-) > > > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > > index 3298a14..fd961b5 100644 > > --- a/hw/ppc/spapr_hcall.c > > +++ b/hw/ppc/spapr_hcall.c > > @@ -84,7 +84,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, > > sPAPRMachineState *spapr, > > unsigned apshift; > > target_ulong raddr; > > target_ulong slot; > > - uint64_t token; > > + const ppc_hash_pte64_t *hptes; > > > > apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel); > > if (!apshift) { > > @@ -123,23 +123,23 @@ static target_ulong h_enter(PowerPCCPU *cpu, > > sPAPRMachineState *spapr, > > ptex = ptex & ~7ULL; > > > > if (likely((flags & H_EXACT) == 0)) { > > - token = ppc_hash64_start_access(cpu, ptex); > > + hptes = ppc_hash64_map_hptes(cpu, ptex, HPTES_PER_GROUP); > > for (slot = 0; slot < 8; slot++) { > > - if (!(ppc_hash64_load_hpte0(cpu, token, slot) & > > HPTE64_V_VALID)) { > > + if (!(ppc_hash64_hpte0(cpu, hptes, slot) & > > HPTE64_V_VALID)) { > > break; > > } > > } > > - ppc_hash64_stop_access(cpu, token); > > + ppc_hash64_unmap_hptes(cpu, hptes, ptex, HPTES_PER_GROUP); > > if (slot == 8) { > > return H_PTEG_FULL; > > } > > } else { > > - token = ppc_hash64_start_access(cpu, ptex); > > - if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) { > > - ppc_hash64_stop_access(cpu, token); > > + hptes = ppc_hash64_map_hptes(cpu, ptex + slot, 1); > > + if (ppc_hash64_hpte0(cpu, hptes, 0) & HPTE64_V_VALID) { > > + ppc_hash64_unmap_hptes(cpu, hptes, ptex + slot, 1); > > return H_PTEG_FULL; > > } > > - ppc_hash64_stop_access(cpu, token); > > + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); > > } > > > > ppc_hash64_store_hpte(cpu, ptex + slot, pteh | > > HPTE64_V_HPTE_DIRTY, ptel); > > @@ -160,17 +160,17 @@ static RemoveResult remove_hpte(PowerPCCPU > > *cpu, target_ulong ptex, > > target_ulong flags, > > target_ulong *vp, target_ulong *rp) > > { > > - uint64_t token; > > + const ppc_hash_pte64_t *hptes; > > target_ulong v, r; > > > > if (!valid_ptex(cpu, ptex)) { > > return REMOVE_PARM; > > } > > > > - token = ppc_hash64_start_access(cpu, ptex); > > - v = ppc_hash64_load_hpte0(cpu, token, 0); > > - r = ppc_hash64_load_hpte1(cpu, token, 0); > > - ppc_hash64_stop_access(cpu, token); > > + hptes = ppc_hash64_map_hptes(cpu, ptex, 1); > > + v = ppc_hash64_hpte0(cpu, hptes, 0); > > + r = ppc_hash64_hpte1(cpu, hptes, 0); > > + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); > > > > if ((v & HPTE64_V_VALID) == 0 || > > ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) || > > @@ -291,17 +291,17 @@ static target_ulong h_protect(PowerPCCPU *cpu, > > sPAPRMachineState *spapr, > > target_ulong flags = args[0]; > > target_ulong ptex = args[1]; > > target_ulong avpn = args[2]; > > - uint64_t token; > > + const ppc_hash_pte64_t *hptes; > > target_ulong v, r; > > > > if (!valid_ptex(cpu, ptex)) { > > return H_PARAMETER; > > } > > > > - token = ppc_hash64_start_access(cpu, ptex); > > - v = ppc_hash64_load_hpte0(cpu, token, 0); > > - r = ppc_hash64_load_hpte1(cpu, token, 0); > > - ppc_hash64_stop_access(cpu, token); > > + hptes = ppc_hash64_map_hptes(cpu, ptex, 1); > > + v = ppc_hash64_hpte0(cpu, hptes, 0); > > + r = ppc_hash64_hpte1(cpu, hptes, 0); > > + ppc_hash64_unmap_hptes(cpu, hptes, ptex, 1); > > > > if ((v & HPTE64_V_VALID) == 0 || > > ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > > index f99bcae..c89973e 100644 > > --- a/target/ppc/cpu.h > > +++ b/target/ppc/cpu.h > > @@ -223,11 +223,12 @@ enum { > > typedef struct opc_handler_t opc_handler_t; > > > > /******************************************************************* > > **********/ > > -/* Types used to describe some PowerPC registers */ > > +/* Types used to describe some PowerPC registers etc. */ > > typedef struct DisasContext DisasContext; > > typedef struct ppc_spr_t ppc_spr_t; > > typedef union ppc_avr_t ppc_avr_t; > > typedef union ppc_tlb_t ppc_tlb_t; > > +typedef struct ppc_hash_pte64 ppc_hash_pte64_t; > > > > /* SPR access micro-ops generations callbacks */ > > struct ppc_spr_t { > > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c > > index 52bbea5..9d3e57e 100644 > > --- a/target/ppc/kvm.c > > +++ b/target/ppc/kvm.c > > @@ -2601,17 +2601,17 @@ struct kvm_get_htab_buf { > > /* > > * We require one extra byte for read > > */ > > - target_ulong hpte[(HPTES_PER_GROUP * 2) + 1]; > > + ppc_hash_pte64_t hpte[HPTES_PER_GROUP]; > > }; > > > > -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong > > pte_index) > > +const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, int n) > > { > > int htab_fd; > > struct kvm_get_htab_fd ghf; > > - struct kvm_get_htab_buf *hpte_buf; > > + struct kvm_get_htab_buf *hpte_buf; > > > > ghf.flags = 0; > > - ghf.start_index = pte_index; > > + ghf.start_index = ptex; > > htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); > > if (htab_fd < 0) { > > goto error_out; > > @@ -2626,7 +2626,7 @@ uint64_t kvmppc_hash64_read_pteg(PowerPCCPU > > *cpu, target_ulong pte_index) > > } > > > > close(htab_fd); > > - return (uint64_t)(uintptr_t) hpte_buf->hpte; > > + return hpte_buf->hpte; > > > > out_close: > > g_free(hpte_buf); > > @@ -2635,18 +2635,15 @@ error_out: > > return 0; > > } > > > > -void kvmppc_hash64_free_pteg(uint64_t token) > > +void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, hwaddr ptex, > > int n) > > { > > struct kvm_get_htab_buf *htab_buf; > > > > - htab_buf = container_of((void *)(uintptr_t) token, struct > > kvm_get_htab_buf, > > - hpte); > > + htab_buf = container_of((void *)hptes, struct kvm_get_htab_buf, > > hpte); > > g_free(htab_buf); > > - return; > > } > > > > -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong > > pte_index, > > - target_ulong pte0, target_ulong pte1) > > +void kvmppc_hash64_write_pte(hwaddr ptex, uint64_t pte0, uint64_t > > pte1) > > { > > int htab_fd; > > struct kvm_get_htab_fd ghf; > > @@ -2661,9 +2658,9 @@ void kvmppc_hash64_write_pte(CPUPPCState *env, > > target_ulong pte_index, > > > > hpte_buf.header.n_valid = 1; > > hpte_buf.header.n_invalid = 0; > > - hpte_buf.header.index = pte_index; > > - hpte_buf.hpte[0] = pte0; > > - hpte_buf.hpte[1] = pte1; > > + hpte_buf.header.index = ptex; > > + hpte_buf.hpte[0].pte0 = pte0; > > + hpte_buf.hpte[0].pte1 = pte1; > > /* > > * Write the hpte entry. > > * CAUTION: write() has the warn_unused_result attribute. Hence > > we > > diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h > > index 8da2ee4..3f8fccd 100644 > > --- a/target/ppc/kvm_ppc.h > > +++ b/target/ppc/kvm_ppc.h > > @@ -41,6 +41,10 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, > > uint32_t window_size, int *pfd, > > int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t > > window_size); > > int kvmppc_reset_htab(int shift_hint); > > uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int > > hash_shift); > > +const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, int n); > > +void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, hwaddr ptex, > > int n); > > + > > +void kvmppc_hash64_write_pte(hwaddr ptex, uint64_t pte0, uint64_t > > pte1); > > #endif /* !CONFIG_USER_ONLY */ > > bool kvmppc_has_cap_epr(void); > > int kvmppc_define_rtas_kernel_token(uint32_t token, const char > > *function); > > @@ -49,11 +53,6 @@ int kvmppc_get_htab_fd(bool write); > > int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t > > max_ns); > > int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index, > > uint16_t n_valid, uint16_t n_invalid); > > -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong > > pte_index); > > -void kvmppc_hash64_free_pteg(uint64_t token); > > - > > -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong > > pte_index, > > - target_ulong pte0, target_ulong pte1); > > bool kvmppc_has_cap_fixup_hcalls(void); > > bool kvmppc_has_cap_htm(void); > > int kvmppc_enable_hwrng(void); > > @@ -199,6 +198,22 @@ static inline bool > > kvmppc_is_mem_backend_page_size_ok(char *obj_path) > > return true; > > } > > > > +static inline const ppc_hash_pte64_t *kvmppc_map_hptes(hwaddr ptex, > > int n) > > +{ > > + abort(); > > +} > > + > > +static inline void kvmppc_unmap_hptes(const ppc_hash_pte64_t *hptes, > > + hwaddr ptex, int n) > > +{ > > + abort(); > > +} > > + > > +static inline void kvmppc_hash64_write_pte(hwaddr ptex, > > + uint64_t pte0, uint64_t > > pte1) > > +{ > > + abort(); > > +} > > #endif /* !CONFIG_USER_ONLY */ > > > > static inline bool kvmppc_has_cap_epr(void) > > @@ -234,24 +249,6 @@ static inline int > > kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index, > > abort(); > > } > > > > -static inline uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, > > - target_ulong > > pte_index) > > -{ > > - abort(); > > -} > > - > > -static inline void kvmppc_hash64_free_pteg(uint64_t token) > > -{ > > - abort(); > > -} > > - > > -static inline void kvmppc_hash64_write_pte(CPUPPCState *env, > > - target_ulong pte_index, > > - target_ulong pte0, > > target_ulong pte1) > > -{ > > - abort(); > > -} > > - > > static inline bool kvmppc_has_cap_fixup_hcalls(void) > > { > > abort(); > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c > > index 76669ed..c59db47 100644 > > --- a/target/ppc/mmu-hash64.c > > +++ b/target/ppc/mmu-hash64.c > > @@ -27,6 +27,7 @@ > > #include "kvm_ppc.h" > > #include "mmu-hash64.h" > > #include "exec/log.h" > > +#include "hw/hw.h" > > > > //#define DEBUG_SLB > > > > @@ -431,33 +432,42 @@ static int ppc_hash64_amr_prot(PowerPCCPU *cpu, > > ppc_hash_pte64_t pte) > > return prot; > > } > > > > -uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong > > pte_index) > > +const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu, > > + hwaddr ptex, int n) > > { > > - uint64_t token = 0; > > - hwaddr pte_offset; > > + const ppc_hash_pte64_t *hptes = NULL; > > + hwaddr pte_offset = ptex * HASH_PTE_SIZE_64; > > > > - pte_offset = pte_index * HASH_PTE_SIZE_64; > > if (cpu->env.external_htab == MMU_HASH64_KVM_MANAGED_HPT) { > > /* > > * HTAB is controlled by KVM. Fetch the PTEG into a new > > buffer. > > */ > > - token = kvmppc_hash64_read_pteg(cpu, pte_index); > > + hptes = kvmppc_map_hptes(ptex, n); > > } else if (cpu->env.external_htab) { > > /* > > * HTAB is controlled by QEMU. Just point to the internally > > * accessible PTEG. > > */ > > - token = (uint64_t)(uintptr_t) cpu->env.external_htab + > > pte_offset; > > + hptes = (ppc_hash_pte64_t *)(cpu->env.external_htab + > > pte_offset); > > } else if (cpu->env.htab_base) { > > - token = cpu->env.htab_base + pte_offset; > > + hwaddr plen = n * HASH_PTE_SIZE_64; > > + hptes = address_space_map(CPU(cpu)->as, cpu->env.htab_base + > > pte_offset, > > + &plen, false); > > + if (plen < (n * HASH_PTE_SIZE_64)) { > > + hw_error("%s: Unable to map all requested HPTEs\n", > > __FUNCTION__); > > + } > > } > > - return token; > > + return hptes; > > } > > > > -void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token) > > +void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t > > *hptes, > > + hwaddr ptex, int n) > > { > > if (cpu->env.external_htab == MMU_HASH64_KVM_MANAGED_HPT) { > > - kvmppc_hash64_free_pteg(token); > > + kvmppc_unmap_hptes(hptes, ptex, n); > > + } else if (!cpu->env.external_htab) { > > + address_space_unmap(CPU(cpu)->as, (void *)hptes, n * > > HASH_PTE_SIZE_64, > > + false, n * HASH_PTE_SIZE_64); > > } > > } > > > > @@ -505,18 +515,18 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU > > *cpu, hwaddr hash, > > { > > CPUPPCState *env = &cpu->env; > > int i; > > - uint64_t token; > > + const ppc_hash_pte64_t *pteg; > > target_ulong pte0, pte1; > > - target_ulong pte_index; > > + target_ulong ptex; > > > > - pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP; > > - token = ppc_hash64_start_access(cpu, pte_index); > > - if (!token) { > > + ptex = (hash & env->htab_mask) * HPTES_PER_GROUP; > > + pteg = ppc_hash64_map_hptes(cpu, ptex, HPTES_PER_GROUP); > > + if (!pteg) { > > return -1; > > } > > for (i = 0; i < HPTES_PER_GROUP; i++) { > > - pte0 = ppc_hash64_load_hpte0(cpu, token, i); > > - pte1 = ppc_hash64_load_hpte1(cpu, token, i); > > + pte0 = ppc_hash64_hpte0(cpu, pteg, i); > > + pte1 = ppc_hash64_hpte1(cpu, pteg, i); > > > > /* This compares V, B, H (secondary) and the AVPN */ > > if (HPTE64_V_COMPARE(pte0, ptem)) { > > @@ -536,11 +546,11 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU > > *cpu, hwaddr hash, > > */ > > pte->pte0 = pte0; > > pte->pte1 = pte1; > > - ppc_hash64_stop_access(cpu, token); > > - return (pte_index + i) * HASH_PTE_SIZE_64; > > + ppc_hash64_unmap_hptes(cpu, pteg, ptex, > > HPTES_PER_GROUP); > > + return ptex + i; > > } > > } > > - ppc_hash64_stop_access(cpu, token); > > + ppc_hash64_unmap_hptes(cpu, pteg, ptex, HPTES_PER_GROUP); > > /* > > * We didn't find a valid entry. > > */ > > @@ -552,8 +562,7 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU > > *cpu, > > ppc_hash_pte64_t *pte, unsigned > > *pshift) > > { > > CPUPPCState *env = &cpu->env; > > - hwaddr pte_offset; > > - hwaddr hash; > > + hwaddr hash, ptex; > > uint64_t vsid, epnmask, epn, ptem; > > const struct ppc_one_seg_page_size *sps = slb->sps; > > > > @@ -596,9 +605,9 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU > > *cpu, > > " 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(cpu, hash, sps, ptem, pte, > > pshift); > > + ptex = ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, > > pshift); > > > > - if (pte_offset == -1) { > > + if (ptex == -1) { > > /* Secondary PTEG lookup */ > > ptem |= HPTE64_V_SECONDARY; > > qemu_log_mask(CPU_LOG_MMU, > > @@ -607,10 +616,10 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU > > *cpu, > > " hash=" TARGET_FMT_plx "\n", env->htab_base, > > env->htab_mask, vsid, ptem, ~hash); > > > > - pte_offset = ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, > > pte, pshift); > > + ptex = ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, > > pshift); > > } > > > > - return pte_offset; > > + return ptex; > > } > > > > unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, > > @@ -708,7 +717,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, > > vaddr eaddr, > > CPUPPCState *env = &cpu->env; > > ppc_slb_t *slb; > > unsigned apshift; > > - hwaddr pte_offset; > > + hwaddr ptex; > > ppc_hash_pte64_t pte; > > int pp_prot, amr_prot, prot; > > uint64_t new_pte1, dsisr; > > @@ -792,8 +801,8 @@ skip_slb_search: > > } > > > > /* 4. Locate the PTE in the hash table */ > > - pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, > > &apshift); > > - if (pte_offset == -1) { > > + ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift); > > + if (ptex == -1) { > > dsisr = 0x40000000; > > if (rwx == 2) { > > ppc_hash64_set_isi(cs, env, dsisr); > > @@ -806,7 +815,7 @@ skip_slb_search: > > return 1; > > } > > qemu_log_mask(CPU_LOG_MMU, > > - "found PTE at offset %08" HWADDR_PRIx "\n", > > pte_offset); > > + "found PTE at index %08" HWADDR_PRIx "\n", ptex); > > > > /* 5. Check access permissions */ > > > > @@ -849,8 +858,7 @@ skip_slb_search: > > } > > > > if (new_pte1 != pte.pte1) { > > - ppc_hash64_store_hpte(cpu, pte_offset / HASH_PTE_SIZE_64, > > - pte.pte0, new_pte1); > > + ppc_hash64_store_hpte(cpu, ptex, pte.pte0, new_pte1); > > } > > > > /* 7. Determine the real address from the PTE */ > > @@ -867,7 +875,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU > > *cpu, target_ulong addr) > > { > > CPUPPCState *env = &cpu->env; > > ppc_slb_t *slb; > > - hwaddr pte_offset, raddr; > > + hwaddr ptex, raddr; > > ppc_hash_pte64_t pte; > > unsigned apshift; > > > > @@ -900,8 +908,8 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU > > *cpu, target_ulong addr) > > } > > } > > > > - pte_offset = ppc_hash64_htab_lookup(cpu, slb, addr, &pte, > > &apshift); > > - if (pte_offset == -1) { > > + ptex = ppc_hash64_htab_lookup(cpu, slb, addr, &pte, &apshift); > > + if (ptex == -1) { > > return -1; > > } > > > > @@ -909,30 +917,28 @@ hwaddr > > ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr) > > & TARGET_PAGE_MASK; > > } > > > > -void ppc_hash64_store_hpte(PowerPCCPU *cpu, > > - target_ulong pte_index, > > - target_ulong pte0, target_ulong pte1) > > +void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, > > + uint64_t pte0, uint64_t pte1) > > { > > CPUPPCState *env = &cpu->env; > > + hwaddr offset = ptex * HASH_PTE_SIZE_64; > > > > if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) { > > - kvmppc_hash64_write_pte(env, pte_index, pte0, pte1); > > + kvmppc_hash64_write_pte(ptex, pte0, pte1); > > return; > > } > > > > - pte_index *= HASH_PTE_SIZE_64; > > if (env->external_htab) { > > - stq_p(env->external_htab + pte_index, pte0); > > - stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64 / 2, > > pte1); > > + stq_p(env->external_htab + offset, pte0); > > + stq_p(env->external_htab + offset + HASH_PTE_SIZE_64 / 2, > > pte1); > > } else { > > - stq_phys(CPU(cpu)->as, env->htab_base + pte_index, pte0); > > + stq_phys(CPU(cpu)->as, env->htab_base + offset, pte0); > > stq_phys(CPU(cpu)->as, > > - env->htab_base + pte_index + HASH_PTE_SIZE_64 / 2, > > pte1); > > + env->htab_base + offset + HASH_PTE_SIZE_64 / 2, > > pte1); > > } > > } > > > > -void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, > > - target_ulong pte_index, > > +void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, target_ulong ptex, > > target_ulong pte0, target_ulong pte1) > > { > > /* > > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h > > index 7a0b7fc..8637fe4 100644 > > --- a/target/ppc/mmu-hash64.h > > +++ b/target/ppc/mmu-hash64.h > > @@ -10,8 +10,8 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong > > slot, > > hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong > > addr); > > int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int > > rw, > > int mmu_idx); > > -void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index, > > - target_ulong pte0, target_ulong pte1); > > +void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex, > > + uint64_t pte0, uint64_t pte1); > > void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, > > target_ulong pte_index, > > target_ulong pte0, target_ulong > > pte1); > > @@ -96,41 +96,27 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, > > target_ulong value, > > void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int > > shift, > > Error **errp); > > > > -uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong > > pte_index); > > -void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token); > > +struct ppc_hash_pte64 { > > + uint64_t pte0, pte1; > > +}; > > + > > +const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,\ > > + hwaddr ptex, int n); > > +void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t > > *hptes, > > + hwaddr ptex, int n); > > > > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu, > > - uint64_t token, int > > index) > > +static inline uint64_t ppc_hash64_hpte0(PowerPCCPU *cpu, > > + const ppc_hash_pte64_t > > *hptes, int i) > > { > > - CPUPPCState *env = &cpu->env; > > - uint64_t addr; > > - > > - addr = token + (index * HASH_PTE_SIZE_64); > > - if (env->external_htab) { > > - return ldq_p((const void *)(uintptr_t)addr); > > - } else { > > - return ldq_phys(CPU(cpu)->as, addr); > > - } > > + return ldq_p(&(hptes[i].pte0)); > > } > > > > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu, > > - uint64_t token, int > > index) > > +static inline uint64_t ppc_hash64_hpte1(PowerPCCPU *cpu, > > + const ppc_hash_pte64_t > > *hptes, int i) > > { > > - CPUPPCState *env = &cpu->env; > > - uint64_t addr; > > - > > - addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2; > > - if (env->external_htab) { > > - return ldq_p((const void *)(uintptr_t)addr); > > - } else { > > - return ldq_phys(CPU(cpu)->as, addr); > > - } > > + return ldq_p(&(hptes[i].pte1)); > > } > > > > -typedef struct { > > - uint64_t pte0, pte1; > > -} ppc_hash_pte64_t; > > - > > #endif /* CONFIG_USER_ONLY */ > > > > #endif /* MMU_HASH64_H */ > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature