[PATCH 1/1] aarch32 cpu secure register tcg migration

Tao Ding <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel
Message-ID <[email protected]>
In TCG mode, cpu_pre_save is called when saving state and cpu_post_load
is called when restore state. There are two key functions write_cpustate_to_list
and write_list_to_cpustate that use kvm_to_cpreg_id to obtain the regidx.

However, during the processing of kvm_to_cpreg_id, secure state information will
be lost in aarch32 cpu.
The code in kvm_to_cpreg_id always add the NS flag.
     "cpregid |= CP_REG_AA32_NS_MASK;"

The final result is that after migration, some secure registers were not restored, 
such as DACR_S. And this register will affect the CPU's access to the address.

To fix this issue, a new function kvm_to_cpreg_id_with_secure is added to 
restore secure bit information. Call different functions according to 
different modes to keep KVM unaffected.

Signed-off-by: Tao Ding <[email protected]>
---
Steps to reproduce:
1. prepare uboot
     git clone https://github.com/u-boot/u-boot
     cd u-boot && make xilinx_zynq_virt_defconfig && make -j4
2. compile qemu
     mkdir build
     cd build && ../configure --target-list="arm-softmmu"
3. run qemu and save vmstate
     ./build/qemu-system-arm -M xilinx-zynq-a9 -machine boot-mode=sd -m 1024 \
     -display none -serial null -serial mon:stdio \
     -device loader,file=~/u-boot/u-boot-dtb.bin,addr=0x04000000,cpu-num=0 

Model: Xilinx ZC706 board
......
Hit any key to stop autoboot: 0
Zynq> 
(ctrl + a + c)
QEMU 11.0.90 monitor - type 'help' for more information
(qemu) migrate -d file:vmstate
(qemu) q

4. restore qemu
     ./build/qemu-system-arm -M xilinx-zynq-a9 -machine boot-mode=sd -m 1024 \
     -display none -serial null -serial mon:stdio \
     -device loader,file=~/u-boot/u-boot-dtb.bin,addr=0x04000000,cpu-num=0 \
     -incoming file:vmstate

Before fixed, the terminal will hang in step 4.
After fixed, Can enter uboot interaction normally in step 4.

 target/arm/cpregs.h | 11 +++++++++++
 target/arm/helper.c | 14 ++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
index 391c0e322b..c0d1235625 100644
--- a/target/arm/cpregs.h
+++ b/target/arm/cpregs.h
@@ -258,6 +258,17 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
     return kvmid;
 }
 
+/*
+ * Convert kvmid to cpreg_id but keep secure mask.
+ */
+static inline uint32_t kvm_to_cpreg_id_with_secure(uint64_t kvmid)
+{
+    uint32_t cpregid = kvm_to_cpreg_id(kvmid);
+    cpregid &= ~CP_REG_AA32_NS_MASK;
+    cpregid |= (kvmid & CP_REG_AA32_NS_MASK);
+    return cpregid;
+}
+
 /*
  * Valid values for ARMCPRegInfo state field, indicating which of
  * the AArch32 and AArch64 execution states this register is visible in.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index af45234ad2..c8fccf9c0e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -160,7 +160,12 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
     bool ok = true;
 
     for (i = 0; i < cpu->cpreg_array_len; i++) {
-        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+        uint32_t regidx;
+        if (kvm_enabled()) {
+            regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+        } else {
+            regidx = kvm_to_cpreg_id_with_secure(cpu->cpreg_indexes[i]);
+        }
         const ARMCPRegInfo *ri;
         uint64_t newval;
 
@@ -205,7 +210,12 @@ bool write_list_to_cpustate(ARMCPU *cpu)
     bool ok = true;
 
     for (i = 0; i < cpu->cpreg_array_len; i++) {
-        uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+        uint32_t regidx;
+        if (kvm_enabled()) {
+            regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+        } else {
+            regidx = kvm_to_cpreg_id_with_secure(cpu->cpreg_indexes[i]);
+        }
         uint64_t v = cpu->cpreg_values[i];
         const ARMCPRegInfo *ri;
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.