diff mbox series

[2/7] target/sparc: Check for transaction failures in MMU passthrough ASIs

Message ID 20190801183012.17564-3-peter.maydell@linaro.org
State Accepted
Commit b9f5fdad49c74583dcf9fcba0805b148e3992e13
Headers show
Series target/sparc: Convert to do_transaction_failed hook | expand

Commit Message

Peter Maydell Aug. 1, 2019, 6:30 p.m. UTC
Currently the ld/st_asi helper functions make calls to the
ld*_phys() and st*_phys() functions for those ASIs which
imply direct accesses to physical addresses. These implicitly
rely on the unassigned_access hook to cause them to generate
an MMU fault if the access fails.

Switch to using the address_space_* functions instead, which
return a MemTxResult that we can check. This means that when
we switch SPARC over to using the do_transaction_failed hook
we'll still get the same MMU faults we did before.

This commit converts the ASIs which do "MMU passthrough".

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

---
 target/sparc/ldst_helper.c | 49 +++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 16 deletions(-)

-- 
2.20.1

Comments

Richard Henderson Aug. 1, 2019, 8:18 p.m. UTC | #1
On 8/1/19 11:30 AM, Peter Maydell wrote:
> Currently the ld/st_asi helper functions make calls to the

> ld*_phys() and st*_phys() functions for those ASIs which

> imply direct accesses to physical addresses. These implicitly

> rely on the unassigned_access hook to cause them to generate

> an MMU fault if the access fails.

> 

> Switch to using the address_space_* functions instead, which

> return a MemTxResult that we can check. This means that when

> we switch SPARC over to using the do_transaction_failed hook

> we'll still get the same MMU faults we did before.

> 

> This commit converts the ASIs which do "MMU passthrough".

> 

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

> ---

>  target/sparc/ldst_helper.c | 49 +++++++++++++++++++++++++-------------

>  1 file changed, 33 insertions(+), 16 deletions(-)


Reviewed-by: Richard Henderson <richard.henderson@linaro.org>



r~
diff mbox series

Patch

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 26876e5a575..39698c58859 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -718,26 +718,36 @@  uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     case ASI_M_DATAC_DATA: /* SparcStation 5 D-cache data */
         break;
     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
+    {
+        MemTxResult result;
+        hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
+
         switch (size) {
         case 1:
-            ret = ldub_phys(cs->as, (hwaddr)addr
-                            | ((hwaddr)(asi & 0xf) << 32));
+            ret = address_space_ldub(cs->as, access_addr,
+                                     MEMTXATTRS_UNSPECIFIED, &result);
             break;
         case 2:
-            ret = lduw_phys(cs->as, (hwaddr)addr
-                            | ((hwaddr)(asi & 0xf) << 32));
+            ret = address_space_lduw(cs->as, access_addr,
+                                     MEMTXATTRS_UNSPECIFIED, &result);
             break;
         default:
         case 4:
-            ret = ldl_phys(cs->as, (hwaddr)addr
-                           | ((hwaddr)(asi & 0xf) << 32));
+            ret = address_space_ldl(cs->as, access_addr,
+                                    MEMTXATTRS_UNSPECIFIED, &result);
             break;
         case 8:
-            ret = ldq_phys(cs->as, (hwaddr)addr
-                           | ((hwaddr)(asi & 0xf) << 32));
+            ret = address_space_ldq(cs->as, access_addr,
+                                    MEMTXATTRS_UNSPECIFIED, &result);
             break;
         }
+
+        if (result != MEMTX_OK) {
+            sparc_raise_mmu_fault(cs, access_addr, false, false, false,
+                                  size, GETPC());
+        }
         break;
+    }
     case 0x30: /* Turbosparc secondary cache diagnostic */
     case 0x31: /* Turbosparc RAM snoop */
     case 0x32: /* Turbosparc page table descriptor diagnostic */
@@ -1053,25 +1063,32 @@  void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
         break;
     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
         {
+            MemTxResult result;
+            hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
+
             switch (size) {
             case 1:
-                stb_phys(cs->as, (hwaddr)addr
-                         | ((hwaddr)(asi & 0xf) << 32), val);
+                address_space_stb(cs->as, access_addr, val,
+                                  MEMTXATTRS_UNSPECIFIED, &result);
                 break;
             case 2:
-                stw_phys(cs->as, (hwaddr)addr
-                         | ((hwaddr)(asi & 0xf) << 32), val);
+                address_space_stw(cs->as, access_addr, val,
+                                  MEMTXATTRS_UNSPECIFIED, &result);
                 break;
             case 4:
             default:
-                stl_phys(cs->as, (hwaddr)addr
-                         | ((hwaddr)(asi & 0xf) << 32), val);
+                address_space_stl(cs->as, access_addr, val,
+                                  MEMTXATTRS_UNSPECIFIED, &result);
                 break;
             case 8:
-                stq_phys(cs->as, (hwaddr)addr
-                         | ((hwaddr)(asi & 0xf) << 32), val);
+                address_space_stq(cs->as, access_addr, val,
+                                  MEMTXATTRS_UNSPECIFIED, &result);
                 break;
             }
+            if (result != MEMTX_OK) {
+                sparc_raise_mmu_fault(cs, access_addr, true, false, false,
+                                      size, GETPC());
+            }
         }
         break;
     case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */