qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 4/6] target/ppc: Cleanup HPTE accessors for 64-b


From: David Gibson
Subject: Re: [Qemu-devel] [PATCH 4/6] target/ppc: Cleanup HPTE accessors for 64-bit hash MMU
Date: Fri, 24 Feb 2017 16:25:04 +1100
User-agent: Mutt/1.7.1 (2016-10-04)

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 <address@hidden>
> 
> Other than the commit message:
> 
> Reviewed-by: Suraj Jitindar Singh <address@hidden>
> 
> > ---
> >  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

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]