1616#include <simics/base/conf-object.h>
1717#include <simics/base/version.h>
1818#include <simics/util/swabber.h>
19+ #include <simics/base/object-locks.h>
1920#include <simics/model-iface/bank-instrumentation.h>
2021#include <simics/simulator/conf-object.h>
2122#include <simics/util/alloc.h>
@@ -633,6 +634,22 @@ FOR_ENDIAN_VARIANTS(DEFINE_PRECHANGE);
633634#undef FOR_ALL_BITSIZES
634635#undef FOR_ENDIAN_VARIANTS
635636
637+
638+ #define DML_THREAD_AWARE_IFACE_CALL (target_obj , call_expr ) (({ \
639+ domain_lock_t *__lock; \
640+ SIM_ACQUIRE_TARGET(target_obj, &__lock); \
641+ __auto_type __iface_ret = call_expr; \
642+ SIM_RELEASE_TARGET(target_obj, &__lock); \
643+ __iface_ret; \
644+ }))
645+
646+ #define DML_THREAD_AWARE_IFACE_CALL_VOID (target_obj , call_expr ) (({ \
647+ domain_lock_t *__lock; \
648+ SIM_ACQUIRE_TARGET(target_obj, &__lock); \
649+ call_expr; \
650+ SIM_RELEASE_TARGET(target_obj, &__lock); \
651+ }))
652+
636653UNUSED static attr_value_t
637654_serialize_identity (const _id_info_t * id_info_array , const _identity_t id ) {
638655 if (unlikely (id .id ) == 0 ) {
@@ -1293,15 +1310,23 @@ _DML_execute_immediate_afters_now(conf_object_t *dev,
12931310UNUSED static void
12941311_DML_execute_immediate_afters (conf_object_t * dev , lang_void * aux ) {
12951312 _dml_immediate_after_state_t * state = (_dml_immediate_after_state_t * )aux ;
1296- ASSERT (state -> posted );
1313+ // Only acquire the device if it hasn't been deleted to avoid a
1314+ // use-after-free. There's no possibility of a data race on state->deleted
1315+ // (nor any other part of the state if state->deleted is true) as the
1316+ // device can only be deleted in global context.
12971317 if (unlikely (state -> deleted )) {
1318+ ASSERT (state -> posted );
12981319 ASSERT (QEMPTY (state -> queue ));
12991320 // No need to call QFREE, already done
13001321 MM_FREE (state );
13011322 return ;
13021323 }
1324+ domain_lock_t * lock ;
1325+ SIM_ACQUIRE_OBJECT (dev , & lock );
1326+ ASSERT (state -> posted );
13031327 if (unlikely (QEMPTY (state -> queue ))) {
13041328 state -> posted = false;
1329+ SIM_RELEASE_OBJECT (dev , & lock );
13051330 return ;
13061331 }
13071332 _dml_immediate_after_queue_elem_t elem = QREMOVE (state -> queue );
@@ -1314,6 +1339,7 @@ _DML_execute_immediate_afters(conf_object_t *dev, lang_void *aux) {
13141339 }
13151340 elem .callback (dev , elem .data .indices , elem .data .args );
13161341 _free_simple_event_data (elem .data );
1342+ SIM_RELEASE_OBJECT (dev , & lock );
13171343}
13181344
13191345UNUSED static void
0 commit comments