diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-04-11 10:00:02 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-04-26 11:37:57 +1000 |
commit | 6e8a65abbbd47a870ddc37484e7c9f183b7a7cce (patch) | |
tree | c0e0438bde05f398359d4683ebfb5d1de128efb6 /target | |
parent | a2dd4e83e76ba9c0d432145059dd9e2b2a096e2b (diff) |
ppc/hash32: Rework R and C bit updates
With MT-TCG, we are now running translation in a racy way, thus
we need to mimic hardware when it comes to updating the R and
C bits, by doing byte stores.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190411080004.8690-5-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/mmu-hash32.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c index 3f4dee835e..55cf156a0b 100644 --- a/target/ppc/mmu-hash32.c +++ b/target/ppc/mmu-hash32.c @@ -345,6 +345,24 @@ static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu, hwaddr pteg_off, return -1; } +static void ppc_hash32_set_r(PowerPCCPU *cpu, hwaddr pte_offset, uint32_t pte1) +{ + target_ulong base = ppc_hash32_hpt_base(cpu); + hwaddr offset = pte_offset + 6; + + /* The HW performs a non-atomic byte update */ + stb_phys(CPU(cpu)->as, base + offset, ((pte1 >> 8) & 0xff) | 0x01); +} + +static void ppc_hash32_set_c(PowerPCCPU *cpu, hwaddr pte_offset, uint64_t pte1) +{ + target_ulong base = ppc_hash32_hpt_base(cpu); + hwaddr offset = pte_offset + 7; + + /* The HW performs a non-atomic byte update */ + stb_phys(CPU(cpu)->as, base + offset, (pte1 & 0xff) | 0x80); +} + static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu, target_ulong sr, target_ulong eaddr, ppc_hash_pte32_t *pte) @@ -403,7 +421,6 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, hwaddr pte_offset; ppc_hash_pte32_t pte; int prot; - uint32_t new_pte1; const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; hwaddr raddr; @@ -519,20 +536,20 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, /* 8. Update PTE referenced and changed bits if necessary */ - new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */ - if (rwx == 1) { - new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */ - } else { - /* - * Treat the page as read-only for now, so that a later write - * will pass through this function again to set the C bit - */ - prot &= ~PAGE_WRITE; - } - - if (new_pte1 != pte.pte1) { - ppc_hash32_store_hpte1(cpu, pte_offset, new_pte1); + if (!(pte.pte1 & HPTE32_R_R)) { + ppc_hash32_set_r(cpu, pte_offset, pte.pte1); } + if (!(pte.pte1 & HPTE32_R_C)) { + if (rwx == 1) { + ppc_hash32_set_c(cpu, pte_offset, pte.pte1); + } else { + /* + * Treat the page as read-only for now, so that a later write + * will pass through this function again to set the C bit + */ + prot &= ~PAGE_WRITE; + } + } /* 9. Determine the real address from the PTE */ |