[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 1/1] arm/ptw: Handle atomic updates of page tables entries in
From: |
Jonathan Cameron |
Subject: |
[RFC PATCH 1/1] arm/ptw: Handle atomic updates of page tables entries in MMIO during PTW. |
Date: |
Thu, 15 Feb 2024 15:18:04 +0000 |
I'm far from confident this handling here is correct. Hence
RFC. In particular not sure on what locks I should hold for this
to be even moderately safe.
The function already appears to be inconsistent in what it returns
as the CONFIG_ATOMIC64 block returns the endian converted 'eventual'
value of the cmpxchg whereas the TCG_OVERSIZED_GUEST case returns
the previous value.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
target/arm/ptw.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 5eb3577bcd..37ddb4a4db 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -711,8 +711,38 @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t
old_val,
void *host = ptw->out_host;
if (unlikely(!host)) {
- fi->type = ARMFault_UnsuppAtomicUpdate;
- return 0;
+ /* Can I do a load and store via the physical address */
+
+ bool locked = bql_locked();
+ if (!locked) {
+ bql_lock();
+ }
+ /* Page table in MMIO Memory Region */
+ if (ptw->out_be) {
+ old_val = cpu_to_be64(old_val);
+ new_val = cpu_to_be64(new_val);
+ cpu_physical_memory_read(ptw->out_phys, &cur_val, 8);
+ if (cur_val == old_val) {
+ cpu_physical_memory_write(ptw->out_phys, &new_val, 8);
+ cur_val = be64_to_cpu(new_val);
+ } else {
+ cur_val = be64_to_cpu(cur_val);
+ }
+ } else {
+ old_val = cpu_to_le64(old_val);
+ new_val = cpu_to_le64(new_val);
+ cpu_physical_memory_read(ptw->out_phys, &cur_val, 8);
+ if (cur_val == old_val) {
+ cpu_physical_memory_write(ptw->out_phys, &new_val, 8);
+ cur_val = le64_to_cpu(new_val);
+ } else {
+ cur_val = le64_to_cpu(cur_val);
+ }
+ }
+ if (!locked) {
+ bql_unlock();
+ }
+ return cur_val;
}
/*
--
2.39.2