Add a mutex to HexagonTLBState and hold it while interacting with TLB
entries.

Signed-off-by: Brian Cain <[email protected]>
---
 include/hw/hexagon/hexagon_tlb.h |  5 ++++-
 hw/hexagon/hexagon_tlb.c         | 27 ++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/include/hw/hexagon/hexagon_tlb.h b/include/hw/hexagon/hexagon_tlb.h
index 6bc33c05452..56aa0b2beed 100644
--- a/include/hw/hexagon/hexagon_tlb.h
+++ b/include/hw/hexagon/hexagon_tlb.h
@@ -13,6 +13,7 @@
 #include "exec/hwaddr.h"
 #include "exec/mmu-access-type.h"
 #include "monitor/hmp.h"
+#include "qemu/thread.h"
 
 #define TYPE_HEXAGON_TLB "hexagon-tlb"
 OBJECT_DECLARE_SIMPLE_TYPE(HexagonTLBState, HEXAGON_TLB)
@@ -22,10 +23,12 @@ struct HexagonTLBState {
 
     uint32_t num_entries;
     uint64_t *entries;
+    QemuMutex lock;
 };
 
 uint64_t hexagon_tlb_read(HexagonTLBState *tlb, uint32_t index);
-void hexagon_tlb_write(HexagonTLBState *tlb, uint32_t index, uint64_t value);
+uint64_t hexagon_tlb_write(HexagonTLBState *tlb, uint32_t index,
+                           uint64_t value);
 
 bool hexagon_tlb_find_match(HexagonTLBState *tlb, uint32_t asid,
                             uint32_t VA, MMUAccessType access_type,
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 157d03e51bf..28601b78a6f 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -7,6 +7,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/log.h"
+#include "qemu/lockable.h"
 #include "hw/hexagon/hexagon_tlb.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/resettable.h"
@@ -162,6 +163,7 @@ bool hexagon_tlb_dump_entry(MonitorHMP *hmp, uint64_t entry)
 
 void hexagon_tlb_dump(MonitorHMP *hmp, HexagonTLBState *tlb)
 {
+    QEMU_LOCK_GUARD(&tlb->lock);
     for (uint32_t i = 0; i < tlb->num_entries; i++) {
         hexagon_tlb_dump_entry(hmp, tlb->entries[i]);
     }
@@ -303,13 +305,20 @@ static bool hex_tlb_is_match(uint64_t entry1, uint64_t 
entry2,
 uint64_t hexagon_tlb_read(HexagonTLBState *tlb, uint32_t index)
 {
     g_assert(index < tlb->num_entries);
+    QEMU_LOCK_GUARD(&tlb->lock);
     return tlb->entries[index];
 }
 
-void hexagon_tlb_write(HexagonTLBState *tlb, uint32_t index, uint64_t value)
+uint64_t hexagon_tlb_write(HexagonTLBState *tlb, uint32_t index,
+                           uint64_t value)
 {
+    uint64_t old;
+
     g_assert(index < tlb->num_entries);
+    QEMU_LOCK_GUARD(&tlb->lock);
+    old = tlb->entries[index];
     tlb->entries[index] = value;
+    return old;
 }
 
 bool hexagon_tlb_find_match(HexagonTLBState *tlb, uint32_t asid,
@@ -323,6 +332,7 @@ bool hexagon_tlb_find_match(HexagonTLBState *tlb, uint32_t 
asid,
     *excp = 0;
     *cause_code = 0;
 
+    QEMU_LOCK_GUARD(&tlb->lock);
     for (uint32_t i = 0; i < tlb->num_entries; i++) {
         if (hex_tlb_entry_match(tlb->entries[i], asid, VA, access_type,
                                 PA, prot, size, excp, cause_code, mmu_idx)) {
@@ -349,6 +359,7 @@ uint32_t hexagon_tlb_lookup(HexagonTLBState *tlb, uint32_t 
asid,
     uint32_t not_found = 0x80000000;
     uint32_t idx = not_found;
 
+    QEMU_LOCK_GUARD(&tlb->lock);
     *imprecise_exception = 0;
     for (uint32_t i = 0; i < tlb->num_entries; i++) {
         uint64_t entry = tlb->entries[i];
@@ -387,6 +398,7 @@ int hexagon_tlb_check_overlap(HexagonTLBState *tlb, 
uint64_t entry,
     int matches = 0;
     int last_match = 0;
 
+    QEMU_LOCK_GUARD(&tlb->lock);
     for (uint32_t i = 0; i < tlb->num_entries; i++) {
         if (hex_tlb_is_match(entry, tlb->entries[i], false)) {
             matches++;
@@ -412,6 +424,16 @@ uint32_t hexagon_tlb_get_num_entries(HexagonTLBState *tlb)
 
 static void hexagon_tlb_init(Object *obj)
 {
+    HexagonTLBState *s = HEXAGON_TLB(obj);
+
+    qemu_mutex_init(&s->lock);
+}
+
+static void hexagon_tlb_finalize(Object *obj)
+{
+    HexagonTLBState *s = HEXAGON_TLB(obj);
+
+    qemu_mutex_destroy(&s->lock);
 }
 
 static void hexagon_tlb_realize(DeviceState *dev, Error **errp)
@@ -436,6 +458,8 @@ static void hexagon_tlb_unrealize(DeviceState *dev)
 static void hexagon_tlb_reset_hold(Object *obj, ResetType type)
 {
     HexagonTLBState *s = HEXAGON_TLB(obj);
+
+    QEMU_LOCK_GUARD(&s->lock);
     if (s->entries) {
         memset(s->entries, 0, sizeof(uint64_t) * s->num_entries);
     }
@@ -476,6 +500,7 @@ static const TypeInfo hexagon_tlb_info = {
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(HexagonTLBState),
     .instance_init = hexagon_tlb_init,
+    .instance_finalize = hexagon_tlb_finalize,
     .class_init = hexagon_tlb_class_init,
 };
 
-- 
2.34.1

Reply via email to