[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 02/11] whpx: Fixed incorrect CR8/TPR synchronization
From: |
Paolo Bonzini |
Subject: |
[PULL 02/11] whpx: Fixed incorrect CR8/TPR synchronization |
Date: |
Wed, 2 Mar 2022 19:11:25 +0100 |
From: Ivan Shcherbakov <ivan@sysprogs.com>
This fixes the following error triggered when stopping and resuming a 64-bit
Linux kernel via gdb:
qemu-system-x86_64.exe: WHPX: Failed to set virtual processor context,
hr=c0350005
The previous logic for synchronizing the values did not take into account
that the lower 4 bits of the CR8 register, containing the priority level,
mapped to bits 7:4 of the APIC.TPR register (see section 10.8.6.1 of
Volume 3 of Intel 64 and IA-32 Architectures Software Developer's Manual).
The caused WHvSetVirtualProcessorRegisters() to fail with an error,
effectively preventing GDB from changing the guest context.
Signed-off-by: Ivan Shcherbakov <ivan@sysprogs.com>
Message-Id: <010b01d82874$bb4ef160$31ecd420$@sysprogs.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index edd4fafbdf..63203730bc 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -256,6 +256,21 @@ static int whpx_set_tsc(CPUState *cpu)
return 0;
}
+/*
+ * The CR8 register in the CPU is mapped to the TPR register of the APIC,
+ * however, they use a slightly different encoding. Specifically:
+ *
+ * APIC.TPR[bits 7:4] = CR8[bits 3:0]
+ *
+ * This mechanism is described in section 10.8.6.1 of Volume 3 of Intel 64
+ * and IA-32 Architectures Software Developer's Manual.
+ */
+
+static uint64_t whpx_apic_tpr_to_cr8(uint64_t tpr)
+{
+ return tpr >> 4;
+}
+
static void whpx_set_registers(CPUState *cpu, int level)
{
struct whpx_state *whpx = &whpx_global;
@@ -284,7 +299,7 @@ static void whpx_set_registers(CPUState *cpu, int level)
v86 = (env->eflags & VM_MASK);
r86 = !(env->cr[0] & CR0_PE_MASK);
- vcpu->tpr = cpu_get_apic_tpr(x86_cpu->apic_state);
+ vcpu->tpr = whpx_apic_tpr_to_cr8(cpu_get_apic_tpr(x86_cpu->apic_state));
vcpu->apic_base = cpu_get_apic_base(x86_cpu->apic_state);
idx = 0;
@@ -475,6 +490,17 @@ static void whpx_get_registers(CPUState *cpu)
hr);
}
+ if (whpx_apic_in_platform()) {
+ /*
+ * Fetch the TPR value from the emulated APIC. It may get overwritten
+ * below with the value from CR8 returned by
+ * WHvGetVirtualProcessorRegisters().
+ */
+ whpx_apic_get(x86_cpu->apic_state);
+ vcpu->tpr = whpx_apic_tpr_to_cr8(
+ cpu_get_apic_tpr(x86_cpu->apic_state));
+ }
+
idx = 0;
/* Indexes for first 16 registers match between HV and QEMU definitions */
--
2.34.1
- [PULL 00/11] QEMU changes for 2021-03-02, Paolo Bonzini, 2022/03/02
- [PULL 02/11] whpx: Fixed incorrect CR8/TPR synchronization,
Paolo Bonzini <=
- [PULL 03/11] vmxcap: Add 5-level EPT bit, Paolo Bonzini, 2022/03/02
- [PULL 04/11] meson: fix generic location of vss headers, Paolo Bonzini, 2022/03/02
- [PULL 01/11] whpx: Fixed reporting of the CPU context to GDB for 64-bit, Paolo Bonzini, 2022/03/02
- [PULL 06/11] qga/vss: update informative message about MinGW, Paolo Bonzini, 2022/03/02
- [PULL 05/11] qga/vss-win32: check old VSS SDK headers, Paolo Bonzini, 2022/03/02
- [PULL 07/11] update meson-buildoptions.sh, Paolo Bonzini, 2022/03/02
- [PULL 08/11] kvm-irqchip: introduce new API to support route change, Paolo Bonzini, 2022/03/02
- [PULL 09/11] kvm/msi: do explicit commit when adding msi routes, Paolo Bonzini, 2022/03/02
- [PULL 11/11] target/i386: Throw a #SS when loading a non-canonical IST, Paolo Bonzini, 2022/03/02
- [PULL 10/11] target/i386: only include bits in pg_mode if they are not ignored, Paolo Bonzini, 2022/03/02