From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Richard Henderson <richard.henderson@linaro.org>
Subject: [PULL 20/20] target/i386/tcg: save current task state before loading new one
Date: Wed, 17 Jul 2024 07:03:30 +0200 [thread overview]
Message-ID: <20240717050331.295371-21-pbonzini@redhat.com> (raw)
In-Reply-To: <20240717050331.295371-1-pbonzini@redhat.com>
This is how the steps are ordered in the manual. EFLAGS.NT is
overwritten after the fact in the saved image.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/seg_helper.c | 85 +++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 40 deletions(-)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 36d2f089cae..aac092a356b 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -389,6 +389,42 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector,
access_prepare_mmu(&new, env, tss_base, tss_limit,
MMU_DATA_LOAD, mmu_index, retaddr);
+ /* save the current state in the old TSS */
+ old_eflags = cpu_compute_eflags(env);
+ if (old_type & 8) {
+ /* 32 bit */
+ access_stl(&old, env->tr.base + 0x20, next_eip);
+ access_stl(&old, env->tr.base + 0x24, old_eflags);
+ access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
+ access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
+ access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
+ access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
+ access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
+ access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
+ access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);
+ access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]);
+ for (i = 0; i < 6; i++) {
+ access_stw(&old, env->tr.base + (0x48 + i * 4),
+ env->segs[i].selector);
+ }
+ } else {
+ /* 16 bit */
+ access_stw(&old, env->tr.base + 0x0e, next_eip);
+ access_stw(&old, env->tr.base + 0x10, old_eflags);
+ access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
+ access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
+ access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
+ access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
+ access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
+ access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
+ access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);
+ access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]);
+ for (i = 0; i < 4; i++) {
+ access_stw(&old, env->tr.base + (0x22 + i * 2),
+ env->segs[i].selector);
+ }
+ }
+
/* read all the registers from the new TSS */
if (type & 8) {
/* 32 bit */
@@ -428,49 +464,16 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector,
if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {
tss_set_busy(env, env->tr.selector, 0, retaddr);
}
- old_eflags = cpu_compute_eflags(env);
+
if (source == SWITCH_TSS_IRET) {
old_eflags &= ~NT_MASK;
+ if (old_type & 8) {
+ access_stl(&old, env->tr.base + 0x24, old_eflags);
+ } else {
+ access_stw(&old, env->tr.base + 0x10, old_eflags);
+ }
}
- /* save the current state in the old TSS */
- if (old_type & 8) {
- /* 32 bit */
- access_stl(&old, env->tr.base + 0x20, next_eip);
- access_stl(&old, env->tr.base + 0x24, old_eflags);
- access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);
- access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);
- access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);
- access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);
- access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);
- access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);
- access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);
- access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]);
- for (i = 0; i < 6; i++) {
- access_stw(&old, env->tr.base + (0x48 + i * 4),
- env->segs[i].selector);
- }
- } else {
- /* 16 bit */
- access_stw(&old, env->tr.base + 0x0e, next_eip);
- access_stw(&old, env->tr.base + 0x10, old_eflags);
- access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);
- access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);
- access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);
- access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);
- access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);
- access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);
- access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);
- access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]);
- for (i = 0; i < 4; i++) {
- access_stw(&old, env->tr.base + (0x22 + i * 2),
- env->segs[i].selector);
- }
- }
-
- /* now if an exception occurs, it will occurs in the next task
- context */
-
if (source == SWITCH_TSS_CALL) {
/*
* Thanks to the probe_access above, we know the first two
@@ -486,7 +489,9 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector,
}
/* set the new CPU state */
- /* from this point, any exception which occurs can give problems */
+
+ /* now if an exception occurs, it will occur in the next task context */
+
env->cr[0] |= CR0_TS_MASK;
env->hflags |= HF_TS_MASK;
env->tr.selector = tss_selector;
--
2.45.2
next prev parent reply other threads:[~2024-07-17 5:06 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-17 5:03 [PULL 00/20] i386, bugfix changes for QEMU 9.1 soft freeze Paolo Bonzini
2024-07-17 5:03 ` [PULL 01/20] i386/sev: Don't allow automatic fallback to legacy KVM_SEV*_INIT Paolo Bonzini
2024-07-17 5:03 ` [PULL 02/20] Revert "qemu-char: do not operate on sources from finalize callbacks" Paolo Bonzini
2024-07-17 5:03 ` [PULL 03/20] cpu: Free queued CPU work Paolo Bonzini
2024-07-17 5:03 ` [PULL 04/20] disas: Fix build against Capstone v6 Paolo Bonzini
2024-07-17 5:03 ` [PULL 05/20] hw/scsi/lsi53c895a: bump instruction limit in scripts processing to fix regression Paolo Bonzini
2024-07-17 5:03 ` [PULL 06/20] scsi: fix regression and honor bootindex again for legacy drives Paolo Bonzini
2024-07-17 5:03 ` [PULL 07/20] qemu/timer: Add host ticks function for LoongArch Paolo Bonzini
2024-07-17 5:03 ` [PULL 08/20] docs: Update description of 'user=username' for '-run-with' Paolo Bonzini
2024-07-17 5:03 ` [PULL 09/20] hpet: fix clamping of period Paolo Bonzini
2024-07-17 5:03 ` [PULL 10/20] hpet: fix HPET_TN_SETVAL for high 32-bits of the comparator Paolo Bonzini
2024-07-17 5:03 ` [PULL 11/20] target/i386/tcg: fix POP to memory in long mode Paolo Bonzini
2024-07-17 5:03 ` [PULL 12/20] target/i386/tcg: Remove SEG_ADDL Paolo Bonzini
2024-07-17 5:03 ` [PULL 13/20] target/i386/tcg: Allow IRET from user mode to user mode with SMAP Paolo Bonzini
2024-07-17 5:03 ` [PULL 14/20] target/i386/tcg: use PUSHL/PUSHW for error code Paolo Bonzini
2024-07-17 5:03 ` [PULL 15/20] target/i386/tcg: Reorg push/pop within seg_helper.c Paolo Bonzini
2024-07-17 5:03 ` [PULL 16/20] target/i386/tcg: Introduce x86_mmu_index_{kernel_,}pl Paolo Bonzini
2024-07-17 5:03 ` [PULL 17/20] target/i386/tcg: Compute MMU index once Paolo Bonzini
2024-07-17 5:03 ` [PULL 18/20] target/i386/tcg: check for correct busy state before switching to a new task Paolo Bonzini
2024-07-17 5:03 ` [PULL 19/20] target/i386/tcg: use X86Access for TSS access Paolo Bonzini
2024-07-17 5:03 ` Paolo Bonzini [this message]
2024-07-18 0:07 ` [PULL 00/20] i386, bugfix changes for QEMU 9.1 soft freeze Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240717050331.295371-21-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).