From: @zhendongchen Reviewed-by: @yorifang Signed-off-by: @yorifang
This commit is contained in:
commit
2cf6d11541
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 4.1.0
|
||||
Release: 38
|
||||
Release: 39
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY
|
||||
@ -286,6 +286,7 @@ Patch0273: hw-ehci-check-return-value-of-usb_packet_map.patch
|
||||
Patch0274: hw-usb-hcd-ohci-check-len-and-frame_number-variables.patch
|
||||
Patch0275: hw-net-e1000e-advance-desc_offset-in-case-of-null-de.patch
|
||||
Patch0276: hostmem-Fix-up-free-host_nodes-list-right-after-visi.patch
|
||||
Patch0277: target-arm-Fix-write-redundant-values-to-kvm.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: bison
|
||||
@ -663,6 +664,9 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Dec 9 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com>
|
||||
- target/arm: Fix write redundant values to kvm
|
||||
|
||||
* Fri Dec 11 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com>
|
||||
- hostmem: Fix up free host_nodes list right after visited
|
||||
|
||||
|
||||
118
target-arm-Fix-write-redundant-values-to-kvm.patch
Normal file
118
target-arm-Fix-write-redundant-values-to-kvm.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From 479c384f2944f52f9199bffa191b587a3f02663c Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Wed, 9 Dec 2020 19:35:08 +0800
|
||||
Subject: [PATCH] target/arm: Fix write redundant values to kvm
|
||||
|
||||
After modifying the value of a ID register, we'd better to try to write
|
||||
it to KVM so that we can known the value is acceptable for KVM.
|
||||
Because it may modify the registers' values of KVM, it's not suitable
|
||||
for other registers.
|
||||
|
||||
(cherry-picked from a0d7a9de807639fcfcbe1fe037cb8772d459a9cf)
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
---
|
||||
target/arm/helper.c | 73 ++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 49 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/target/arm/helper.c b/target/arm/helper.c
|
||||
index b262f5d6c5..bddd355fa0 100644
|
||||
--- a/target/arm/helper.c
|
||||
+++ b/target/arm/helper.c
|
||||
@@ -252,6 +252,16 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool is_id_reg(const ARMCPRegInfo *ri)
|
||||
+{
|
||||
+ /*
|
||||
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||
+ * where 1<=crm<8, 0<=op2<8.
|
||||
+ */
|
||||
+ return ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 &&
|
||||
+ ri->crm > 0 && ri->crm < 8;
|
||||
+}
|
||||
+
|
||||
bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||
{
|
||||
/* Write the coprocessor state from cpu->env to the (index,value) list. */
|
||||
@@ -268,38 +278,53 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
- /*
|
||||
- * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
|
||||
- * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to
|
||||
- * synchronize to kvm.
|
||||
- */
|
||||
- if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync &&
|
||||
- ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) {
|
||||
+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && is_id_reg(ri))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
newval = read_raw_cp_reg(&cpu->env, ri);
|
||||
if (kvm_sync) {
|
||||
- /* Only sync if we can sync to KVM successfully. */
|
||||
- uint64_t oldval;
|
||||
- uint64_t kvmval;
|
||||
+ if (is_id_reg(ri)) {
|
||||
+ /* Only sync if we can sync to KVM successfully. */
|
||||
+ uint64_t oldval;
|
||||
+ uint64_t kvmval;
|
||||
|
||||
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||
- continue;
|
||||
- }
|
||||
- if (oldval == newval) {
|
||||
- continue;
|
||||
- }
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (oldval == newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||
- continue;
|
||||
- }
|
||||
- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||
- kvmval != newval) {
|
||||
- continue;
|
||||
- }
|
||||
+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) ||
|
||||
+ kvmval != newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Only sync if the previous list->cpustate sync succeeded.
|
||||
+ * Rather than tracking the success/failure state for every
|
||||
+ * item in the list, we just recheck "does the raw write we must
|
||||
+ * have made in write_list_to_cpustate() read back OK" here.
|
||||
+ */
|
||||
+ uint64_t oldval = cpu->cpreg_values[i];
|
||||
+
|
||||
+ if (oldval == newval) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval);
|
||||
+ write_raw_cp_reg(&cpu->env, ri, oldval);
|
||||
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ write_raw_cp_reg(&cpu->env, ri, newval);
|
||||
+ }
|
||||
}
|
||||
cpu->cpreg_values[i] = newval;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user