#include "exec/exec-all.h"
#include "tcg/tcg.h"
#include "qemu/bitops.h"
+#include "qemu/rcu.h"
#include "exec/cpu_ldst.h"
#include "exec/translate-all.h"
#include "exec/helper-proto.h"
}
typedef struct PageFlagsNode {
+ struct rcu_head rcu;
IntervalTreeNode itree;
int flags;
} PageFlagsNode;
}
} else if (p_last <= last) {
/* Range completely covers node -- remove it. */
- g_free(p);
+ g_free_rcu(p, rcu);
} else {
/* Truncate the node from the start. */
p->itree.start = last + 1;
if (prev) {
if (next) {
prev->itree.last = next->itree.last;
- g_free(next);
+ g_free_rcu(next, rcu);
} else {
prev->itree.last = last;
}
p->flags = merge_flags;
} else {
interval_tree_remove(&p->itree, &pageflags_root);
- g_free(p);
+ g_free_rcu(p, rcu);
}
goto done;
}
p->flags = merge_flags;
} else {
interval_tree_remove(&p->itree, &pageflags_root);
- g_free(p);
+ g_free_rcu(p, rcu);
}
if (p_last < last) {
start = p_last + 1;
p->itree.start = last + 1;
interval_tree_insert(&p->itree, &pageflags_root);
} else {
- g_free(p);
+ g_free_rcu(p, rcu);
goto restart;
}
if (set_flags) {
#define TBD_MASK (TARGET_PAGE_MASK * TPD_PAGES)
typedef struct TargetPageDataNode {
+ struct rcu_head rcu;
IntervalTreeNode itree;
char data[TPD_PAGES][TARGET_PAGE_DATA_SIZE] __attribute__((aligned));
} TargetPageDataNode;
n = next,
next = next ? interval_tree_iter_next(n, start, last) : NULL) {
target_ulong n_start, n_last, p_ofs, p_len;
- TargetPageDataNode *t;
+ TargetPageDataNode *t = container_of(n, TargetPageDataNode, itree);
if (n->start >= start && n->last <= last) {
interval_tree_remove(n, &targetdata_root);
- g_free(n);
+ g_free_rcu(t, rcu);
continue;
}
n_last = MIN(last, n->last);
p_len = (n_last + 1 - n_start) >> TARGET_PAGE_BITS;
- t = container_of(n, TargetPageDataNode, itree);
memset(t->data[p_ofs], 0, p_len * TARGET_PAGE_DATA_SIZE);
}
}