aboutsummaryrefslogtreecommitdiff
path: root/softmmu
diff options
context:
space:
mode:
Diffstat (limited to 'softmmu')
-rw-r--r--softmmu/physmem.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index f1275b61f8..3c1912a1a0 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -3684,8 +3684,14 @@ void mtree_print_dispatch(AddressSpaceDispatch *d, MemoryRegion *root)
}
}
+/* Require any discards to work. */
static unsigned int ram_block_discard_required_cnt;
+/* Require only coordinated discards to work. */
+static unsigned int ram_block_coordinated_discard_required_cnt;
+/* Disable any discards. */
static unsigned int ram_block_discard_disabled_cnt;
+/* Disable only uncoordinated discards. */
+static unsigned int ram_block_uncoordinated_discard_disabled_cnt;
static QemuMutex ram_block_discard_disable_mutex;
static void ram_block_discard_disable_mutex_lock(void)
@@ -3711,10 +3717,27 @@ int ram_block_discard_disable(bool state)
ram_block_discard_disable_mutex_lock();
if (!state) {
ram_block_discard_disabled_cnt--;
- } else if (!ram_block_discard_required_cnt) {
- ram_block_discard_disabled_cnt++;
+ } else if (ram_block_discard_required_cnt ||
+ ram_block_coordinated_discard_required_cnt) {
+ ret = -EBUSY;
} else {
+ ram_block_discard_disabled_cnt++;
+ }
+ ram_block_discard_disable_mutex_unlock();
+ return ret;
+}
+
+int ram_block_uncoordinated_discard_disable(bool state)
+{
+ int ret = 0;
+
+ ram_block_discard_disable_mutex_lock();
+ if (!state) {
+ ram_block_uncoordinated_discard_disabled_cnt--;
+ } else if (ram_block_discard_required_cnt) {
ret = -EBUSY;
+ } else {
+ ram_block_uncoordinated_discard_disabled_cnt++;
}
ram_block_discard_disable_mutex_unlock();
return ret;
@@ -3727,10 +3750,27 @@ int ram_block_discard_require(bool state)
ram_block_discard_disable_mutex_lock();
if (!state) {
ram_block_discard_required_cnt--;
- } else if (!ram_block_discard_disabled_cnt) {
- ram_block_discard_required_cnt++;
+ } else if (ram_block_discard_disabled_cnt ||
+ ram_block_uncoordinated_discard_disabled_cnt) {
+ ret = -EBUSY;
} else {
+ ram_block_discard_required_cnt++;
+ }
+ ram_block_discard_disable_mutex_unlock();
+ return ret;
+}
+
+int ram_block_coordinated_discard_require(bool state)
+{
+ int ret = 0;
+
+ ram_block_discard_disable_mutex_lock();
+ if (!state) {
+ ram_block_coordinated_discard_required_cnt--;
+ } else if (ram_block_discard_disabled_cnt) {
ret = -EBUSY;
+ } else {
+ ram_block_coordinated_discard_required_cnt++;
}
ram_block_discard_disable_mutex_unlock();
return ret;
@@ -3738,10 +3778,12 @@ int ram_block_discard_require(bool state)
bool ram_block_discard_is_disabled(void)
{
- return qatomic_read(&ram_block_discard_disabled_cnt);
+ return qatomic_read(&ram_block_discard_disabled_cnt) ||
+ qatomic_read(&ram_block_uncoordinated_discard_disabled_cnt);
}
bool ram_block_discard_is_required(void)
{
- return qatomic_read(&ram_block_discard_required_cnt);
+ return qatomic_read(&ram_block_discard_required_cnt) ||
+ qatomic_read(&ram_block_coordinated_discard_required_cnt);
}