[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 22/50] target/ppc: Fix ordering of hash MMU accesses
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PULL 22/50] target/ppc: Fix ordering of hash MMU accesses |
Date: |
Tue, 26 Feb 2019 15:52:36 +1100 |
From: Benjamin Herrenschmidt <address@hidden>
With mttcg, we can have MMU lookups happening at the same time
as the guest modifying the page tables.
Since the HPTEs of the hash table MMU contains two words (or
double worlds on 64-bit), we need to make sure we read them
in the right order, with the correct memory barrier.
Additionally, when using emulated SPAPR mode, the hypercalls
writing to the hash table must also perform the udpates in
the right order.
Note: This part is still not entirely correct
Signed-off-by: Benjamin Herrenschmidt <address@hidden>
Signed-off-by: Cédric Le Goater <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr.c | 21 +++++++++++++++++++--
target/ppc/mmu-hash32.c | 6 ++++++
target/ppc/mmu-hash64.c | 6 ++++++
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 84f6e9d9a8..d2520bc662 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1524,8 +1524,25 @@ static void spapr_store_hpte(PPCVirtualHypervisor *vhyp,
hwaddr ptex,
if (!spapr->htab) {
kvmppc_write_hpte(ptex, pte0, pte1);
} else {
- stq_p(spapr->htab + offset, pte0);
- stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1);
+ if (pte0 & HPTE64_V_VALID) {
+ stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1);
+ /*
+ * When setting valid, we write PTE1 first. This ensures
+ * proper synchronization with the reading code in
+ * ppc_hash64_pteg_search()
+ */
+ smp_wmb();
+ stq_p(spapr->htab + offset, pte0);
+ } else {
+ stq_p(spapr->htab + offset, pte0);
+ /*
+ * When clearing it we set PTE0 first. This ensures proper
+ * synchronization with the reading code in
+ * ppc_hash64_pteg_search()
+ */
+ smp_wmb();
+ stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1);
+ }
}
}
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index 03ae3c1279..e8562a7c87 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -319,6 +319,12 @@ static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu,
hwaddr pteg_off,
for (i = 0; i < HPTES_PER_GROUP; i++) {
pte0 = ppc_hash32_load_hpte0(cpu, pte_offset);
+ /*
+ * pte0 contains the valid bit and must be read before pte1,
+ * otherwise we might see an old pte1 with a new valid bit and
+ * thus an inconsistent hpte value
+ */
+ smp_rmb();
pte1 = ppc_hash32_load_hpte1(cpu, pte_offset);
if ((pte0 & HPTE32_V_VALID)
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 1175b991d9..fbefe5b5aa 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -507,6 +507,12 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,
hwaddr hash,
}
for (i = 0; i < HPTES_PER_GROUP; i++) {
pte0 = ppc_hash64_hpte0(cpu, pteg, i);
+ /*
+ * pte0 contains the valid bit and must be read before pte1,
+ * otherwise we might see an old pte1 with a new valid bit and
+ * thus an inconsistent hpte value
+ */
+ smp_rmb();
pte1 = ppc_hash64_hpte1(cpu, pteg, i);
/* This compares V, B, H (secondary) and the AVPN */
--
2.20.1
- [Qemu-ppc] [PULL 06/50] target/ppc: Add POWER9 exception model, (continued)
- [Qemu-ppc] [PULL 06/50] target/ppc: Add POWER9 exception model, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 12/50] cpus: Properly release the iothread lock when killing a dummy VCPU, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 15/50] tests/device-plug: Add CCW unplug test for s390x, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 17/50] tests/device-plug: Add memory unplug request test for spapr, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 16/50] tests/device-plug: Add CPU core unplug request test for spapr, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 24/50] target/ppc: Fix synchronization of mttcg with broadcast TLB flushes, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 26/50] target/ppc: Rename PATB/PATBE -> PATE, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 14/50] tests/device-plug: Add a simple PCI unplug request test, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 25/50] target/ppc: Flush the TLB locally when the LPIDR is written, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 23/50] target/ppc: Add basic support for "new format" HPTE as found on POWER9, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 22/50] target/ppc: Fix ordering of hash MMU accesses,
David Gibson <=
- [Qemu-ppc] [PULL 28/50] target/ppc: Basic POWER9 bare-metal radix MMU support, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 35/50] spapr: Expose the name of the interrupt controller node, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 27/50] target/ppc: Support for POWER9 native hash, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 30/50] spapr: Generate FDT fragment for LMBs at configure connector time, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 39/50] spapr: populate PHB DRC entries for root DT node, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 46/50] ppc/xive: xive does not have a POWER7 interrupt model, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 29/50] spapr_drc: Allow FDT fragment to be added later, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 33/50] spapr/drc: Drop spapr_drc_attach() fdt argument, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 38/50] spapr: create DR connectors for PHBs, David Gibson, 2019/02/25
- [Qemu-ppc] [PULL 49/50] ppc/pnv: add INITRD_MAX_SIZE constant, David Gibson, 2019/02/25