From: Zhao Liu <zhao1.liu@intel.com>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Junjie Mao" <junjie.mao@hotmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Peter Maydell" <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, qemu-rust@nongnu.org,
Zhao Liu <zhao1.liu@intel.com>
Subject: [RFC 01/13] bql: check that the BQL is not dropped within marked sections
Date: Thu, 5 Dec 2024 14:07:02 +0800 [thread overview]
Message-ID: <20241205060714.256270-2-zhao1.liu@intel.com> (raw)
In-Reply-To: <20241205060714.256270-1-zhao1.liu@intel.com>
From: Paolo Bonzini <pbonzini@redhat.com>
The Big QEMU Lock (BQL) is used to provide interior mutability to Rust
code. While BqlCell performs indivisible accesses, an equivalent of
RefCell will allow the borrower to hold to the interior content for a
long time. If the BQL is dropped, another thread could come and mutate
the data from C code (Rust code would panic on borrow_mut() instead).
In order to prevent this, add a new BQL primitive that can mark
BQL-atomic sections and aborts if the BQL is dropped within them.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
include/qemu/main-loop.h | 15 +++++++++++++++
stubs/iothread-lock.c | 15 +++++++++++++++
system/cpus.c | 15 +++++++++++++++
3 files changed, 45 insertions(+)
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 5764db157c97..646306c272f7 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -262,6 +262,21 @@ AioContext *iohandler_get_aio_context(void);
*/
bool bql_locked(void);
+/**
+ * bql_block: Allow/deny releasing the BQL
+ *
+ * The Big QEMU Lock (BQL) is used to provide interior mutability to
+ * Rust code, but this only works if other threads cannot run while
+ * the Rust code has an active borrow. This is because C code in
+ * other threads could come in and mutate data under the Rust code's
+ * feet.
+ *
+ * @increase: Whether to increase or decrease the blocking counter.
+ * Releasing the BQL while the counter is nonzero triggers
+ * an assertion failure.
+ */
+void bql_block_unlock(bool increase);
+
/**
* qemu_in_main_thread: return whether it's possible to safely access
* the global state of the block layer.
diff --git a/stubs/iothread-lock.c b/stubs/iothread-lock.c
index d7890e5581c5..54676598950f 100644
--- a/stubs/iothread-lock.c
+++ b/stubs/iothread-lock.c
@@ -1,6 +1,8 @@
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
+static uint32_t bql_unlock_blocked;
+
bool bql_locked(void)
{
return false;
@@ -12,4 +14,17 @@ void bql_lock_impl(const char *file, int line)
void bql_unlock(void)
{
+ assert(!bql_unlock_blocked);
+}
+
+void bql_block_unlock(bool increase)
+{
+ uint32_t new_value;
+
+ assert(bql_locked());
+
+ /* check for overflow! */
+ new_value = bql_unlock_blocked + increase - !increase;
+ assert((new_value > bql_unlock_blocked) == increase);
+ bql_unlock_blocked = new_value;
}
diff --git a/system/cpus.c b/system/cpus.c
index a1b46f68476a..793c4698c7ad 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -514,6 +514,20 @@ bool qemu_in_vcpu_thread(void)
QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked)
+static uint32_t bql_unlock_blocked;
+
+void bql_block_unlock(bool increase)
+{
+ uint32_t new_value;
+
+ assert(bql_locked());
+
+ /* check for overflow! */
+ new_value = bql_unlock_blocked + increase - !increase;
+ assert((new_value > bql_unlock_blocked) == increase);
+ bql_unlock_blocked = new_value;
+}
+
bool bql_locked(void)
{
return get_bql_locked();
@@ -540,6 +554,7 @@ void bql_lock_impl(const char *file, int line)
void bql_unlock(void)
{
g_assert(bql_locked());
+ g_assert(!bql_unlock_blocked);
set_bql_locked(false);
qemu_mutex_unlock(&bql);
}
--
2.34.1
next prev parent reply other threads:[~2024-12-05 5:50 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-05 6:07 [RFC 00/13] rust: Reinvent the wheel for HPET timer in Rust Zhao Liu
2024-12-05 6:07 ` Zhao Liu [this message]
2024-12-05 6:07 ` [RFC 02/13] rust: cell: add BQL-enforcing RefCell variant Zhao Liu
2024-12-05 6:07 ` [RFC 03/13] rust/cell: add get_mut() method for BqlCell Zhao Liu
2024-12-05 15:55 ` Paolo Bonzini
2024-12-07 15:56 ` Zhao Liu
2024-12-07 19:49 ` Paolo Bonzini
2024-12-05 6:07 ` [RFC 04/13] rust: add bindings for gpio_{in|out} initialization Zhao Liu
2024-12-05 18:53 ` Paolo Bonzini
2024-12-08 16:27 ` Zhao Liu
2024-12-09 11:08 ` Paolo Bonzini
2025-01-16 3:04 ` Zhao Liu
2025-01-17 9:40 ` Paolo Bonzini
2025-01-17 11:14 ` Zhao Liu
2025-01-17 12:47 ` Paolo Bonzini
2024-12-05 6:07 ` [RFC 05/13] rust: add a bit operation binding for deposit64 Zhao Liu
2024-12-05 16:09 ` Paolo Bonzini
2024-12-07 16:01 ` Zhao Liu
2024-12-07 19:44 ` Paolo Bonzini
2024-12-05 6:07 ` [RFC 06/13] rust: add bindings for memattrs Zhao Liu
2024-12-05 18:15 ` Richard Henderson
2024-12-05 18:30 ` Paolo Bonzini
2024-12-05 23:51 ` Richard Henderson
2024-12-06 8:41 ` Zhao Liu
2024-12-06 14:07 ` Richard Henderson
2024-12-06 10:59 ` Peter Maydell
2024-12-06 14:28 ` Paolo Bonzini
2024-12-06 14:42 ` Peter Maydell
2024-12-06 19:13 ` Paolo Bonzini
2025-01-20 16:52 ` Zhao Liu
2025-01-20 17:19 ` Paolo Bonzini
2025-01-23 15:10 ` Zhao Liu
2025-01-23 15:33 ` Paolo Bonzini
2024-12-07 9:21 ` Philippe Mathieu-Daudé
2024-12-08 9:30 ` Paolo Bonzini
2024-12-08 15:51 ` Zhao Liu
2024-12-05 6:07 ` [RFC 07/13] rust: add bindings for timer Zhao Liu
2024-12-05 18:18 ` Richard Henderson
2024-12-07 17:18 ` Zhao Liu
2024-12-05 18:46 ` Paolo Bonzini
2024-12-07 16:54 ` Zhao Liu
2025-01-14 15:36 ` Zhao Liu
2025-01-14 15:42 ` Zhao Liu
2025-01-14 16:14 ` Paolo Bonzini
2025-01-15 7:09 ` Zhao Liu
2024-12-05 6:07 ` [RFC 08/13] rust/qdev: add the macro to define bit property Zhao Liu
2024-12-05 6:07 ` [RFC 09/13] i386/fw_cfg: move hpet_cfg definition to hpet.c Zhao Liu
2024-12-05 12:04 ` Philippe Mathieu-Daudé
2024-12-05 12:46 ` Zhao Liu
2024-12-05 21:17 ` Philippe Mathieu-Daudé
2024-12-05 21:19 ` Paolo Bonzini
2024-12-07 9:16 ` Philippe Mathieu-Daudé
2024-12-07 15:36 ` Zhao Liu
2024-12-05 15:30 ` Paolo Bonzini
2024-12-07 15:28 ` Zhao Liu
2025-01-17 10:31 ` Zhao Liu
2025-01-17 10:15 ` Paolo Bonzini
2024-12-05 6:07 ` [RFC 10/13] rust/timer/hpet: define hpet_fw_cfg Zhao Liu
2024-12-05 6:07 ` [RFC 11/13] rust/timer/hpet: add basic HPET timer & state Zhao Liu
2024-12-05 20:22 ` Paolo Bonzini
2024-12-05 21:20 ` Paolo Bonzini
2024-12-09 7:46 ` Zhao Liu
2024-12-09 7:26 ` Zhao Liu
2024-12-05 6:07 ` [RFC 12/13] rust/timer/hpet: add qdev APIs support Zhao Liu
2024-12-05 18:58 ` Paolo Bonzini
2024-12-07 16:05 ` Zhao Liu
2024-12-05 6:07 ` [RFC 13/13] i386: enable rust hpet for pc when rust is enabled Zhao Liu
2024-12-05 15:20 ` Paolo Bonzini
2024-12-06 9:06 ` Zhao Liu
2024-12-05 6:22 ` [RFC 00/13] rust: Reinvent the wheel for HPET timer in Rust Zhao Liu
2024-12-05 16:28 ` Paolo Bonzini
2024-12-09 7:57 ` Zhao Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241205060714.256270-2-zhao1.liu@intel.com \
--to=zhao1.liu@intel.com \
--cc=alex.bennee@linaro.org \
--cc=junjie.mao@hotmail.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-rust@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).