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>
This commit is contained in:
parent
a2dd4e83e7
commit
6e8a65abbb
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user