Commit 8436d21c04 for qemu.org
commit 8436d21c0488d10bcd634bbb884a6909c322a9d9
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date: Sat Sep 26 19:43:45 2026 -0700
hw/hexagon: protect the shared architectural TLB
Add a mutex to HexagonTLBState and hold it while interacting with TLB
entries.
Reviewed-by: Marco Liebel <marco.liebel@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 157d03e51b..28601b78a6 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,
};
diff --git a/include/hw/hexagon/hexagon_tlb.h b/include/hw/hexagon/hexagon_tlb.h
index 6bc33c0545..56aa0b2bee 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,