* [PULL 01/42] target/i386: fix pushed value of EFLAGS.RF
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 02/42] target/i386: fix implementation of ICEBP Paolo Bonzini
` (41 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
When preparing an exception stack frame for a fault exception, the value
pushed for RF is 1. Take that into account. The same should be true
of interrupts for repeated string instructions, but the situation there
is complicated.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/seg_helper.c | 49 ++++++++++++++++++++++++++++++++----
target/i386/tcg/translate.c | 8 ++++++
2 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 0301459004e..715db1f2326 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -526,6 +526,24 @@ static inline unsigned int get_sp_mask(unsigned int e2)
}
}
+static int exception_is_fault(int intno)
+{
+ switch (intno) {
+ /*
+ * #DB can be both fault- and trap-like, but it never sets RF=1
+ * in the RFLAGS value pushed on the stack.
+ */
+ case EXCP01_DB:
+ case EXCP03_INT3:
+ case EXCP04_INTO:
+ case EXCP08_DBLE:
+ case EXCP12_MCHK:
+ return 0;
+ }
+ /* Everything else including reserved exception is a fault. */
+ return 1;
+}
+
int exception_has_error_code(int intno)
{
switch (intno) {
@@ -605,8 +623,9 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
int type, dpl, selector, ss_dpl, cpl;
int has_error_code, new_stack, shift;
uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0;
- uint32_t old_eip, sp_mask;
+ uint32_t old_eip, sp_mask, eflags;
int vm86 = env->eflags & VM_MASK;
+ bool set_rf;
has_error_code = 0;
if (!is_int && !is_hw) {
@@ -614,8 +633,10 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
}
if (is_int) {
old_eip = next_eip;
+ set_rf = false;
} else {
old_eip = env->eip;
+ set_rf = exception_is_fault(intno);
}
dt = &env->idt;
@@ -748,6 +769,15 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
}
push_size <<= shift;
#endif
+ eflags = cpu_compute_eflags(env);
+ /*
+ * AMD states that code breakpoint #DBs clear RF=0, Intel leaves it
+ * as is. AMD behavior could be implemented in check_hw_breakpoints().
+ */
+ if (set_rf) {
+ eflags |= RF_MASK;
+ }
+
if (shift == 1) {
if (new_stack) {
if (vm86) {
@@ -759,7 +789,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector);
PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]);
}
- PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env));
+ PUSHL(ssp, esp, sp_mask, eflags);
PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector);
PUSHL(ssp, esp, sp_mask, old_eip);
if (has_error_code) {
@@ -776,7 +806,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector);
PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]);
}
- PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env));
+ PUSHW(ssp, esp, sp_mask, eflags);
PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector);
PUSHW(ssp, esp, sp_mask, old_eip);
if (has_error_code) {
@@ -868,8 +898,9 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
target_ulong ptr;
int type, dpl, selector, cpl, ist;
int has_error_code, new_stack;
- uint32_t e1, e2, e3, ss;
+ uint32_t e1, e2, e3, ss, eflags;
target_ulong old_eip, esp, offset;
+ bool set_rf;
has_error_code = 0;
if (!is_int && !is_hw) {
@@ -877,8 +908,10 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
}
if (is_int) {
old_eip = next_eip;
+ set_rf = false;
} else {
old_eip = env->eip;
+ set_rf = exception_is_fault(intno);
}
dt = &env->idt;
@@ -950,9 +983,15 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
}
esp &= ~0xfLL; /* align stack */
+ /* See do_interrupt_protected. */
+ eflags = cpu_compute_eflags(env);
+ if (set_rf) {
+ eflags |= RF_MASK;
+ }
+
PUSHQ(esp, env->segs[R_SS].selector);
PUSHQ(esp, env->regs[R_ESP]);
- PUSHQ(esp, cpu_compute_eflags(env));
+ PUSHQ(esp, eflags);
PUSHQ(esp, env->segs[R_CS].selector);
PUSHQ(esp, old_eip);
if (has_error_code) {
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 0486ab69112..d438f8f76f7 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -4630,6 +4630,14 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
* If jmp_opt, we want to handle each string instruction individually.
* For icount also disable repz optimization so that each iteration
* is accounted separately.
+ *
+ * FIXME: this is messy; it makes REP string instructions a lot less
+ * efficient than they should be and it gets in the way of correct
+ * handling of RF (interrupts or traps arriving after any iteration
+ * of a repeated string instruction but the last should set RF to 1).
+ * Perhaps it would be more efficient if REP string instructions were
+ * always at the beginning of the TB, or even their own TB? That
+ * would even allow accounting up to 64k iterations at once for icount.
*/
dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 02/42] target/i386: fix implementation of ICEBP
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
2024-06-08 8:33 ` [PULL 01/42] target/i386: fix pushed value of EFLAGS.RF Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 03/42] target/i386: cleanup HLT helpers Paolo Bonzini
` (40 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson
ICEBP generates a trap-like exception, while gen_exception() produces
a fault. Resurrect gen_update_eip_next() to implement the desired
semantics.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/helper.h | 1 +
target/i386/tcg/helper-tcg.h | 12 +++++++++++-
target/i386/tcg/excp_helper.c | 20 ++++++++++++++++++++
target/i386/tcg/translate.c | 13 +++++++++++++
target/i386/tcg/emit.c.inc | 5 ++++-
5 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index a52a1bf0f21..8f291a5f66f 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -56,6 +56,7 @@ DEF_HELPER_2(sysret, void, env, int)
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_1(icebp, TCG_CALL_NO_WG, noreturn, env)
DEF_HELPER_3(boundw, void, env, tl, int)
DEF_HELPER_3(boundl, void, env, tl, int)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 85957943bf3..eb6a4926a43 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -111,7 +111,17 @@ int exception_has_error_code(int intno);
/* smm_helper.c */
void do_smm_enter(X86CPU *cpu);
-/* bpt_helper.c */
+/* sysemu/bpt_helper.c */
bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update);
+/*
+ * Do the tasks usually performed by gen_eob(). Callers of this function
+ * should also handle TF as appropriate.
+ */
+static inline void do_end_instruction(CPUX86State *env)
+{
+ /* needed if sti is just before */
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK;
+ env->eflags &= ~HF_RF_MASK;
+}
#endif /* I386_HELPER_TCG_H */
diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c
index 65e37ae2a0c..72387aac24f 100644
--- a/target/i386/tcg/excp_helper.c
+++ b/target/i386/tcg/excp_helper.c
@@ -140,6 +140,26 @@ G_NORETURN void raise_exception_ra(CPUX86State *env, int exception_index,
raise_interrupt2(env, exception_index, 0, 0, 0, retaddr);
}
+G_NORETURN void helper_icebp(CPUX86State *env)
+{
+ CPUState *cs = env_cpu(env);
+
+ do_end_instruction(env);
+
+ /*
+ * INT1 aka ICEBP generates a trap-like #DB, but it is pretty special.
+ *
+ * "Although the ICEBP instruction dispatches through IDT vector 1,
+ * that event is not interceptable by means of the #DB exception
+ * intercept". Instead there is a separate fault-like ICEBP intercept.
+ */
+ cs->exception_index = EXCP01_DB;
+ env->error_code = 0;
+ env->exception_is_int = 0;
+ env->exception_next_eip = env->eip;
+ cpu_loop_exit(cs);
+}
+
G_NORETURN void handle_unaligned_access(CPUX86State *env, vaddr vaddr,
MMUAccessType access_type,
uintptr_t retaddr)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index d438f8f76f7..77ed9c1db47 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -549,6 +549,19 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
}
}
+static void gen_update_eip_next(DisasContext *s)
+{
+ assert(s->pc_save != -1);
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
+ tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
+ } else if (CODE64(s)) {
+ tcg_gen_movi_tl(cpu_eip, s->pc);
+ } else {
+ tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base));
+ }
+ s->pc_save = s->pc;
+}
+
static void gen_update_eip_cur(DisasContext *s)
{
assert(s->pc_save != -1);
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index e990141454b..36127d99943 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -1858,7 +1858,10 @@ static void gen_INT(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
static void gen_INT1(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
{
- gen_exception(s, EXCP01_DB);
+ gen_update_cc_op(s);
+ gen_update_eip_next(s);
+ gen_helper_icebp(tcg_env);
+ s->base.is_jmp = DISAS_NORETURN;
}
static void gen_INT3(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 03/42] target/i386: cleanup HLT helpers
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
2024-06-08 8:33 ` [PULL 01/42] target/i386: fix pushed value of EFLAGS.RF Paolo Bonzini
2024-06-08 8:33 ` [PULL 02/42] target/i386: fix implementation of ICEBP Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 04/42] target/i386: cleanup PAUSE helpers Paolo Bonzini
` (39 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
Use decode.c's support for intercepts, doing the check in TCG-generated
code rather than the helper. This is cleaner because it allows removing
the eip_addend argument to helper_hlt().
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/helper.h | 2 +-
target/i386/tcg/sysemu/misc_helper.c | 13 ++-----------
target/i386/tcg/decode-new.c.inc | 4 ++--
target/i386/tcg/emit.c.inc | 4 ++--
4 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index 8f291a5f66f..c244dbb4812 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -90,7 +90,7 @@ DEF_HELPER_2(vmsave, void, env, int)
DEF_HELPER_1(stgi, void, env)
DEF_HELPER_1(clgi, void, env)
DEF_HELPER_FLAGS_2(flush_page, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_1(hlt, TCG_CALL_NO_WG, noreturn, env)
DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
DEF_HELPER_1(rdmsr, void, env)
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index edb7c3d8940..e41c88346cb 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -516,8 +516,7 @@ void helper_flush_page(CPUX86State *env, target_ulong addr)
tlb_flush_page(env_cpu(env), addr);
}
-static G_NORETURN
-void do_hlt(CPUX86State *env)
+G_NORETURN void helper_hlt(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
@@ -527,14 +526,6 @@ void do_hlt(CPUX86State *env)
cpu_loop_exit(cs);
}
-G_NORETURN void helper_hlt(CPUX86State *env, int next_eip_addend)
-{
- cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
- env->eip += next_eip_addend;
-
- do_hlt(env);
-}
-
void helper_monitor(CPUX86State *env, target_ulong ptr)
{
if ((uint32_t)env->regs[R_ECX] != 0) {
@@ -558,6 +549,6 @@ G_NORETURN void helper_mwait(CPUX86State *env, int next_eip_addend)
if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
do_pause(env);
} else {
- do_hlt(env);
+ helper_hlt(env);
}
}
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 0ff0866e8f3..376d2bdabe1 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1496,7 +1496,7 @@ static const X86OpEntry opcodes_root[256] = {
[0xE7] = X86_OP_ENTRYrr(OUT, 0,v, I_unsigned,b), /* AX/EAX */
[0xF1] = X86_OP_ENTRY0(INT1, svm(ICEBP)),
- [0xF4] = X86_OP_ENTRY0(HLT, chk(cpl0)),
+ [0xF4] = X86_OP_ENTRY0(HLT, chk(cpl0) svm(HLT)),
[0xF5] = X86_OP_ENTRY0(CMC),
[0xF6] = X86_OP_GROUP1(group3, E,b),
[0xF7] = X86_OP_GROUP1(group3, E,v),
@@ -2539,7 +2539,7 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
/*
* Checks that result in #GP or VMEXIT come second. Intercepts are
- * generally checked after non-memory exceptions (i.e. before all
+ * generally checked after non-memory exceptions (i.e. after all
* exceptions if there is no memory operand). Exceptions are
* vm86 checks (INTn, IRET, PUSHF/POPF), RSM and XSETBV (!).
*
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 36127d99943..2e94e8ec56f 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -1638,8 +1638,8 @@ static void gen_HLT(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
{
#ifdef CONFIG_SYSTEM_ONLY
gen_update_cc_op(s);
- gen_update_eip_cur(s);
- gen_helper_hlt(tcg_env, cur_insn_len_i32(s));
+ gen_update_eip_next(s);
+ gen_helper_hlt(tcg_env);
s->base.is_jmp = DISAS_NORETURN;
#endif
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 04/42] target/i386: cleanup PAUSE helpers
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (2 preceding siblings ...)
2024-06-08 8:33 ` [PULL 03/42] target/i386: cleanup HLT helpers Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 05/42] target/i386: implement DR7.GD Paolo Bonzini
` (38 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
Use decode.c's support for intercepts, doing the check in TCG-generated
code rather than the helper. This is cleaner because it allows removing
the eip_addend argument to helper_pause(), even though it adds a bit of
bloat for opcode 0x90's new decoding function.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/helper.h | 2 +-
target/i386/tcg/helper-tcg.h | 1 -
target/i386/tcg/misc_helper.c | 10 +---------
target/i386/tcg/sysemu/misc_helper.c | 2 +-
target/i386/tcg/decode-new.c.inc | 15 ++++++++++++++-
target/i386/tcg/emit.c.inc | 20 ++++++++------------
6 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index c244dbb4812..2f46cffabd8 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -53,7 +53,7 @@ DEF_HELPER_1(sysenter, void, env)
DEF_HELPER_2(sysexit, void, env, int)
DEF_HELPER_2(syscall, void, env, int)
DEF_HELPER_2(sysret, void, env, int)
-DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_1(pause, TCG_CALL_NO_WG, noreturn, env)
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
DEF_HELPER_FLAGS_1(icebp, TCG_CALL_NO_WG, noreturn, env)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index eb6a4926a43..15d6c6f8b4f 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -91,7 +91,6 @@ extern const uint8_t parity_table[256];
/* misc_helper.c */
void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask);
-G_NORETURN void do_pause(CPUX86State *env);
/* sysemu/svm_helper.c */
#ifndef CONFIG_USER_ONLY
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index b0f0f7b893b..8316d42ffcd 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -88,7 +88,7 @@ G_NORETURN void helper_rdpmc(CPUX86State *env)
raise_exception_err(env, EXCP06_ILLOP, 0);
}
-G_NORETURN void do_pause(CPUX86State *env)
+G_NORETURN void helper_pause(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
@@ -97,14 +97,6 @@ G_NORETURN void do_pause(CPUX86State *env)
cpu_loop_exit(cs);
}
-G_NORETURN void helper_pause(CPUX86State *env, int next_eip_addend)
-{
- cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC());
- env->eip += next_eip_addend;
-
- do_pause(env);
-}
-
uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx)
{
if ((env->cr[4] & CR4_PKE_MASK) == 0) {
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index e41c88346cb..093cc2d0f90 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -547,7 +547,7 @@ G_NORETURN void helper_mwait(CPUX86State *env, int next_eip_addend)
/* XXX: not complete but not completely erroneous */
if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
- do_pause(env);
+ helper_pause(env);
} else {
helper_hlt(env);
}
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 376d2bdabe1..c2d8da8d14e 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1359,6 +1359,19 @@ static void decode_group11(DisasContext *s, CPUX86State *env, X86OpEntry *entry,
}
}
+static void decode_90(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
+{
+ static X86OpEntry pause = X86_OP_ENTRY0(PAUSE, svm(PAUSE));
+ static X86OpEntry nop = X86_OP_ENTRY0(NOP);
+ static X86OpEntry xchg_ax = X86_OP_ENTRY2(XCHG, 0,v, LoBits,v);
+
+ if (REX_B(s)) {
+ *entry = xchg_ax;
+ } else {
+ *entry = (s->prefix & PREFIX_REPZ) ? pause : nop;
+ }
+}
+
static const X86OpEntry opcodes_root[256] = {
[0x00] = X86_OP_ENTRY2(ADD, E,b, G,b, lock),
[0x01] = X86_OP_ENTRY2(ADD, E,v, G,v, lock),
@@ -1441,7 +1454,7 @@ static const X86OpEntry opcodes_root[256] = {
[0x86] = X86_OP_ENTRY2(XCHG, E,b, G,b, xchg),
[0x87] = X86_OP_ENTRY2(XCHG, E,v, G,v, xchg),
- [0x90] = X86_OP_ENTRY2(XCHG, 0,v, LoBits,v),
+ [0x90] = X86_OP_GROUP0(90),
[0x91] = X86_OP_ENTRY2(XCHG, 0,v, LoBits,v),
[0x92] = X86_OP_ENTRY2(XCHG, 0,v, LoBits,v),
[0x93] = X86_OP_ENTRY2(XCHG, 0,v, LoBits,v),
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 2e94e8ec56f..f90f3d3c589 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -2350,6 +2350,14 @@ static void gen_PANDN(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
decode->op[1].offset, vec_len, vec_len);
}
+static void gen_PAUSE(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
+{
+ gen_update_cc_op(s);
+ gen_update_eip_next(s);
+ gen_helper_pause(tcg_env);
+ s->base.is_jmp = DISAS_NORETURN;
+}
+
static void gen_PCMPESTRI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
{
TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
@@ -4014,18 +4022,6 @@ static void gen_WAIT(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
static void gen_XCHG(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
{
- if (decode->b == 0x90 && !REX_B(s)) {
- if (s->prefix & PREFIX_REPZ) {
- gen_update_cc_op(s);
- gen_update_eip_cur(s);
- gen_helper_pause(tcg_env, cur_insn_len_i32(s));
- s->base.is_jmp = DISAS_NORETURN;
- }
- /* No writeback. */
- decode->op[0].unit = X86_OP_SKIP;
- return;
- }
-
if (s->prefix & PREFIX_LOCK) {
tcg_gen_atomic_xchg_tl(s->T0, s->A0, s->T1,
s->mem_index, decode->op[0].ot | MO_LE);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 05/42] target/i386: implement DR7.GD
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (3 preceding siblings ...)
2024-06-08 8:33 ` [PULL 04/42] target/i386: cleanup PAUSE helpers Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 06/42] target/i386: disable/enable breakpoints on vmentry/vmexit Paolo Bonzini
` (37 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
DR7.GD triggers a #DB exception on any access to debug registers.
The GD bit is cleared so that the #DB handler itself can access
the debug registers.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/sysemu/bpt_helper.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/target/i386/tcg/sysemu/bpt_helper.c b/target/i386/tcg/sysemu/bpt_helper.c
index 4d96a48a3ca..c1d5fce250c 100644
--- a/target/i386/tcg/sysemu/bpt_helper.c
+++ b/target/i386/tcg/sysemu/bpt_helper.c
@@ -238,6 +238,12 @@ target_ulong helper_get_dr(CPUX86State *env, int reg)
}
}
+ if (env->dr[7] & DR7_GD) {
+ env->dr[7] &= ~DR7_GD;
+ env->dr[6] |= DR6_BD;
+ raise_exception_ra(env, EXCP01_DB, GETPC());
+ }
+
return env->dr[reg];
}
@@ -251,6 +257,12 @@ void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
}
}
+ if (env->dr[7] & DR7_GD) {
+ env->dr[7] &= ~DR7_GD;
+ env->dr[6] |= DR6_BD;
+ raise_exception_ra(env, EXCP01_DB, GETPC());
+ }
+
if (reg < 4) {
if (hw_breakpoint_enabled(env->dr[7], reg)
&& hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 06/42] target/i386: disable/enable breakpoints on vmentry/vmexit
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (4 preceding siblings ...)
2024-06-08 8:33 ` [PULL 05/42] target/i386: implement DR7.GD Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 07/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for VMRUN Paolo Bonzini
` (36 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
If the required DR7 (either from the VMCB or from the host save
area) disables a breakpoint that was enabled prior to vmentry
or vmexit, it is left enabled and will trigger EXCP_DEBUG.
This causes a spurious #DB on the next crossing of the breakpoint.
To disable it, vmentry/vmexit must use cpu_x86_update_dr7
to load DR7.
Because cpu_x86_update_dr7 takes a 32-bit argument, check
reserved bits prior to calling cpu_x86_update_dr7, and do the
same for DR6 as well for consistency.
This scenario is tested by the "host_rflags" test in kvm-unit-tests.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/sysemu/svm_helper.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 5d6de2294fa..922d8964f8e 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -163,6 +163,8 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
uint64_t new_cr0;
uint64_t new_cr3;
uint64_t new_cr4;
+ uint64_t new_dr6;
+ uint64_t new_dr7;
if (aflag == 2) {
addr = env->regs[R_EAX];
@@ -361,20 +363,22 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
env->vm_vmcb + offsetof(struct vmcb, save.rsp));
env->regs[R_EAX] = x86_ldq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.rax));
- env->dr[7] = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.dr7));
- env->dr[6] = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.dr6));
+
+ new_dr7 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr7));
+ new_dr6 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr6));
#ifdef TARGET_X86_64
- if (env->dr[6] & DR_RESERVED_MASK) {
+ if (new_dr7 & DR_RESERVED_MASK) {
cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
}
- if (env->dr[7] & DR_RESERVED_MASK) {
+ if (new_dr6 & DR_RESERVED_MASK) {
cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
}
#endif
+ cpu_x86_update_dr7(env, new_dr7);
+ env->dr[6] = new_dr6;
+
if (is_efer_invalid_state(env)) {
cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
}
@@ -864,8 +868,11 @@ void do_vmexit(CPUX86State *env)
env->dr[6] = x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb, save.dr6));
- env->dr[7] = x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.dr7));
+
+ /* Disables all breakpoints in the host DR7 register. */
+ cpu_x86_update_dr7(env,
+ x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.dr7)) & ~0xff);
/* other setups */
x86_stl_phys(cs,
@@ -891,8 +898,6 @@ void do_vmexit(CPUX86State *env)
from the page table indicated the host's CR3. If the PDPEs contain
illegal state, the processor causes a shutdown. */
- /* Disables all breakpoints in the host DR7 register. */
-
/* Checks the reloaded host state for consistency. */
/* If the host's rIP reloaded by #VMEXIT is outside the limit of the
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 07/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for VMRUN
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (5 preceding siblings ...)
2024-06-08 8:33 ` [PULL 06/42] target/i386: disable/enable breakpoints on vmentry/vmexit Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 08/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for PAUSE Paolo Bonzini
` (35 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
From vm entry to exit, VMRUN is handled as a single instruction. It
uses DISAS_NORETURN in order to avoid processing TF or RF before
the first instruction executes in the guest. However, the corresponding
handling is missing in vmexit. Add it, and at the same time reorganize
the comments with quotes from the manual about the tasks performed
by a #VMEXIT.
Another gen_eob() task that is missing in VMRUN is preparing the
HF_INHIBIT_IRQ flag for the next instruction, in this case by loading
it from the VMCB control state.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/sysemu/svm_helper.c | 46 +++++++++++++++++++++--------
target/i386/tcg/translate.c | 5 ++++
2 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 922d8964f8e..9db8ad62a01 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -254,6 +254,13 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
control.intercept_exceptions
));
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK;
+ if (x86_ldl_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.int_state)) &
+ SVM_INTERRUPT_SHADOW_MASK) {
+ env->hflags |= HF_INHIBIT_IRQ_MASK;
+ }
+
nested_ctl = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
control.nested_ctl));
asid = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
@@ -815,8 +822,12 @@ void do_vmexit(CPUX86State *env)
env->hflags &= ~HF_GUEST_MASK;
env->intercept = 0;
env->intercept_exceptions = 0;
+
+ /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
env->int_ctl = 0;
+
+ /* Clears the TSC_OFFSET inside the processor. */
env->tsc_offset = 0;
env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
@@ -836,6 +847,15 @@ void do_vmexit(CPUX86State *env)
cpu_x86_update_cr4(env, x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb,
save.cr4)));
+
+ /*
+ * Resets the current ASID register to zero (host ASID; TLB flush).
+ *
+ * If the host is in PAE mode, the processor reloads the host's PDPEs
+ * from the page table indicated the host's CR3. FIXME: If the PDPEs
+ * contain illegal state, the processor causes a shutdown (QEMU does
+ * not implement PDPTRs).
+ */
cpu_x86_update_cr3(env, x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb,
save.cr3)));
@@ -843,12 +863,14 @@ void do_vmexit(CPUX86State *env)
set properly */
cpu_load_efer(env, x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
save.efer)));
+
+ /* Completion of the VMRUN instruction clears the host EFLAGS.RF bit. */
env->eflags = 0;
cpu_load_eflags(env, x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb,
save.rflags)),
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK |
- VM_MASK));
+ RF_MASK | VM_MASK));
svm_load_seg_cache(env, MMU_PHYS_IDX,
env->vm_hsave + offsetof(struct vmcb, save.es), R_ES);
@@ -888,19 +910,17 @@ void do_vmexit(CPUX86State *env)
env->hflags2 &= ~HF2_GIF_MASK;
env->hflags2 &= ~HF2_VGIF_MASK;
- /* FIXME: Resets the current ASID register to zero (host ASID). */
- /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
- /* Clears the TSC_OFFSET inside the processor. */
+ /* FIXME: Checks the reloaded host state for consistency. */
- /* If the host is in PAE mode, the processor reloads the host's PDPEs
- from the page table indicated the host's CR3. If the PDPEs contain
- illegal state, the processor causes a shutdown. */
-
- /* Checks the reloaded host state for consistency. */
-
- /* If the host's rIP reloaded by #VMEXIT is outside the limit of the
- host's code segment or non-canonical (in the case of long mode), a
- #GP fault is delivered inside the host. */
+ /*
+ * EFLAGS.TF causes a #DB trap after the VMRUN completes on the host
+ * side (i.e., after the #VMEXIT from the guest). Since we're running
+ * in the main loop, call do_interrupt_all directly.
+ */
+ if ((env->eflags & TF_MASK) != 0) {
+ env->dr[6] |= DR6_BS;
+ do_interrupt_all(X86_CPU(cs), EXCP01_DB, 0, 0, env->eip, 0);
+ }
}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 77ed9c1db47..a9c6424c7df 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -3745,6 +3745,11 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
}
gen_update_cc_op(s);
gen_update_eip_cur(s);
+ /*
+ * Reloads INHIBIT_IRQ mask as well as TF and RF with guest state.
+ * The usual gen_eob() handling is performed on vmexit after
+ * host state is reloaded.
+ */
gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1),
cur_insn_len_i32(s));
tcg_gen_exit_tb(NULL, 0);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 08/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for PAUSE
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (6 preceding siblings ...)
2024-06-08 8:33 ` [PULL 07/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for VMRUN Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 09/42] target/i386: fix TF/RF handling for HLT Paolo Bonzini
` (34 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
PAUSE uses DISAS_NORETURN because the corresponding helper
calls cpu_loop_exit(). However, while HLT clear HF_INHIBIT_IRQ_MASK
to correctly handle "STI; HLT", the same is missing from PAUSE.
And also gen_eob() clears HF_RF_MASK and synthesizes a #DB exception
if single-step is active; none of this is done by HLT and PAUSE.
Start fixing PAUSE, HLT will follow.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/misc_helper.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index 8316d42ffcd..ed4cda8001e 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -92,6 +92,10 @@ G_NORETURN void helper_pause(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
+ /* Do gen_eob() tasks before going back to the main loop. */
+ do_end_instruction(env);
+ helper_rechecking_single_step(env);
+
/* Just let another CPU run. */
cs->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(cs);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 09/42] target/i386: fix TF/RF handling for HLT
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (7 preceding siblings ...)
2024-06-08 8:33 ` [PULL 08/42] target/i386: fix INHIBIT_IRQ/TF/RF handling for PAUSE Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 10/42] target/i386: document incorrect semantics of watchpoint following MOV/POP SS Paolo Bonzini
` (33 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
HLT uses DISAS_NORETURN because the corresponding helper calls
cpu_loop_exit(). However, while gen_eob() clears HF_RF_MASK and
synthesizes a #DB exception if single-step is active, none of this is
done by HLT. Note that the single-step trap is generated after the halt
is finished.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/sysemu/misc_helper.c | 2 +-
target/i386/tcg/sysemu/seg_helper.c | 17 ++++++++++++++---
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index 093cc2d0f90..7fa0c5a06de 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -520,7 +520,7 @@ G_NORETURN void helper_hlt(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
- env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
+ do_end_instruction(env);
cs->halted = 1;
cs->exception_index = EXCP_HLT;
cpu_loop_exit(cs);
diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c
index 9ba94deb3aa..05174a79e73 100644
--- a/target/i386/tcg/sysemu/seg_helper.c
+++ b/target/i386/tcg/sysemu/seg_helper.c
@@ -130,15 +130,26 @@ void x86_cpu_do_interrupt(CPUState *cs)
bool x86_cpu_exec_halt(CPUState *cpu)
{
- if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
- X86CPU *x86_cpu = X86_CPU(cpu);
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+ if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
bql_lock();
apic_poll_irq(x86_cpu->apic_state);
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
bql_unlock();
}
- return cpu_has_work(cpu);
+
+ if (!cpu_has_work(cpu)) {
+ return false;
+ }
+
+ /* Complete HLT instruction. */
+ if (env->eflags & TF_MASK) {
+ env->dr[6] |= DR6_BS;
+ do_interrupt_all(x86_cpu, EXCP01_DB, 0, 0, env->eip, 0);
+ }
+ return true;
}
bool x86_need_replay_interrupt(int interrupt_request)
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 10/42] target/i386: document incorrect semantics of watchpoint following MOV/POP SS
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (8 preceding siblings ...)
2024-06-08 8:33 ` [PULL 09/42] target/i386: fix TF/RF handling for HLT Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 11/42] target/i386: document use of DISAS_NORETURN Paolo Bonzini
` (32 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/sysemu/bpt_helper.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/target/i386/tcg/sysemu/bpt_helper.c b/target/i386/tcg/sysemu/bpt_helper.c
index c1d5fce250c..b29acf41c38 100644
--- a/target/i386/tcg/sysemu/bpt_helper.c
+++ b/target/i386/tcg/sysemu/bpt_helper.c
@@ -215,6 +215,12 @@ void breakpoint_handler(CPUState *cs)
if (cs->watchpoint_hit->flags & BP_CPU) {
cs->watchpoint_hit = NULL;
if (check_hw_breakpoints(env, false)) {
+ /*
+ * FIXME: #DB should be delayed by one instruction if
+ * INHIBIT_IRQ is set (STI cannot trigger a watchpoint).
+ * The delayed #DB should also fuse with one generated
+ * by ICEBP (aka INT1).
+ */
raise_exception(env, EXCP01_DB);
} else {
cpu_loop_exit_noexc(cs);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 11/42] target/i386: document use of DISAS_NORETURN
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (9 preceding siblings ...)
2024-06-08 8:33 ` [PULL 10/42] target/i386: document incorrect semantics of watchpoint following MOV/POP SS Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 12/42] target/i386: use local X86DecodedOp in gen_POP() Paolo Bonzini
` (31 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
DISAS_NORETURN suppresses the work normally done by gen_eob(), and therefore
must be used in special cases only. Document them.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/translate.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index a9c6424c7df..2b6f67be40b 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -4761,6 +4761,17 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
switch (dc->base.is_jmp) {
case DISAS_NORETURN:
+ /*
+ * Most instructions should not use DISAS_NORETURN, as that suppresses
+ * the handling of hflags normally done by gen_eob(). We can
+ * get here:
+ * - for exception and interrupts
+ * - for jump optimization (which is disabled by INHIBIT_IRQ/RF/TF)
+ * - for VMRUN because RF/TF handling for the host is done after vmexit,
+ * and INHIBIT_IRQ is loaded from the VMCB
+ * - for HLT/PAUSE/MWAIT to exit the main loop with specific EXCP_* values;
+ * the helpers handle themselves the tasks normally done by gen_eob().
+ */
break;
case DISAS_TOO_MANY:
gen_update_cc_op(dc);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 12/42] target/i386: use local X86DecodedOp in gen_POP()
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (10 preceding siblings ...)
2024-06-08 8:33 ` [PULL 11/42] target/i386: document use of DISAS_NORETURN Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 13/42] target/i386: use gen_writeback() within gen_POP() Paolo Bonzini
` (30 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark Cave-Ayland
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This will make subsequent changes a little easier to read.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-ID: <20240606095319.229650-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/emit.c.inc | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index f90f3d3c589..ca78504b6e4 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -2575,11 +2575,13 @@ static void gen_PMOVMSKB(DisasContext *s, CPUX86State *env, X86DecodedInsn *deco
static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
{
+ X86DecodedOp *op = &decode->op[0];
MemOp ot = gen_pop_T0(s);
- if (decode->op[0].has_ea) {
+
+ if (op->has_ea) {
/* NOTE: order is important for MMU exceptions */
gen_op_st_v(s, ot, s->T0, s->A0);
- decode->op[0].unit = X86_OP_SKIP;
+ op->unit = X86_OP_SKIP;
}
/* NOTE: writing back registers after update is important for pop %sp */
gen_pop_update(s, ot);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 13/42] target/i386: use gen_writeback() within gen_POP()
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (11 preceding siblings ...)
2024-06-08 8:33 ` [PULL 12/42] target/i386: use local X86DecodedOp in gen_POP() Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-07-10 9:42 ` Clément Chigot
2024-06-08 8:33 ` [PULL 14/42] target/i386: fix SP when taking a memory fault during POP Paolo Bonzini
` (29 subsequent siblings)
42 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark Cave-Ayland
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Instead of directly implementing the writeback using gen_op_st_v(), use the
existing gen_writeback() function.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-ID: <20240606095319.229650-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/emit.c.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index ca78504b6e4..6123235c000 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -2580,9 +2580,9 @@ static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
if (op->has_ea) {
/* NOTE: order is important for MMU exceptions */
- gen_op_st_v(s, ot, s->T0, s->A0);
- op->unit = X86_OP_SKIP;
+ gen_writeback(s, decode, 0, s->T0);
}
+
/* NOTE: writing back registers after update is important for pop %sp */
gen_pop_update(s, ot);
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PULL 13/42] target/i386: use gen_writeback() within gen_POP()
2024-06-08 8:33 ` [PULL 13/42] target/i386: use gen_writeback() within gen_POP() Paolo Bonzini
@ 2024-07-10 9:42 ` Clément Chigot
2024-07-10 10:43 ` Paolo Bonzini
0 siblings, 1 reply; 50+ messages in thread
From: Clément Chigot @ 2024-07-10 9:42 UTC (permalink / raw)
To: Mark Cave-Ayland; +Cc: qemu-devel, Paolo Bonzini
Hi Mark,
This patch introduces regressions in our x86_64 VxWorks kernels
running over qemu. Some page faults are triggered randomly.
Earlier to this patch, the MemOp `ot` passed to `gen_op_st_v` was the
`gen_pop_T0` created a few lines above.
Now, this is `op->ot` which comes from elsewhere.
Adding `op->ot = ot` just before calling `gen_writeback` fixes my
regressions. But I'm wondering if there could be some unexpected
fallbacks, `op->ot` possibly being used afterwards.
Thanks,
Clément
On Sat, Jun 8, 2024 at 10:36 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>
> Instead of directly implementing the writeback using gen_op_st_v(), use the
> existing gen_writeback() function.
>
> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Message-ID: <20240606095319.229650-3-mark.cave-ayland@ilande.co.uk>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/emit.c.inc | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
> index ca78504b6e4..6123235c000 100644
> --- a/target/i386/tcg/emit.c.inc
> +++ b/target/i386/tcg/emit.c.inc
> @@ -2580,9 +2580,9 @@ static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
>
> if (op->has_ea) {
> /* NOTE: order is important for MMU exceptions */
> - gen_op_st_v(s, ot, s->T0, s->A0);
> - op->unit = X86_OP_SKIP;
> + gen_writeback(s, decode, 0, s->T0);
> }
> +
> /* NOTE: writing back registers after update is important for pop %sp */
> gen_pop_update(s, ot);
> }
> --
> 2.45.1
>
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PULL 13/42] target/i386: use gen_writeback() within gen_POP()
2024-07-10 9:42 ` Clément Chigot
@ 2024-07-10 10:43 ` Paolo Bonzini
2024-07-10 12:53 ` Clément Chigot
0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2024-07-10 10:43 UTC (permalink / raw)
To: Clément Chigot, Mark Cave-Ayland; +Cc: qemu-devel
On 7/10/24 11:42, Clément Chigot wrote:
> Hi Mark,
>
> This patch introduces regressions in our x86_64 VxWorks kernels
> running over qemu. Some page faults are triggered randomly.
>
> Earlier to this patch, the MemOp `ot` passed to `gen_op_st_v` was the
> `gen_pop_T0` created a few lines above.
> Now, this is `op->ot` which comes from elsewhere.
>
> Adding `op->ot = ot` just before calling `gen_writeback` fixes my
> regressions. But I'm wondering if there could be some unexpected
> fallbacks, `op->ot` possibly being used afterwards.
Mark's patch is correct and the (previously latent) mistake is in
the decoding table.
The manual correctly says that POP has "default 64-bit" operand;
that is, it is 64-bit even without a REX.W prefix. It must be
marked as "d64" rather than "v".
Can you test this patch?
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 0d846c32c22..d2da1d396d5 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1717,7 +1717,7 @@ static const X86OpEntry opcodes_root[256] = {
[0x8C] = X86_OP_ENTRYwr(MOV, E,v, S,w, op0_Mw),
[0x8D] = X86_OP_ENTRYwr(LEA, G,v, M,v, nolea),
[0x8E] = X86_OP_ENTRYwr(MOV, S,w, E,w),
- [0x8F] = X86_OP_GROUPw(group1A, E,v),
+ [0x8F] = X86_OP_GROUPw(group1A, E,d64),
[0x98] = X86_OP_ENTRY1(CBW, 0,v), /* rAX */
[0x99] = X86_OP_ENTRYwr(CWD, 2,v, 0,v), /* rDX, rAX */
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index fc7477833bc..36bb308e449 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -2788,6 +2788,8 @@ static void gen_POP(DisasContext *s, X86DecodedInsn *decode)
X86DecodedOp *op = &decode->op[0];
MemOp ot = gen_pop_T0(s);
+ /* Only 16/32-bit access in 32-bit mode, 16/64-bit access in long mode. */
+ assert(ot == op->ot);
if (op->has_ea || op->unit == X86_OP_SEG) {
/* NOTE: order is important for MMU exceptions */
gen_writeback(s, decode, 0, s->T0);
Thanks (and it's reassuring that everything else has worked fine
for you!),
Paolo
> Thanks,
> Clément
>
> On Sat, Jun 8, 2024 at 10:36 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>
>> Instead of directly implementing the writeback using gen_op_st_v(), use the
>> existing gen_writeback() function.
>>
>> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> Message-ID: <20240606095319.229650-3-mark.cave-ayland@ilande.co.uk>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> target/i386/tcg/emit.c.inc | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
>> index ca78504b6e4..6123235c000 100644
>> --- a/target/i386/tcg/emit.c.inc
>> +++ b/target/i386/tcg/emit.c.inc
>> @@ -2580,9 +2580,9 @@ static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
>>
>> if (op->has_ea) {
>> /* NOTE: order is important for MMU exceptions */
>> - gen_op_st_v(s, ot, s->T0, s->A0);
>> - op->unit = X86_OP_SKIP;
>> + gen_writeback(s, decode, 0, s->T0);
>> }
>> +
>> /* NOTE: writing back registers after update is important for pop %sp */
>> gen_pop_update(s, ot);
>> }
>> --
>> 2.45.1
>>
>>
>
>
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PULL 13/42] target/i386: use gen_writeback() within gen_POP()
2024-07-10 10:43 ` Paolo Bonzini
@ 2024-07-10 12:53 ` Clément Chigot
0 siblings, 0 replies; 50+ messages in thread
From: Clément Chigot @ 2024-07-10 12:53 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Mark Cave-Ayland, qemu-devel
On Wed, Jul 10, 2024 at 12:43 PM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 7/10/24 11:42, Clément Chigot wrote:
> > Hi Mark,
> >
> > This patch introduces regressions in our x86_64 VxWorks kernels
> > running over qemu. Some page faults are triggered randomly.
> >
> > Earlier to this patch, the MemOp `ot` passed to `gen_op_st_v` was the
> > `gen_pop_T0` created a few lines above.
> > Now, this is `op->ot` which comes from elsewhere.
> >
> > Adding `op->ot = ot` just before calling `gen_writeback` fixes my
> > regressions. But I'm wondering if there could be some unexpected
> > fallbacks, `op->ot` possibly being used afterwards.
>
> Mark's patch is correct and the (previously latent) mistake is in
> the decoding table.
>
> The manual correctly says that POP has "default 64-bit" operand;
> that is, it is 64-bit even without a REX.W prefix. It must be
> marked as "d64" rather than "v".
>
> Can you test this patch?
Yes, it does work. Thanks a lot for it !
> diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
> index 0d846c32c22..d2da1d396d5 100644
> --- a/target/i386/tcg/decode-new.c.inc
> +++ b/target/i386/tcg/decode-new.c.inc
> @@ -1717,7 +1717,7 @@ static const X86OpEntry opcodes_root[256] = {
> [0x8C] = X86_OP_ENTRYwr(MOV, E,v, S,w, op0_Mw),
> [0x8D] = X86_OP_ENTRYwr(LEA, G,v, M,v, nolea),
> [0x8E] = X86_OP_ENTRYwr(MOV, S,w, E,w),
> - [0x8F] = X86_OP_GROUPw(group1A, E,v),
> + [0x8F] = X86_OP_GROUPw(group1A, E,d64),
>
> [0x98] = X86_OP_ENTRY1(CBW, 0,v), /* rAX */
> [0x99] = X86_OP_ENTRYwr(CWD, 2,v, 0,v), /* rDX, rAX */
> diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
> index fc7477833bc..36bb308e449 100644
> --- a/target/i386/tcg/emit.c.inc
> +++ b/target/i386/tcg/emit.c.inc
> @@ -2788,6 +2788,8 @@ static void gen_POP(DisasContext *s, X86DecodedInsn *decode)
> X86DecodedOp *op = &decode->op[0];
> MemOp ot = gen_pop_T0(s);
>
> + /* Only 16/32-bit access in 32-bit mode, 16/64-bit access in long mode. */
> + assert(ot == op->ot);
> if (op->has_ea || op->unit == X86_OP_SEG) {
> /* NOTE: order is important for MMU exceptions */
> gen_writeback(s, decode, 0, s->T0);
>
> Thanks (and it's reassuring that everything else has worked fine
> for you!),
>
> Paolo
>
> > Thanks,
> > Clément
> >
> > On Sat, Jun 8, 2024 at 10:36 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
> >>
> >> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >>
> >> Instead of directly implementing the writeback using gen_op_st_v(), use the
> >> existing gen_writeback() function.
> >>
> >> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >> Message-ID: <20240606095319.229650-3-mark.cave-ayland@ilande.co.uk>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> ---
> >> target/i386/tcg/emit.c.inc | 4 ++--
> >> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
> >> index ca78504b6e4..6123235c000 100644
> >> --- a/target/i386/tcg/emit.c.inc
> >> +++ b/target/i386/tcg/emit.c.inc
> >> @@ -2580,9 +2580,9 @@ static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
> >>
> >> if (op->has_ea) {
> >> /* NOTE: order is important for MMU exceptions */
> >> - gen_op_st_v(s, ot, s->T0, s->A0);
> >> - op->unit = X86_OP_SKIP;
> >> + gen_writeback(s, decode, 0, s->T0);
> >> }
> >> +
> >> /* NOTE: writing back registers after update is important for pop %sp */
> >> gen_pop_update(s, ot);
> >> }
> >> --
> >> 2.45.1
> >>
> >>
> >
> >
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PULL 14/42] target/i386: fix SP when taking a memory fault during POP
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (12 preceding siblings ...)
2024-06-08 8:33 ` [PULL 13/42] target/i386: use gen_writeback() within gen_POP() Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 15/42] target/i386: fix size of EBP writeback in gen_enter() Paolo Bonzini
` (28 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark Cave-Ayland
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
When OS/2 Warp configures its segment descriptors, many of them are configured with
the P flag clear to allow for a fault-on-demand implementation. In the case where
the stack value is POPped into the segment registers, the SP is incremented before
calling gen_helper_load_seg() to validate the segment descriptor:
IN:
0xffef2c0c: 66 07 popl %es
OP:
ld_i32 loc9,env,$0xfffffffffffffff8
sub_i32 loc9,loc9,$0x1
brcond_i32 loc9,$0x0,lt,$L0
st16_i32 loc9,env,$0xfffffffffffffff8
st8_i32 $0x1,env,$0xfffffffffffffffc
---- 0000000000000c0c 0000000000000000
ext16u_i64 loc0,rsp
add_i64 loc0,loc0,ss_base
ext32u_i64 loc0,loc0
qemu_ld_a64_i64 loc0,loc0,noat+un+leul,5
add_i64 loc3,rsp,$0x4
deposit_i64 rsp,rsp,loc3,$0x0,$0x10
extrl_i64_i32 loc5,loc0
call load_seg,$0x0,$0,env,$0x0,loc5
add_i64 rip,rip,$0x2
ext16u_i64 rip,rip
exit_tb $0x0
set_label $L0
exit_tb $0x7fff58000043
If helper_load_seg() generates a fault when validating the segment descriptor then as
the SP has already been incremented, the topmost word of the stack is overwritten by
the arguments pushed onto the stack by the CPU before taking the fault handler. As a
consequence things rapidly go wrong upon return from the fault handler due to the
corrupted stack.
Update the logic for the existing writeback condition so that a POP into the segment
registers also calls helper_load_seg() first before incrementing the SP, so that if a
fault occurs the SP remains unaltered.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2198
Message-ID: <20240606095319.229650-4-mark.cave-ayland@ilande.co.uk>
Fixes: cc1d28bdbe0 ("target/i386: move 00-5F opcodes to new decoder", 2024-05-07)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/emit.c.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 6123235c000..4be3d9a6fba 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -2578,7 +2578,7 @@ static void gen_POP(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
X86DecodedOp *op = &decode->op[0];
MemOp ot = gen_pop_T0(s);
- if (op->has_ea) {
+ if (op->has_ea || op->unit == X86_OP_SEG) {
/* NOTE: order is important for MMU exceptions */
gen_writeback(s, decode, 0, s->T0);
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 15/42] target/i386: fix size of EBP writeback in gen_enter()
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (13 preceding siblings ...)
2024-06-08 8:33 ` [PULL 14/42] target/i386: fix SP when taking a memory fault during POP Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 16/42] machine: default -M mem-merge to off is QEMU_MADV_MERGEABLE is not available Paolo Bonzini
` (27 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark Cave-Ayland, qemu-stable
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
The calculation of FrameTemp is done using the size indicated by mo_pushpop()
before being written back to EBP, but the final writeback to EBP is done using
the size indicated by mo_stacksize().
In the case where mo_pushpop() is MO_32 and mo_stacksize() is MO_16 then the
final writeback to EBP is done using MO_16 which can leave junk in the top
16-bits of EBP after executing ENTER.
Change the writeback of EBP to use the same size indicated by mo_pushpop() to
ensure that the full value is written back.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2198
Message-ID: <20240606095319.229650-5-mark.cave-ayland@ilande.co.uk>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/translate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 2b6f67be40b..fcba9c155f9 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2138,7 +2138,7 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
}
/* Copy the FrameTemp value to EBP. */
- gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1);
+ gen_op_mov_reg_v(s, d_ot, R_EBP, s->T1);
/* Compute the final value of ESP. */
tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 16/42] machine: default -M mem-merge to off is QEMU_MADV_MERGEABLE is not available
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (14 preceding siblings ...)
2024-06-08 8:33 ` [PULL 15/42] target/i386: fix size of EBP writeback in gen_enter() Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 17/42] meson: Don't even detect posix_madvise() on Darwin Paolo Bonzini
` (26 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michal Privoznik
Otherwise, starting any guest on a non-Linux guests results in
qemu-system-arm: Couldn't set property 'merge' on 'memory-backend-ram': Invalid argument
Cc: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/core/machine.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 77a356f232f..a0ee43ca5c0 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -17,6 +17,7 @@
#include "hw/loader.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-machine.h"
+#include "qemu/madvise.h"
#include "qom/object_interfaces.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
@@ -1129,7 +1130,7 @@ static void machine_initfn(Object *obj)
container_get(obj, "/peripheral-anon");
ms->dump_guest_core = true;
- ms->mem_merge = true;
+ ms->mem_merge = (QEMU_MADV_MERGEABLE != QEMU_MADV_INVALID);
ms->enable_graphics = true;
ms->kernel_cmdline = g_strdup("");
ms->ram_size = mc->default_ram_size;
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 17/42] meson: Don't even detect posix_madvise() on Darwin
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (15 preceding siblings ...)
2024-06-08 8:33 ` [PULL 16/42] machine: default -M mem-merge to off is QEMU_MADV_MERGEABLE is not available Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 18/42] osdep: Make qemu_madvise() to set errno in all cases Paolo Bonzini
` (25 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michal Privoznik
From: Michal Privoznik <mprivozn@redhat.com>
On Darwin, posix_madvise() has the same return semantics as plain
madvise() [1]. That's not really what our usage expects.
Fortunately, madvise() is available and preferred anyways so we
may stop detecting posix_madvise() on Darwin.
1: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man2/madvise.2.auto.html
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Message-ID: <00f71753bdeb8c0f049fda05fb63b84bb5502fb3.1717584048.git.mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/meson.build b/meson.build
index d80203f1cde..ec59effca26 100644
--- a/meson.build
+++ b/meson.build
@@ -2556,10 +2556,16 @@ config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
#else
int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
#endif'''))
-config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
- #include <sys/mman.h>
- #include <stddef.h>
- int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
+
+# On Darwin posix_madvise() has the same return semantics as plain madvise(),
+# i.e. errno is set and -1 is returned. That's not really how POSIX defines the
+# function. On the flip side, it has madvise() which is preferred anyways.
+if host_os != 'darwin'
+ config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
+ #include <sys/mman.h>
+ #include <stddef.h>
+ int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
+endif
config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
#include <pthread.h>
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 18/42] osdep: Make qemu_madvise() to set errno in all cases
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (16 preceding siblings ...)
2024-06-08 8:33 ` [PULL 17/42] meson: Don't even detect posix_madvise() on Darwin Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 19/42] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes Paolo Bonzini
` (24 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michal Privoznik, David Hildenbrand
From: Michal Privoznik <mprivozn@redhat.com>
The unspoken premise of qemu_madvise() is that errno is set on
error. And it is mostly the case except for posix_madvise() which
is documented to return either zero (on success) or a positive
error number. This means, we must set errno ourselves. And while
at it, make the function return a negative value on error, just
like other error paths do.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <af17113e7c1f2cc909ffd36d23f5a411b63b8764.1717584048.git.mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
util/osdep.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/util/osdep.c b/util/osdep.c
index e996c4744af..e42f4e8121d 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -57,7 +57,12 @@ int qemu_madvise(void *addr, size_t len, int advice)
#if defined(CONFIG_MADVISE)
return madvise(addr, len, advice);
#elif defined(CONFIG_POSIX_MADVISE)
- return posix_madvise(addr, len, advice);
+ int rc = posix_madvise(addr, len, advice);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
+ return 0;
#else
errno = EINVAL;
return -1;
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 19/42] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (17 preceding siblings ...)
2024-06-08 8:33 ` [PULL 18/42] osdep: Make qemu_madvise() to set errno in all cases Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 20/42] backends/hostmem: Report error when memory size is unaligned Paolo Bonzini
` (23 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel
Cc: Michal Privoznik, Philippe Mathieu-Daudé, David Hildenbrand
From: Michal Privoznik <mprivozn@redhat.com>
Not every OS is capable of madvise() or posix_madvise() even. In
that case, errno should be set to ENOSYS as it reflects the cause
better.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <b381c23bd8f413f1453a2c1a66e0979beaf27433.1717584048.git.mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
util/osdep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util/osdep.c b/util/osdep.c
index e42f4e8121d..5d23bbfbec4 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -64,7 +64,7 @@ int qemu_madvise(void *addr, size_t len, int advice)
}
return 0;
#else
- errno = EINVAL;
+ errno = ENOSYS;
return -1;
#endif
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 20/42] backends/hostmem: Report error when memory size is unaligned
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (18 preceding siblings ...)
2024-06-08 8:33 ` [PULL 19/42] osdep: Make qemu_madvise() return ENOSYS on unsupported OSes Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 21/42] machine, hostmem: improve error messages for unsupported features Paolo Bonzini
` (22 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michal Privoznik, Philippe Mathieu-Daudé, Mario Casquero
From: Michal Privoznik <mprivozn@redhat.com>
If memory-backend-{file,ram} has a size that's not aligned to
underlying page size it is not only wasteful, but also may lead
to hard to debug behaviour. For instance, in case
memory-backend-file and hugepages, madvise() and mbind() fail.
Rightfully so, page is the smallest unit they can work with. And
even though an error is reported, the root cause it not very
clear:
qemu-system-x86_64: Couldn't set property 'dump' on 'memory-backend-file': Invalid argument
After this commit:
qemu-system-x86_64: backend 'memory-backend-file' memory size must be multiple of 2 MiB
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Mario Casquero <mcasquer@redhat.com>
Message-ID: <b5b9f9c6bba07879fb43f3c6f496c69867ae3716.1717584048.git.mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/hostmem.h | 2 +-
backends/hostmem-epc.c | 1 +
backends/hostmem-file.c | 1 +
backends/hostmem-memfd.c | 1 +
backends/hostmem.c | 10 ++++++++++
5 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 04b884bf42a..de47ae59e4b 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -74,7 +74,7 @@ struct HostMemoryBackend {
uint64_t size;
bool merge, dump, use_canonical_path;
bool prealloc, is_mapped, share, reserve;
- bool guest_memfd;
+ bool guest_memfd, aligned;
uint32_t prealloc_threads;
ThreadContext *prealloc_context;
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
diff --git a/backends/hostmem-epc.c b/backends/hostmem-epc.c
index 735e2e1cf84..f58fcf00a10 100644
--- a/backends/hostmem-epc.c
+++ b/backends/hostmem-epc.c
@@ -36,6 +36,7 @@ sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
return false;
}
+ backend->aligned = true;
name = object_get_canonical_path(OBJECT(backend));
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 3c69db79460..7e5072e33ef 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -80,6 +80,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
g_assert_not_reached();
}
+ backend->aligned = true;
name = host_memory_backend_get_name(backend);
ram_flags = backend->share ? RAM_SHARED : 0;
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 745ead0034d..6a3c89a12b2 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -52,6 +52,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
return false;
}
+ backend->aligned = true;
name = host_memory_backend_get_name(backend);
ram_flags = backend->share ? RAM_SHARED : 0;
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
diff --git a/backends/hostmem.c b/backends/hostmem.c
index eb9682b4a85..1edc0ede2a5 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -20,6 +20,7 @@
#include "qom/object_interfaces.h"
#include "qemu/mmap-alloc.h"
#include "qemu/madvise.h"
+#include "qemu/cutils.h"
#include "hw/qdev-core.h"
#ifdef CONFIG_NUMA
@@ -325,6 +326,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
void *ptr;
uint64_t sz;
+ size_t pagesize;
bool async = !phase_check(PHASE_LATE_BACKENDS_CREATED);
if (!bc->alloc) {
@@ -336,6 +338,14 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
ptr = memory_region_get_ram_ptr(&backend->mr);
sz = memory_region_size(&backend->mr);
+ pagesize = qemu_ram_pagesize(backend->mr.ram_block);
+
+ if (backend->aligned && !QEMU_IS_ALIGNED(sz, pagesize)) {
+ g_autofree char *pagesize_str = size_to_str(pagesize);
+ error_setg(errp, "backend '%s' memory size must be multiple of %s",
+ object_get_typename(OBJECT(uc)), pagesize_str);
+ return;
+ }
if (backend->merge) {
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 21/42] machine, hostmem: improve error messages for unsupported features
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (19 preceding siblings ...)
2024-06-08 8:33 ` [PULL 20/42] backends/hostmem: Report error when memory size is unaligned Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 22/42] hostmem: simplify the code for merge and dump properties Paolo Bonzini
` (21 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michal Privoznik
Detect early unsupported MADV_MERGEABLE and MADV_DONTDUMP, and print a clearer
error message that points to the deficiency of the host.
Cc: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem.c | 16 ++++++++++++++++
hw/core/machine.c | 8 ++++++++
2 files changed, 24 insertions(+)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 1edc0ede2a5..6da3d7383e3 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -170,6 +170,14 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ if (QEMU_MADV_MERGEABLE == QEMU_MADV_INVALID) {
+ if (value) {
+ error_setg(errp, "Memory merging is not supported on this host");
+ }
+ assert(!backend->merge);
+ return;
+ }
+
if (!host_memory_backend_mr_inited(backend)) {
backend->merge = value;
return;
@@ -196,6 +204,14 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+ if (QEMU_MADV_DONTDUMP == QEMU_MADV_INVALID) {
+ if (!value) {
+ error_setg(errp, "Dumping guest memory cannot be disabled on this host");
+ }
+ assert(backend->dump);
+ return;
+ }
+
if (!host_memory_backend_mr_inited(backend)) {
backend->dump = value;
return;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index a0ee43ca5c0..c93d2492443 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -428,6 +428,10 @@ static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp)
{
MachineState *ms = MACHINE(obj);
+ if (!value && QEMU_MADV_DONTDUMP == QEMU_MADV_INVALID) {
+ error_setg(errp, "Dumping guest memory cannot be disabled on this host");
+ return;
+ }
ms->dump_guest_core = value;
}
@@ -442,6 +446,10 @@ static void machine_set_mem_merge(Object *obj, bool value, Error **errp)
{
MachineState *ms = MACHINE(obj);
+ if (value && QEMU_MADV_MERGEABLE == QEMU_MADV_INVALID) {
+ error_setg(errp, "Memory merging is not supported on this host");
+ return;
+ }
ms->mem_merge = value;
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 22/42] hostmem: simplify the code for merge and dump properties
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (20 preceding siblings ...)
2024-06-08 8:33 ` [PULL 21/42] machine, hostmem: improve error messages for unsupported features Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 23/42] scsi-disk: Don't silently truncate serial number Paolo Bonzini
` (20 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé
No semantic change, just simpler control flow.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 6da3d7383e3..4e5576a4ada 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -178,19 +178,16 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
return;
}
- if (!host_memory_backend_mr_inited(backend)) {
- backend->merge = value;
- return;
- }
-
- if (value != backend->merge) {
+ if (!host_memory_backend_mr_inited(backend) &&
+ value != backend->merge) {
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
qemu_madvise(ptr, sz,
value ? QEMU_MADV_MERGEABLE : QEMU_MADV_UNMERGEABLE);
- backend->merge = value;
}
+
+ backend->merge = value;
}
static bool host_memory_backend_get_dump(Object *obj, Error **errp)
@@ -212,19 +209,16 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp)
return;
}
- if (!host_memory_backend_mr_inited(backend)) {
- backend->dump = value;
- return;
- }
-
- if (value != backend->dump) {
+ if (host_memory_backend_mr_inited(backend) &&
+ value != backend->dump) {
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
qemu_madvise(ptr, sz,
value ? QEMU_MADV_DODUMP : QEMU_MADV_DONTDUMP);
- backend->dump = value;
}
+
+ backend->dump = value;
}
static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 23/42] scsi-disk: Don't silently truncate serial number
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (21 preceding siblings ...)
2024-06-08 8:33 ` [PULL 22/42] hostmem: simplify the code for merge and dump properties Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 24/42] stubs/meson: Fix qemuutil build when --disable-system Paolo Bonzini
` (19 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Peter Krempa
From: Kevin Wolf <kwolf@redhat.com>
Before this commit, scsi-disk accepts a string of arbitrary length for
its "serial" property. However, the value visible on the guest is
actually truncated to 36 characters. This limitation doesn't come from
the SCSI specification, it is an arbitrary limit that was initially
picked as 20 and later bumped to 36 by commit 48b62063.
Similarly, device_id was introduced as a copy of the serial number,
limited to 20 characters, but commit 48b62063 forgot to actually bump
it.
As long as we silently truncate the given string, extending the limit is
actually not a harmless change, but break the guest ABI. This is the
most important reason why commit 48b62063 was really wrong (and it's
also why we can't change device_id to be in sync with the serial number
again and use 36 characters now, it would be another guest ABI
breakage).
In order to avoid future breakage, don't silently truncate the serial
number string any more, but just error out if it would be truncated.
Buglink: https://issues.redhat.com/browse/RHEL-3542
Suggested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20240604161755.63448-1-kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-disk.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 4bd7af9d0c2..5f55ae54e42 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -58,6 +58,9 @@
#define TYPE_SCSI_DISK_BASE "scsi-disk-base"
+#define MAX_SERIAL_LEN 36
+#define MAX_SERIAL_LEN_FOR_DEVID 20
+
OBJECT_DECLARE_TYPE(SCSIDiskState, SCSIDiskClass, SCSI_DISK_BASE)
struct SCSIDiskClass {
@@ -648,8 +651,8 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
}
l = strlen(s->serial);
- if (l > 36) {
- l = 36;
+ if (l > MAX_SERIAL_LEN) {
+ l = MAX_SERIAL_LEN;
}
trace_scsi_disk_emulate_vpd_page_80(req->cmd.xfer);
@@ -2501,9 +2504,20 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
}
+ if (s->serial && strlen(s->serial) > MAX_SERIAL_LEN) {
+ error_setg(errp, "The serial number can't be longer than %d characters",
+ MAX_SERIAL_LEN);
+ return;
+ }
if (!s->device_id) {
if (s->serial) {
- s->device_id = g_strdup_printf("%.20s", s->serial);
+ if (strlen(s->serial) > MAX_SERIAL_LEN_FOR_DEVID) {
+ error_setg(errp, "The serial number can't be longer than %d "
+ "characters when it is also used as the default for "
+ "device_id", MAX_SERIAL_LEN_FOR_DEVID);
+ return;
+ }
+ s->device_id = g_strdup(s->serial);
} else {
const char *str = blk_name(s->qdev.conf.blk);
if (str && *str) {
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 24/42] stubs/meson: Fix qemuutil build when --disable-system
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (22 preceding siblings ...)
2024-06-08 8:33 ` [PULL 23/42] scsi-disk: Don't silently truncate serial number Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 25/42] i386/hvf: Adds support for INVTSC cpuid bit Paolo Bonzini
` (18 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Zhao Liu, Daniel P . Berrangé
From: Zhao Liu <zhao1.liu@intel.com>
Compiling without system, user, tools or guest-agent fails with the
following error message:
./configure --disable-system --disable-user --disable-tools \
--disable-guest-agent
error message:
/usr/bin/ld: libqemuutil.a.p/util_error-report.c.o: in function `error_printf':
/media/liuzhao/data/qemu-cook/build/../util/error-report.c:38: undefined reference to `error_vprintf'
/usr/bin/ld: libqemuutil.a.p/util_error-report.c.o: in function `vreport':
/media/liuzhao/data/qemu-cook/build/../util/error-report.c:215: undefined reference to `error_vprintf'
collect2: error: ld returned 1 exit status
This is because tests/bench and tests/unit both need qemuutil, which
requires error_vprintf stub when system is disabled.
Add error_vprintf stub into stub_ss for all cases other than disabling
system.
Fixes: 3a15604900c4 ("stubs: include stubs only if needed")
Reported-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20240605152549.1795762-1-zhao1.liu@intel.com>
[Include error-printf.c unconditionally. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
stubs/meson.build | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/stubs/meson.build b/stubs/meson.build
index 3b9d42023cb..f15b48d01f0 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -3,6 +3,7 @@
# below, so that it is clear who needs the stubbed functionality.
stub_ss.add(files('cpu-get-clock.c'))
+stub_ss.add(files('error-printf.c'))
stub_ss.add(files('fdset.c'))
stub_ss.add(files('iothread-lock.c'))
stub_ss.add(files('is-daemonized.c'))
@@ -45,17 +46,10 @@ if have_block or have_ga
stub_ss.add(files('qmp-quit.c'))
endif
-if have_ga
- stub_ss.add(files('error-printf.c'))
-endif
-
if have_block or have_user
stub_ss.add(files('qtest.c'))
stub_ss.add(files('vm-stop.c'))
stub_ss.add(files('vmstate.c'))
-
- # more symbols provided by the monitor
- stub_ss.add(files('error-printf.c'))
endif
if have_user
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 25/42] i386/hvf: Adds support for INVTSC cpuid bit
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (23 preceding siblings ...)
2024-06-08 8:33 ` [PULL 24/42] stubs/meson: Fix qemuutil build when --disable-system Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:33 ` [PULL 26/42] i386/hvf: Fixes some compilation warnings Paolo Bonzini
` (17 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan, Roman Bolshakov
From: Phil Dennis-Jordan <phil@philjordan.eu>
This patch adds the INVTSC bit to the Hypervisor.framework accelerator's
CPUID bit passthrough allow-list. Previously, specifying +invtsc in the CPU
configuration would fail with the following warning despite the host CPU
advertising the feature:
qemu-system-x86_64: warning: host doesn't support requested feature:
CPUID.80000007H:EDX.invtsc [bit 8]
x86 macOS itself relies on a fixed rate TSC for its own Mach absolute time
timestamp mechanism, so there's no reason we can't enable this bit for guests.
When the feature is enabled, a migration blocker is installed.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Roman Bolshakov <roman@roolebo.dev>
Tested-by: Roman Bolshakov <roman@roolebo.dev>
Message-ID: <20240605112556.43193-2-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf/hvf.c | 18 ++++++++++++++++++
target/i386/hvf/x86_cpuid.c | 4 ++++
2 files changed, 22 insertions(+)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index e493452acb9..e6e916225bf 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -49,6 +49,8 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/memalign.h"
+#include "qapi/error.h"
+#include "migration/blocker.h"
#include "sysemu/hvf.h"
#include "sysemu/hvf_int.h"
@@ -74,6 +76,8 @@
#include "qemu/accel.h"
#include "target/i386/cpu.h"
+static Error *invtsc_mig_blocker;
+
void vmx_update_tpr(CPUState *cpu)
{
/* TODO: need integrate APIC handling */
@@ -221,6 +225,8 @@ int hvf_arch_init_vcpu(CPUState *cpu)
{
X86CPU *x86cpu = X86_CPU(cpu);
CPUX86State *env = &x86cpu->env;
+ Error *local_err = NULL;
+ int r;
uint64_t reqCap;
init_emu();
@@ -238,6 +244,18 @@ int hvf_arch_init_vcpu(CPUState *cpu)
}
}
+ if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
+ invtsc_mig_blocker == NULL) {
+ error_setg(&invtsc_mig_blocker,
+ "State blocked by non-migratable CPU device (invtsc flag)");
+ r = migrate_add_blocker(&invtsc_mig_blocker, &local_err);
+ if (r < 0) {
+ error_report_err(local_err);
+ return r;
+ }
+ }
+
+
if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,
&hvf_state->hvf_caps->vmx_cap_pinbased)) {
abort();
diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c
index 9380b90496e..e56cd8411ba 100644
--- a/target/i386/hvf/x86_cpuid.c
+++ b/target/i386/hvf/x86_cpuid.c
@@ -146,6 +146,10 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_OSVW | CPUID_EXT3_XOP |
CPUID_EXT3_FMA4 | CPUID_EXT3_TBM;
break;
+ case 0x80000007:
+ edx &= CPUID_APM_INVTSC;
+ eax = ebx = ecx = 0;
+ break;
default:
return 0;
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 26/42] i386/hvf: Fixes some compilation warnings
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (24 preceding siblings ...)
2024-06-08 8:33 ` [PULL 25/42] i386/hvf: Adds support for INVTSC cpuid bit Paolo Bonzini
@ 2024-06-08 8:33 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 27/42] hvf: Consistent types for vCPU handles Paolo Bonzini
` (16 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan, Roman Bolshakov
From: Phil Dennis-Jordan <phil@philjordan.eu>
A bunch of function definitions used empty parentheses instead of (void) syntax, yielding the following warning when building with clang on macOS:
warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
In addition to fixing these function headers, it also fixes what appears to be a typo causing a variable to be unused after initialisation.
warning: variable 'entry_ctls' set but not used [-Wunused-but-set-variable]
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Roman Bolshakov <roman@roolebo.dev>
Tested-by: Roman Bolshakov <roman@roolebo.dev>
Message-ID: <20240605112556.43193-3-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf/vmx.h | 3 +--
target/i386/hvf/x86_decode.c | 2 +-
target/i386/hvf/x86_emu.c | 4 ++--
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
index 0fffcfa46ce..3954ef883df 100644
--- a/target/i386/hvf/vmx.h
+++ b/target/i386/hvf/vmx.h
@@ -95,8 +95,7 @@ static void enter_long_mode(hv_vcpuid_t vcpu, uint64_t cr0, uint64_t efer)
efer |= MSR_EFER_LMA;
wvmcs(vcpu, VMCS_GUEST_IA32_EFER, efer);
entry_ctls = rvmcs(vcpu, VMCS_ENTRY_CTLS);
- wvmcs(vcpu, VMCS_ENTRY_CTLS, rvmcs(vcpu, VMCS_ENTRY_CTLS) |
- VM_ENTRY_GUEST_LMA);
+ wvmcs(vcpu, VMCS_ENTRY_CTLS, entry_ctls | VM_ENTRY_GUEST_LMA);
uint64_t guest_tr_ar = rvmcs(vcpu, VMCS_GUEST_TR_ACCESS_RIGHTS);
if ((efer & MSR_EFER_LME) &&
diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c
index 3728d7705e2..a4a28f113fd 100644
--- a/target/i386/hvf/x86_decode.c
+++ b/target/i386/hvf/x86_decode.c
@@ -2111,7 +2111,7 @@ uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
return decode->len;
}
-void init_decoder()
+void init_decoder(void)
{
int i;
diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c
index 3a3f0a50d0b..38c782b8e3b 100644
--- a/target/i386/hvf/x86_emu.c
+++ b/target/i386/hvf/x86_emu.c
@@ -1409,7 +1409,7 @@ static struct cmd_handler {
static struct cmd_handler _cmd_handler[X86_DECODE_CMD_LAST];
-static void init_cmd_handler()
+static void init_cmd_handler(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(handlers); i++) {
@@ -1481,7 +1481,7 @@ bool exec_instruction(CPUX86State *env, struct x86_decode *ins)
return true;
}
-void init_emu()
+void init_emu(void)
{
init_cmd_handler();
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 27/42] hvf: Consistent types for vCPU handles
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (25 preceding siblings ...)
2024-06-08 8:33 ` [PULL 26/42] i386/hvf: Fixes some compilation warnings Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 28/42] i386/hvf: Fixes dirty memory tracking by page granularity RX->RWX change Paolo Bonzini
` (15 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan, Roman Bolshakov
From: Phil Dennis-Jordan <phil@philjordan.eu>
macOS Hypervisor.framework uses different types for identifying vCPUs, hv_vcpu_t or hv_vcpuid_t, depending on host architecture. They are not just differently named typedefs for the same primitive type, but reference different-width integers.
Instead of using an integer type and casting where necessary, this change introduces a typedef which resolves the active architecture’s hvf typedef. It also removes a now-unnecessary cast.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Roman Bolshakov <roman@roolebo.dev>
Tested-by: Roman Bolshakov <roman@roolebo.dev>
Message-ID: <20240605112556.43193-4-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/hvf_int.h | 4 +++-
accel/hvf/hvf-accel-ops.c | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
index 4a327fd5260..30e739a2b52 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/sysemu/hvf_int.h
@@ -13,8 +13,10 @@
#ifdef __aarch64__
#include <Hypervisor/Hypervisor.h>
+typedef hv_vcpu_t hvf_vcpuid;
#else
#include <Hypervisor/hv.h>
+typedef hv_vcpuid_t hvf_vcpuid;
#endif
/* hvf_slot flags */
@@ -50,7 +52,7 @@ struct HVFState {
extern HVFState *hvf_state;
struct AccelCPUState {
- uint64_t fd;
+ hvf_vcpuid fd;
void *exit;
bool vtimer_masked;
sigset_t unblock_ipi_mask;
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 6f1e27ef469..b2a37a2229f 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -400,7 +400,7 @@ static int hvf_init_vcpu(CPUState *cpu)
r = hv_vcpu_create(&cpu->accel->fd,
(hv_vcpu_exit_t **)&cpu->accel->exit, NULL);
#else
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->accel->fd, HV_VCPU_DEFAULT);
+ r = hv_vcpu_create(&cpu->accel->fd, HV_VCPU_DEFAULT);
#endif
cpu->accel->dirty = true;
assert_hvf_ok(r);
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 28/42] i386/hvf: Fixes dirty memory tracking by page granularity RX->RWX change
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (26 preceding siblings ...)
2024-06-08 8:34 ` [PULL 27/42] hvf: Consistent types for vCPU handles Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 29/42] i386/hvf: In kick_vcpu use hv_vcpu_interrupt to force exit Paolo Bonzini
` (14 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan, Roman Bolshakov
From: Phil Dennis-Jordan <phil@philjordan.eu>
When using x86 macOS Hypervisor.framework as accelerator, detection of
dirty memory regions is implemented by marking logged memory region
slots as read-only in the EPT, then setting the dirty flag when a
guest write causes a fault. The area marked dirty should then be marked
writable in order for subsequent writes to succeed without a VM exit.
However, dirty bits are tracked on a per-page basis, whereas the fault
handler was marking the whole logged memory region as writable. This
change fixes the fault handler so only the protection of the single
faulting page is marked as dirty.
(Note: the dirty page tracking appeared to work despite this error
because HVF’s hv_vcpu_run() function generated unnecessary EPT fault
exits, which ended up causing the dirty marking handler to run even
when the memory region had been marked RW. When using
hv_vcpu_run_until(), a change planned for a subsequent commit, these
spurious exits no longer occur, so dirty memory tracking malfunctions.)
Additionally, the dirty page is set to permit code execution, the same
as all other guest memory; changing memory protection from RX to RW not
RWX appears to have been an oversight.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Roman Bolshakov <roman@roolebo.dev>
Tested-by: Roman Bolshakov <roman@roolebo.dev>
Message-ID: <20240605112556.43193-5-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf/hvf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index e6e916225bf..268c5734d5c 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -135,9 +135,10 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
if (write && slot) {
if (slot->flags & HVF_SLOT_LOG) {
+ uint64_t dirty_page_start = gpa & ~(TARGET_PAGE_SIZE - 1u);
memory_region_set_dirty(slot->region, gpa - slot->start, 1);
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
- HV_MEMORY_READ | HV_MEMORY_WRITE);
+ hv_vm_protect(dirty_page_start, TARGET_PAGE_SIZE,
+ HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
}
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 29/42] i386/hvf: In kick_vcpu use hv_vcpu_interrupt to force exit
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (27 preceding siblings ...)
2024-06-08 8:34 ` [PULL 28/42] i386/hvf: Fixes dirty memory tracking by page granularity RX->RWX change Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 30/42] i386/hvf: Updates API usage to use modern vCPU run function Paolo Bonzini
` (13 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan
From: Phil Dennis-Jordan <phil@philjordan.eu>
When interrupting a vCPU thread, this patch actually tells the hypervisor to
stop running guest code on that vCPU.
Calling hv_vcpu_interrupt actually forces a vCPU exit, analogously to
hv_vcpus_exit on aarch64. Alternatively, if the vCPU thread
is not
running the VM, it will immediately cause an exit when it attempts
to do so.
Previously, hvf_kick_vcpu_thread relied upon hv_vcpu_run returning very
frequently, including many spurious exits, which made it less of a problem that
nothing was actively done to stop the vCPU thread running guest code.
The newer, more efficient hv_vcpu_run_until exits much more rarely, so a true
"kick" is needed before switching to that.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Message-ID: <20240605112556.43193-6-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf/hvf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 268c5734d5c..106ac5cbf62 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -215,6 +215,7 @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
void hvf_kick_vcpu_thread(CPUState *cpu)
{
cpus_kick_thread(cpu);
+ hv_vcpu_interrupt(&cpu->accel->fd, 1);
}
int hvf_arch_init(void)
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 30/42] i386/hvf: Updates API usage to use modern vCPU run function
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (28 preceding siblings ...)
2024-06-08 8:34 ` [PULL 29/42] i386/hvf: In kick_vcpu use hv_vcpu_interrupt to force exit Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 31/42] hvf: Makes assert_hvf_ok report failed expression Paolo Bonzini
` (12 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan
From: Phil Dennis-Jordan <phil@philjordan.eu>
macOS 10.15 introduced the more efficient hv_vcpu_run_until() function
to supersede hv_vcpu_run(). According to the documentation, there is no
longer any reason to use the latter on modern host OS versions, especially
after 11.0 added support for an indefinite deadline.
Observed behaviour of the newer function is that as documented, it exits
much less frequently - and most of the original function’s exits seem to
have been effectively pointless.
Another reason to use the new function is that it is a prerequisite for
using newer features such as in-kernel APIC support. (Not covered by
this patch.)
This change implements the upgrade by selecting one of three code paths
at compile time: two static code paths for the new and old functions
respectively, when building for targets where the new function is either
not available, or where the built executable won’t run on older
platforms lacking the new function anyway. The third code path selects
dynamically based on runtime detected availability of the weakly-linked
symbol.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Message-ID: <20240605112556.43193-7-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/hvf/hvf.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 106ac5cbf62..2d0eef6cd97 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -427,6 +427,27 @@ static void hvf_cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
}
+static hv_return_t hvf_vcpu_run(hv_vcpuid_t vcpu_id)
+{
+ /*
+ * hv_vcpu_run_until is available and recommended from macOS 10.15+,
+ * HV_DEADLINE_FOREVER from 11.0. Test for availability at runtime and fall
+ * back to hv_vcpu_run() only where necessary.
+ */
+#ifndef MAC_OS_VERSION_11_0
+ return hv_vcpu_run(vcpu_id);
+#elif MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+ return hv_vcpu_run_until(vcpu_id, HV_DEADLINE_FOREVER);
+#else /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_11_0 */
+ /* 11.0 SDK or newer, but could be < 11 at runtime */
+ if (__builtin_available(macOS 11.0, *)) {
+ return hv_vcpu_run_until(vcpu_id, HV_DEADLINE_FOREVER);
+ } else {
+ return hv_vcpu_run(vcpu_id);
+ }
+#endif
+}
+
int hvf_vcpu_exec(CPUState *cpu)
{
X86CPU *x86_cpu = X86_CPU(cpu);
@@ -455,7 +476,7 @@ int hvf_vcpu_exec(CPUState *cpu)
return EXCP_HLT;
}
- hv_return_t r = hv_vcpu_run(cpu->accel->fd);
+ hv_return_t r = hvf_vcpu_run(cpu->accel->fd);
assert_hvf_ok(r);
/* handle VMEXIT */
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 31/42] hvf: Makes assert_hvf_ok report failed expression
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (29 preceding siblings ...)
2024-06-08 8:34 ` [PULL 30/42] i386/hvf: Updates API usage to use modern vCPU run function Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 32/42] target/i386: add support for FRED in CPUID enumeration Paolo Bonzini
` (11 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan
From: Phil Dennis-Jordan <phil@philjordan.eu>
When a macOS Hypervisor.framework call fails which is checked by
assert_hvf_ok(), Qemu exits printing the error value, but not the
location
in the code, as regular assert() macro expansions would.
This change turns assert_hvf_ok() into a macro similar to other
assertions, which expands to a call to the corresponding _impl()
function together with information about the expression that failed
the assertion and its location in the code.
Additionally, stringifying the numeric hv_return_t code is factored
into a helper function that can be reused for diagnostics and debugging
outside of assertions.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Message-ID: <20240605112556.43193-8-phil@philjordan.eu>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/hvf_int.h | 5 +++-
accel/hvf/hvf-all.c | 51 +++++++++++++++++-----------------------
2 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
index 30e739a2b52..5b28d17ba1f 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/sysemu/hvf_int.h
@@ -60,7 +60,10 @@ struct AccelCPUState {
bool dirty;
};
-void assert_hvf_ok(hv_return_t ret);
+void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
+ const char *exp);
+#define assert_hvf_ok(EX) assert_hvf_ok_impl((EX), __FILE__, __LINE__, #EX)
+const char *hvf_return_string(hv_return_t ret);
int hvf_arch_init(void);
int hvf_arch_init_vcpu(CPUState *cpu);
void hvf_arch_vcpu_destroy(CPUState *cpu);
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index db05b81be58..c008dc2f1ea 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -13,40 +13,33 @@
#include "sysemu/hvf.h"
#include "sysemu/hvf_int.h"
-void assert_hvf_ok(hv_return_t ret)
+const char *hvf_return_string(hv_return_t ret)
+{
+ switch (ret) {
+ case HV_SUCCESS: return "HV_SUCCESS";
+ case HV_ERROR: return "HV_ERROR";
+ case HV_BUSY: return "HV_BUSY";
+ case HV_BAD_ARGUMENT: return "HV_BAD_ARGUMENT";
+ case HV_NO_RESOURCES: return "HV_NO_RESOURCES";
+ case HV_NO_DEVICE: return "HV_NO_DEVICE";
+ case HV_UNSUPPORTED: return "HV_UNSUPPORTED";
+#if defined(MAC_OS_VERSION_11_0) && \
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+ case HV_DENIED: return "HV_DENIED";
+#endif
+ default: return "[unknown hv_return value]";
+ }
+}
+
+void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
+ const char *exp)
{
if (ret == HV_SUCCESS) {
return;
}
- switch (ret) {
- case HV_ERROR:
- error_report("Error: HV_ERROR");
- break;
- case HV_BUSY:
- error_report("Error: HV_BUSY");
- break;
- case HV_BAD_ARGUMENT:
- error_report("Error: HV_BAD_ARGUMENT");
- break;
- case HV_NO_RESOURCES:
- error_report("Error: HV_NO_RESOURCES");
- break;
- case HV_NO_DEVICE:
- error_report("Error: HV_NO_DEVICE");
- break;
- case HV_UNSUPPORTED:
- error_report("Error: HV_UNSUPPORTED");
- break;
-#if defined(MAC_OS_VERSION_11_0) && \
- MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
- case HV_DENIED:
- error_report("Error: HV_DENIED");
- break;
-#endif
- default:
- error_report("Unknown Error");
- }
+ error_report("Error: %s = %s (0x%x, at %s:%u)",
+ exp, hvf_return_string(ret), ret, file, line);
abort();
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 32/42] target/i386: add support for FRED in CPUID enumeration
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (30 preceding siblings ...)
2024-06-08 8:34 ` [PULL 31/42] hvf: Makes assert_hvf_ok report failed expression Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 33/42] target/i386: mark CR4.FRED not reserved Paolo Bonzini
` (10 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Xin Li, Shan Kang
From: Xin Li <xin3.li@intel.com>
FRED, i.e., the Intel flexible return and event delivery architecture,
defines simple new transitions that change privilege level (ring
transitions).
The new transitions defined by the FRED architecture are FRED event
delivery and, for returning from events, two FRED return instructions.
FRED event delivery can effect a transition from ring 3 to ring 0, but
it is used also to deliver events incident to ring 0. One FRED
instruction (ERETU) effects a return from ring 0 to ring 3, while the
other (ERETS) returns while remaining in ring 0. Collectively, FRED
event delivery and the FRED return instructions are FRED transitions.
In addition to these transitions, the FRED architecture defines a new
instruction (LKGS) for managing the state of the GS segment register.
The LKGS instruction can be used by 64-bit operating systems that do
not use the new FRED transitions.
WRMSRNS is an instruction that behaves exactly like WRMSR, with the
only difference being that it is not a serializing instruction by
default. Under certain conditions, WRMSRNS may replace WRMSR to improve
performance. FRED uses it to switch RSP0 in a faster manner.
Search for the latest FRED spec in most search engines with this search
pattern:
site:intel.com FRED (flexible return and event delivery) specification
The CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[17] enumerates FRED, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[18] enumerates LKGS, and
the CPUID feature flag CPUID.(EAX=7,ECX=1):EAX[19] enumerates WRMSRNS.
Add CPUID definitions for FRED/LKGS/WRMSRNS, and expose them to KVM guests.
Because FRED relies on LKGS and WRMSRNS, add that to feature dependency
map.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Message-ID: <20231109072012.8078-2-xin3.li@intel.com>
[Fix order of dependencies, add dependencies from LM to FRED. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 6 ++++++
target/i386/cpu.c | 14 +++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c64ef0c1a28..ad3577056da 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -941,6 +941,12 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8)
/* PREFETCHIT0/1 Instructions */
#define CPUID_7_1_EDX_PREFETCHITI (1U << 14)
+/* Flexible return and event delivery (FRED) */
+#define CPUID_7_1_EAX_FRED (1U << 17)
+/* Load into IA32_KERNEL_GS_BASE (LKGS) */
+#define CPUID_7_1_EAX_LKGS (1U << 18)
+/* Non-Serializing Write to Model Specific Register (WRMSRNS) */
+#define CPUID_7_1_EAX_WRMSRNS (1U << 19)
/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */
#define CPUID_7_2_EDX_MCDT_NO (1U << 5)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 914bef442c7..bfb5a25e596 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1114,7 +1114,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
NULL, NULL, "fzrm", "fsrs",
"fsrc", NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, "fred", "lkgs", "wrmsrns",
NULL, "amx-fp16", NULL, "avx-ifma",
NULL, NULL, "lam", NULL,
NULL, NULL, NULL, NULL,
@@ -1701,6 +1701,18 @@ static FeatureDep feature_dependencies[] = {
.from = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG },
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
},
+ {
+ .from = { FEAT_8000_0001_EDX, CPUID_EXT2_LM },
+ .to = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED },
+ },
+ {
+ .from = { FEAT_7_1_EAX, CPUID_7_1_EAX_LKGS },
+ .to = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED },
+ },
+ {
+ .from = { FEAT_7_1_EAX, CPUID_7_1_EAX_WRMSRNS },
+ .to = { FEAT_7_1_EAX, CPUID_7_1_EAX_FRED },
+ },
};
typedef struct X86RegisterInfo32 {
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 33/42] target/i386: mark CR4.FRED not reserved
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (31 preceding siblings ...)
2024-06-08 8:34 ` [PULL 32/42] target/i386: add support for FRED in CPUID enumeration Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 34/42] vmxcap: add support for VMX FRED controls Paolo Bonzini
` (9 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Xin Li, Shan Kang, Zhao Liu
From: Xin Li <xin3.li@intel.com>
The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when FRED
is exposed to guests, otherwise it is still a reserved bit.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20231109072012.8078-3-xin3.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ad3577056da..9a582218f43 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -261,6 +261,18 @@ typedef enum X86Seg {
#define CR4_PKS_MASK (1U << 24)
#define CR4_LAM_SUP_MASK (1U << 28)
+#ifdef TARGET_X86_64
+#define CR4_FRED_MASK (1ULL << 32)
+#else
+#define CR4_FRED_MASK 0
+#endif
+
+#ifdef TARGET_X86_64
+#define CR4_FRED_MASK (1ULL << 32)
+#else
+#define CR4_FRED_MASK 0
+#endif
+
#define CR4_RESERVED_MASK \
(~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
| CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
@@ -269,7 +281,7 @@ typedef enum X86Seg {
| CR4_LA57_MASK \
| CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK \
- | CR4_LAM_SUP_MASK))
+ | CR4_LAM_SUP_MASK | CR4_FRED_MASK))
#define DR6_BD (1 << 13)
#define DR6_BS (1 << 14)
@@ -2613,6 +2625,9 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_LAM)) {
reserved_bits |= CR4_LAM_SUP_MASK;
}
+ if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED)) {
+ reserved_bits |= CR4_FRED_MASK;
+ }
return reserved_bits;
}
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 34/42] vmxcap: add support for VMX FRED controls
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (32 preceding siblings ...)
2024-06-08 8:34 ` [PULL 33/42] target/i386: mark CR4.FRED not reserved Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 35/42] target/i386: enumerate VMX nested-exception support Paolo Bonzini
` (8 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Xin Li, Shan Kang
From: Xin Li <xin3.li@intel.com>
Report secondary vm-exit controls and the VMX controls used to
save/load FRED MSRs.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Message-ID: <20231109072012.8078-5-xin3.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/kvm/vmxcap | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 3fb4d5b3425..44898d73c2e 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -24,6 +24,7 @@ MSR_IA32_VMX_TRUE_EXIT_CTLS = 0x48F
MSR_IA32_VMX_TRUE_ENTRY_CTLS = 0x490
MSR_IA32_VMX_VMFUNC = 0x491
MSR_IA32_VMX_PROCBASED_CTLS3 = 0x492
+MSR_IA32_VMX_EXIT_CTLS2 = 0x493
class msr(object):
def __init__(self):
@@ -219,11 +220,21 @@ controls = [
23: 'Clear IA32_BNDCFGS',
24: 'Conceal VM exits from PT',
25: 'Clear IA32_RTIT_CTL',
+ 31: 'Activate secondary VM-exit controls',
},
cap_msr = MSR_IA32_VMX_EXIT_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
),
+ Allowed1Control(
+ name = 'secondary VM-Exit controls',
+ bits = {
+ 0: 'Save IA32 FRED MSRs',
+ 1: 'Load IA32 FRED MSRs',
+ },
+ cap_msr = MSR_IA32_VMX_EXIT_CTLS2,
+ ),
+
Control(
name = 'VM-Entry controls',
bits = {
@@ -237,6 +248,7 @@ controls = [
16: 'Load IA32_BNDCFGS',
17: 'Conceal VM entries from PT',
18: 'Load IA32_RTIT_CTL',
+ 23: 'Load IA32 FRED MSRs',
},
cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 35/42] target/i386: enumerate VMX nested-exception support
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (33 preceding siblings ...)
2024-06-08 8:34 ` [PULL 34/42] vmxcap: add support for VMX FRED controls Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 36/42] target/i386: Add get/set/migrate support for FRED MSRs Paolo Bonzini
` (7 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Xin Li, Shan Kang
From: Xin Li <xin3.li@intel.com>
Allow VMX nested-exception support to be exposed in KVM guests, thus
nested KVM guests can enumerate it.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Message-ID: <20231109072012.8078-6-xin3.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 1 +
target/i386/cpu.c | 1 +
scripts/kvm/vmxcap | 1 +
3 files changed, 3 insertions(+)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9a582218f43..8ff27e933de 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1071,6 +1071,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define MSR_VMX_BASIC_INS_OUTS (1ULL << 54)
#define MSR_VMX_BASIC_TRUE_CTLS (1ULL << 55)
#define MSR_VMX_BASIC_ANY_ERRCODE (1ULL << 56)
+#define MSR_VMX_BASIC_NESTED_EXCEPTION (1ULL << 58)
#define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK 0x1Full
#define MSR_VMX_MISC_STORE_LMA (1ULL << 5)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index bfb5a25e596..383230fa479 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1492,6 +1492,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[54] = "vmx-ins-outs",
[55] = "vmx-true-ctls",
[56] = "vmx-any-errcode",
+ [58] = "vmx-nested-exception",
},
.msr = {
.index = MSR_IA32_VMX_BASIC,
diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
index 44898d73c2e..508be19c758 100755
--- a/scripts/kvm/vmxcap
+++ b/scripts/kvm/vmxcap
@@ -117,6 +117,7 @@ controls = [
54: 'INS/OUTS instruction information',
55: 'IA32_VMX_TRUE_*_CTLS support',
56: 'Skip checks on event error code',
+ 58: 'VMX nested exception support',
},
msr = MSR_IA32_VMX_BASIC,
),
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 36/42] target/i386: Add get/set/migrate support for FRED MSRs
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (34 preceding siblings ...)
2024-06-08 8:34 ` [PULL 35/42] target/i386: enumerate VMX nested-exception support Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 37/42] docs: i386: pc: Avoid mentioning limit of maximum vCPUs Paolo Bonzini
` (6 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Xin Li, Shan Kang
From: Xin Li <xin3.li@intel.com>
FRED CPU states are managed in 9 new FRED MSRs, in addtion to a few
existing CPU registers and MSRs, e.g., CR4.FRED and MSR_IA32_PL0_SSP.
Save/restore/migrate FRED MSRs if FRED is exposed to the guest.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
Message-ID: <20231109072012.8078-7-xin3.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 22 +++++++++++++++++++
target/i386/kvm/kvm.c | 49 +++++++++++++++++++++++++++++++++++++++++++
target/i386/machine.c | 28 +++++++++++++++++++++++++
3 files changed, 99 insertions(+)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 8ff27e933de..29d799adfd6 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -538,6 +538,17 @@ typedef enum X86Seg {
#define MSR_IA32_XFD 0x000001c4
#define MSR_IA32_XFD_ERR 0x000001c5
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0 0x000001cc /* Stack level 0 regular stack pointer */
+#define MSR_IA32_FRED_RSP1 0x000001cd /* Stack level 1 regular stack pointer */
+#define MSR_IA32_FRED_RSP2 0x000001ce /* Stack level 2 regular stack pointer */
+#define MSR_IA32_FRED_RSP3 0x000001cf /* Stack level 3 regular stack pointer */
+#define MSR_IA32_FRED_STKLVLS 0x000001d0 /* FRED exception stack levels */
+#define MSR_IA32_FRED_SSP1 0x000001d1 /* Stack level 1 shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP2 0x000001d2 /* Stack level 2 shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_SSP3 0x000001d3 /* Stack level 3 shadow stack pointer in ring 0 */
+#define MSR_IA32_FRED_CONFIG 0x000001d4 /* FRED Entrypoint and interrupt stack level */
+
#define MSR_IA32_BNDCFGS 0x00000d90
#define MSR_IA32_XSS 0x00000da0
#define MSR_IA32_UMWAIT_CONTROL 0xe1
@@ -1723,6 +1734,17 @@ typedef struct CPUArchState {
target_ulong cstar;
target_ulong fmask;
target_ulong kernelgsbase;
+
+ /* FRED MSRs */
+ uint64_t fred_rsp0;
+ uint64_t fred_rsp1;
+ uint64_t fred_rsp2;
+ uint64_t fred_rsp3;
+ uint64_t fred_stklvls;
+ uint64_t fred_ssp1;
+ uint64_t fred_ssp2;
+ uint64_t fred_ssp3;
+ uint64_t fred_config;
#endif
uint64_t tsc_adjust;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 0852ed077f0..b5635209812 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3376,6 +3376,17 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+ if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, env->fred_rsp0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, env->fred_rsp1);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, env->fred_rsp2);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, env->fred_rsp3);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, env->fred_stklvls);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, env->fred_ssp1);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, env->fred_ssp2);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, env->fred_ssp3);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, env->fred_config);
+ }
}
#endif
@@ -3848,6 +3859,17 @@ static int kvm_get_msrs(X86CPU *cpu)
kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
kvm_msr_entry_add(cpu, MSR_FMASK, 0);
kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
+ if (env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED) {
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP0, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP1, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP2, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_RSP3, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_STKLVLS, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP1, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, 0);
+ }
}
#endif
kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
@@ -4069,6 +4091,33 @@ static int kvm_get_msrs(X86CPU *cpu)
case MSR_LSTAR:
env->lstar = msrs[i].data;
break;
+ case MSR_IA32_FRED_RSP0:
+ env->fred_rsp0 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_RSP1:
+ env->fred_rsp1 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_RSP2:
+ env->fred_rsp2 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_RSP3:
+ env->fred_rsp3 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_STKLVLS:
+ env->fred_stklvls = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_SSP1:
+ env->fred_ssp1 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_SSP2:
+ env->fred_ssp2 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_SSP3:
+ env->fred_ssp3 = msrs[i].data;
+ break;
+ case MSR_IA32_FRED_CONFIG:
+ env->fred_config = msrs[i].data;
+ break;
#endif
case MSR_IA32_TSC:
env->tsc = msrs[i].data;
diff --git a/target/i386/machine.c b/target/i386/machine.c
index c3ae3208147..39f8294f279 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1544,6 +1544,33 @@ static const VMStateDescription vmstate_msr_xfd = {
};
#ifdef TARGET_X86_64
+static bool intel_fred_msrs_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return !!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED);
+}
+
+static const VMStateDescription vmstate_msr_fred = {
+ .name = "cpu/fred",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = intel_fred_msrs_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.fred_rsp0, X86CPU),
+ VMSTATE_UINT64(env.fred_rsp1, X86CPU),
+ VMSTATE_UINT64(env.fred_rsp2, X86CPU),
+ VMSTATE_UINT64(env.fred_rsp3, X86CPU),
+ VMSTATE_UINT64(env.fred_stklvls, X86CPU),
+ VMSTATE_UINT64(env.fred_ssp1, X86CPU),
+ VMSTATE_UINT64(env.fred_ssp2, X86CPU),
+ VMSTATE_UINT64(env.fred_ssp3, X86CPU),
+ VMSTATE_UINT64(env.fred_config, X86CPU),
+ VMSTATE_END_OF_LIST()
+ }
+ };
+
static bool amx_xtile_needed(void *opaque)
{
X86CPU *cpu = opaque;
@@ -1747,6 +1774,7 @@ const VMStateDescription vmstate_x86_cpu = {
&vmstate_pdptrs,
&vmstate_msr_xfd,
#ifdef TARGET_X86_64
+ &vmstate_msr_fred,
&vmstate_amx_xtile,
#endif
&vmstate_arch_lbr,
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 37/42] docs: i386: pc: Avoid mentioning limit of maximum vCPUs
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (35 preceding siblings ...)
2024-06-08 8:34 ` [PULL 36/42] target/i386: Add get/set/migrate support for FRED MSRs Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 38/42] i386: Fix MCE support for AMD hosts Paolo Bonzini
` (5 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Zhao Liu, Daniel P . Berrangé
From: Zhao Liu <zhao1.liu@intel.com>
Different versions of PC machine support different maximum vCPUs, and
even different features have limits on the maximum number of vCPUs (
For example, if x2apic is not enabled in the TCG case, the maximum of
255 vCPUs are supported).
It is difficult to list the maximum vCPUs under all restrictions. Thus,
to avoid confusion, avoid mentioning specific maximum vCPU number
limitations here.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240606085436.2028900-1-zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
docs/system/target-i386-desc.rst.inc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/system/target-i386-desc.rst.inc b/docs/system/target-i386-desc.rst.inc
index 319e540573d..ae312b1c1e6 100644
--- a/docs/system/target-i386-desc.rst.inc
+++ b/docs/system/target-i386-desc.rst.inc
@@ -36,7 +36,8 @@ The QEMU PC System emulator simulates the following peripherals:
- PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1
hub.
-SMP is supported with up to 255 CPUs (and 4096 CPUs for PC Q35 machine).
+SMP is supported with a large number of virtual CPUs (upper limit is
+configuration dependent).
QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
VGA BIOS.
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 38/42] i386: Fix MCE support for AMD hosts
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (36 preceding siblings ...)
2024-06-08 8:34 ` [PULL 37/42] docs: i386: pc: Avoid mentioning limit of maximum vCPUs Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 39/42] i386: Add support for SUCCOR feature Paolo Bonzini
` (4 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: John Allen, William Roche
From: John Allen <john.allen@amd.com>
For the most part, AMD hosts can use the same MCE injection code as Intel, but
there are instances where the qemu implementation is Intel specific. First, MCE
delivery works differently on AMD and does not support broadcast. Second,
kvm_mce_inject generates MCEs that include a number of Intel specific status
bits. Modify kvm_mce_inject to properly generate MCEs on AMD platforms.
Reported-by: William Roche <william.roche@oracle.com>
Signed-off-by: John Allen <john.allen@amd.com>
Message-ID: <20240603193622.47156-2-john.allen@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 2 ++
target/i386/helper.c | 4 ++++
target/i386/kvm/kvm.c | 39 +++++++++++++++++++++++++++++++--------
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 29d799adfd6..e6d5d1b483c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -377,6 +377,8 @@ typedef enum X86Seg {
#define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */
#define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */
#define MCI_STATUS_AR (1ULL<<55) /* Action required */
+#define MCI_STATUS_DEFERRED (1ULL<<44) /* Deferred error */
+#define MCI_STATUS_POISON (1ULL<<43) /* Poisoned data consumed */
/* MISC register defines */
#define MCM_ADDR_SEGOFF 0 /* segment offset */
diff --git a/target/i386/helper.c b/target/i386/helper.c
index f9d1381f90b..01a268a30bb 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -91,6 +91,10 @@ int cpu_x86_support_mca_broadcast(CPUX86State *env)
int family = 0;
int model = 0;
+ if (IS_AMD_CPU(env)) {
+ return 0;
+ }
+
cpu_x86_version(env, &family, &model);
if ((family == 6 && model >= 14) || family > 6) {
return 1;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index b5635209812..55a9e8a70cf 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -638,17 +638,40 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
{
CPUState *cs = CPU(cpu);
CPUX86State *env = &cpu->env;
- uint64_t status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN |
- MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S;
- uint64_t mcg_status = MCG_STATUS_MCIP;
+ uint64_t status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_MISCV |
+ MCI_STATUS_ADDRV;
+ uint64_t mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
int flags = 0;
- if (code == BUS_MCEERR_AR) {
- status |= MCI_STATUS_AR | 0x134;
- mcg_status |= MCG_STATUS_RIPV | MCG_STATUS_EIPV;
+ if (!IS_AMD_CPU(env)) {
+ status |= MCI_STATUS_S | MCI_STATUS_UC;
+ if (code == BUS_MCEERR_AR) {
+ status |= MCI_STATUS_AR | 0x134;
+ mcg_status |= MCG_STATUS_EIPV;
+ } else {
+ status |= 0xc0;
+ }
} else {
- status |= 0xc0;
- mcg_status |= MCG_STATUS_RIPV;
+ if (code == BUS_MCEERR_AR) {
+ status |= MCI_STATUS_UC | MCI_STATUS_POISON;
+ mcg_status |= MCG_STATUS_EIPV;
+ } else {
+ /* Setting the POISON bit for deferred errors indicates to the
+ * guest kernel that the address provided by the MCE is valid
+ * and usable which will ensure that the guest kernel will send
+ * a SIGBUS_AO signal to the guest process. This allows for
+ * more desirable behavior in the case that the guest process
+ * with poisoned memory has set the MCE_KILL_EARLY prctl flag
+ * which indicates that the process would prefer to handle or
+ * shutdown due to the poisoned memory condition before the
+ * memory has been accessed.
+ *
+ * While the POISON bit would not be set in a deferred error
+ * sent from hardware, the bit is not meaningful for deferred
+ * errors and can be reused in this scenario.
+ */
+ status |= MCI_STATUS_DEFERRED | MCI_STATUS_POISON;
+ }
}
flags = cpu_x86_support_mca_broadcast(env) ? MCE_INJECT_BROADCAST : 0;
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 39/42] i386: Add support for SUCCOR feature
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (37 preceding siblings ...)
2024-06-08 8:34 ` [PULL 38/42] i386: Fix MCE support for AMD hosts Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-13 9:50 ` Xiaoyao Li
2024-06-08 8:34 ` [PULL 40/42] i386: Add support for overflow recovery Paolo Bonzini
` (3 subsequent siblings)
42 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: John Allen, William Roche, Joao Martins
From: John Allen <john.allen@amd.com>
Add cpuid bit definition for the SUCCOR feature. This cpuid bit is required to
be exposed to guests to allow them to handle machine check exceptions on AMD
hosts.
----
v2:
- Add "succor" feature word.
- Add case to kvm_arch_get_supported_cpuid for the SUCCOR feature.
Reported-by: William Roche <william.roche@oracle.com>
Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: John Allen <john.allen@amd.com>
Message-ID: <20240603193622.47156-3-john.allen@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 4 ++++
target/i386/cpu.c | 18 +++++++++++++++++-
target/i386/kvm/kvm.c | 2 ++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e6d5d1b483c..6786055ec6b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -630,6 +630,7 @@ typedef enum FeatureWord {
FEAT_7_1_EAX, /* CPUID[EAX=7,ECX=1].EAX */
FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+ FEAT_8000_0007_EBX, /* CPUID[8000_0007].EBX */
FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
FEAT_8000_0021_EAX, /* CPUID[8000_0021].EAX */
@@ -982,6 +983,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
/* Packets which contain IP payload have LIP values */
#define CPUID_14_0_ECX_LIP (1U << 31)
+/* RAS Features */
+#define CPUID_8000_0007_EBX_SUCCOR (1U << 1)
+
/* CLZERO instruction */
#define CPUID_8000_0008_EBX_CLZERO (1U << 0)
/* Always save/restore FP error pointers */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 383230fa479..c5a532a254e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1180,6 +1180,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.tcg_features = TCG_APM_FEATURES,
.unmigratable_flags = CPUID_APM_INVTSC,
},
+ [FEAT_8000_0007_EBX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ NULL, "succor", NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ },
+ .cpuid = { .eax = 0x80000007, .reg = R_EBX, },
+ .tcg_features = 0,
+ .unmigratable_flags = 0,
+ },
[FEAT_8000_0008_EBX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
@@ -6887,7 +6903,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0x80000007:
*eax = 0;
- *ebx = 0;
+ *ebx = env->features[FEAT_8000_0007_EBX];
*ecx = 0;
*edx = env->features[FEAT_8000_0007_EDX];
break;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 55a9e8a70cf..56d8e2a89ec 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -532,6 +532,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
*/
cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
+ } else if (function == 0x80000007 && reg == R_EBX) {
+ ret |= CPUID_8000_0007_EBX_SUCCOR;
} else if (function == KVM_CPUID_FEATURES && reg == R_EAX) {
/* kvm_pv_unhalt is reported by GET_SUPPORTED_CPUID, but it can't
* be enabled without the in-kernel irqchip
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PULL 39/42] i386: Add support for SUCCOR feature
2024-06-08 8:34 ` [PULL 39/42] i386: Add support for SUCCOR feature Paolo Bonzini
@ 2024-06-13 9:50 ` Xiaoyao Li
2024-06-24 16:29 ` John Allen
2024-06-27 14:00 ` Paolo Bonzini
0 siblings, 2 replies; 50+ messages in thread
From: Xiaoyao Li @ 2024-06-13 9:50 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel; +Cc: John Allen, William Roche, Joao Martins
On 6/8/2024 4:34 PM, Paolo Bonzini wrote:
> From: John Allen <john.allen@amd.com>
>
> Add cpuid bit definition for the SUCCOR feature. This cpuid bit is required to
> be exposed to guests to allow them to handle machine check exceptions on AMD
> hosts.
>
> ----
> v2:
> - Add "succor" feature word.
> - Add case to kvm_arch_get_supported_cpuid for the SUCCOR feature.
>
> Reported-by: William Roche <william.roche@oracle.com>
> Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
> Signed-off-by: John Allen <john.allen@amd.com>
> Message-ID: <20240603193622.47156-3-john.allen@amd.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[snip]
...
> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> index 55a9e8a70cf..56d8e2a89ec 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -532,6 +532,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
> */
> cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
> ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
> + } else if (function == 0x80000007 && reg == R_EBX) {
> + ret |= CPUID_8000_0007_EBX_SUCCOR;
IMO, this is incorrect.
Why make it supported unconditionally? Shouldn't there be a KVM patch to
report it in KVM_GET_SUPPORTED_CPUID?
If make it supported unconditionally, all VMs boot with "-cpu host/max"
will see the CPUID bits, even if it is Intel VMs.
> } else if (function == KVM_CPUID_FEATURES && reg == R_EAX) {
> /* kvm_pv_unhalt is reported by GET_SUPPORTED_CPUID, but it can't
> * be enabled without the in-kernel irqchip
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PULL 39/42] i386: Add support for SUCCOR feature
2024-06-13 9:50 ` Xiaoyao Li
@ 2024-06-24 16:29 ` John Allen
2024-06-27 14:00 ` Paolo Bonzini
1 sibling, 0 replies; 50+ messages in thread
From: John Allen @ 2024-06-24 16:29 UTC (permalink / raw)
To: Xiaoyao Li, Paolo Bonzini; +Cc: qemu-devel, William Roche, Joao Martins
On Thu, Jun 13, 2024 at 05:50:08PM +0800, Xiaoyao Li wrote:
> On 6/8/2024 4:34 PM, Paolo Bonzini wrote:
> > From: John Allen <john.allen@amd.com>
> >
> > Add cpuid bit definition for the SUCCOR feature. This cpuid bit is required to
> > be exposed to guests to allow them to handle machine check exceptions on AMD
> > hosts.
> >
> > ----
> > v2:
> > - Add "succor" feature word.
> > - Add case to kvm_arch_get_supported_cpuid for the SUCCOR feature.
> >
> > Reported-by: William Roche <william.roche@oracle.com>
> > Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
> > Signed-off-by: John Allen <john.allen@amd.com>
> > Message-ID: <20240603193622.47156-3-john.allen@amd.com>
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> [snip]
> ...
>
> > diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> > index 55a9e8a70cf..56d8e2a89ec 100644
> > --- a/target/i386/kvm/kvm.c
> > +++ b/target/i386/kvm/kvm.c
> > @@ -532,6 +532,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
> > */
> > cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
> > ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
> > + } else if (function == 0x80000007 && reg == R_EBX) {
> > + ret |= CPUID_8000_0007_EBX_SUCCOR;
>
> IMO, this is incorrect.
>
> Why make it supported unconditionally? Shouldn't there be a KVM patch to
> report it in KVM_GET_SUPPORTED_CPUID?
>
> If make it supported unconditionally, all VMs boot with "-cpu host/max" will
> see the CPUID bits, even if it is Intel VMs.
Paolo,
This change in kvm_arch_get_supported_cpuid was added based on your
suggestion here:
https://lore.kernel.org/all/d4c1bb9b-8438-ed00-c79d-e8ad2a7e4eed@redhat.com/
Is there something missing from the patch needed to prevent the bits
from being seen on Intel VMs?
I am planning to send a patch early this week to report the bits for KVM
and a patch that removes the above change for qemu. Is there another way
you would prefer to handle it?
Thanks,
John
>
>
> > } else if (function == KVM_CPUID_FEATURES && reg == R_EAX) {
> > /* kvm_pv_unhalt is reported by GET_SUPPORTED_CPUID, but it can't
> > * be enabled without the in-kernel irqchip
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PULL 39/42] i386: Add support for SUCCOR feature
2024-06-13 9:50 ` Xiaoyao Li
2024-06-24 16:29 ` John Allen
@ 2024-06-27 14:00 ` Paolo Bonzini
1 sibling, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-27 14:00 UTC (permalink / raw)
To: Xiaoyao Li, qemu-devel; +Cc: John Allen, William Roche, Joao Martins
On 6/13/24 11:50, Xiaoyao Li wrote:
> On 6/8/2024 4:34 PM, Paolo Bonzini wrote:
>> From: John Allen <john.allen@amd.com>
>>
>> Add cpuid bit definition for the SUCCOR feature. This cpuid bit is
>> required to
>> be exposed to guests to allow them to handle machine check exceptions
>> on AMD
>> hosts.
>>
>> ----
>> v2:
>> - Add "succor" feature word.
>> - Add case to kvm_arch_get_supported_cpuid for the SUCCOR feature.
>>
>> Reported-by: William Roche <william.roche@oracle.com>
>> Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
>> Signed-off-by: John Allen <john.allen@amd.com>
>> Message-ID: <20240603193622.47156-3-john.allen@amd.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> [snip]
> ...
>
>> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
>> index 55a9e8a70cf..56d8e2a89ec 100644
>> --- a/target/i386/kvm/kvm.c
>> +++ b/target/i386/kvm/kvm.c
>> @@ -532,6 +532,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s,
>> uint32_t function,
>> */
>> cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
>> ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
>> + } else if (function == 0x80000007 && reg == R_EBX) {
>> + ret |= CPUID_8000_0007_EBX_SUCCOR;
>
> IMO, this is incorrect.
>
> Why make it supported unconditionally? Shouldn't there be a KVM patch to
> report it in KVM_GET_SUPPORTED_CPUID?
Yes, but since the bit doesn't need any hypervisor support it is common
to also add it in QEMU.
> If make it supported unconditionally, all VMs boot with "-cpu host/max"
> will see the CPUID bits, even if it is Intel VMs.
It should be harmless, but you're right, it's not tidy and we don't know
for sure that it doesn't trigger weird paths in guest OSes. I've send a
series to fix this.
Paolo
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PULL 40/42] i386: Add support for overflow recovery
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (38 preceding siblings ...)
2024-06-08 8:34 ` [PULL 39/42] i386: Add support for SUCCOR feature Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 41/42] Revert "python: use vendored tomli" Paolo Bonzini
` (2 subsequent siblings)
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel; +Cc: John Allen
From: John Allen <john.allen@amd.com>
Add cpuid bit definition for overflow recovery. This is needed in the case
where a deferred error has been sent to the guest, a guest process accesses the
poisoned memory, but the machine_check_poll function has not yet handled the
original deferred error. If overflow recovery is not set in this case, when we
handle the uncorrected error from the poisoned memory access, the overflow bit
will be set and will result in the guest being shut down.
By the time the MCE reaches the guest, the overflow has been handled
by the host and has not caused a shutdown, so include the bit unconditionally.
Signed-off-by: John Allen <john.allen@amd.com>
Message-ID: <20240603193622.47156-4-john.allen@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.h | 1 +
target/i386/cpu.c | 2 +-
target/i386/kvm/kvm.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 6786055ec6b..8fe28b67e0f 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -984,6 +984,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
#define CPUID_14_0_ECX_LIP (1U << 31)
/* RAS Features */
+#define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0)
#define CPUID_8000_0007_EBX_SUCCOR (1U << 1)
/* CLZERO instruction */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c5a532a254e..7466217d5ea 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1183,7 +1183,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_8000_0007_EBX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
- NULL, "succor", NULL, NULL,
+ "overflow-recov", "succor", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 56d8e2a89ec..912f5d5a6be 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -533,7 +533,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES;
} else if (function == 0x80000007 && reg == R_EBX) {
- ret |= CPUID_8000_0007_EBX_SUCCOR;
+ ret |= CPUID_8000_0007_EBX_OVERFLOW_RECOV | CPUID_8000_0007_EBX_SUCCOR;
} else if (function == KVM_CPUID_FEATURES && reg == R_EAX) {
/* kvm_pv_unhalt is reported by GET_SUPPORTED_CPUID, but it can't
* be enabled without the in-kernel irqchip
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 41/42] Revert "python: use vendored tomli"
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (39 preceding siblings ...)
2024-06-08 8:34 ` [PULL 40/42] i386: Add support for overflow recovery Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 8:34 ` [PULL 42/42] python: mkvenv: remove ensure command Paolo Bonzini
2024-06-08 20:19 ` [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Richard Henderson
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel
Now that Ubuntu 20.04 is not included anymore, there is no need to ship
it as part of QEMU; Ubuntu 22.04 includes it and Leap users anyway
need to install all the required dependencies from PyPI.
This mostly reverts commit ec77ee7634de123b7c899739711000fd21dab68b,
with just some changes to the wording.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
docs/devel/build-system.rst | 13 ++++++-------
configure | 4 ----
python/scripts/vendor.py | 3 ---
python/wheels/tomli-2.0.1-py3-none-any.whl | Bin 12757 -> 0 bytes
4 files changed, 6 insertions(+), 14 deletions(-)
delete mode 100644 python/wheels/tomli-2.0.1-py3-none-any.whl
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 09caf2f8e19..f4fd76117df 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -185,14 +185,13 @@ Bundled Python packages
Python packages that are **mandatory** dependencies to build QEMU,
but are not available in all supported distros, are bundled with the
-QEMU sources. Currently this includes Meson (outdated in CentOS 8
-and derivatives, Ubuntu 20.04 and 22.04, and openSUSE Leap) and tomli
-(absent in Ubuntu 20.04).
+QEMU sources. The only one is currently Meson (outdated in Ubuntu
+22.04 and openSUSE Leap).
-If you need to update these, please do so by modifying and rerunning
-``python/scripts/vendor.py``. This script embeds the sha256 hash of
-package sources and checks it. The pypi.org web site provides an easy
-way to retrieve the sha256 hash of the sources.
+In order to include a new or updated wheel, modify and rerun the
+``python/scripts/vendor.py`` script. The script embeds the
+sha256 hash of package sources and checks it. The pypi.org web site
+provides an easy way to retrieve the sha256 hash of the sources.
Stage 2: Meson
diff --git a/configure b/configure
index 4d01a42ba65..5ad1674ca5f 100755
--- a/configure
+++ b/configure
@@ -955,10 +955,6 @@ mkvenv="$python ${source_path}/python/scripts/mkvenv.py"
# Finish preparing the virtual environment using vendored .whl files
-if $python -c 'import sys; sys.exit(sys.version_info >= (3,11))'; then
- $mkvenv ensure --dir "${source_path}/python/wheels" \
- 'tomli>=1.2.0' || exit 1
-fi
$mkvenv ensuregroup --dir "${source_path}/python/wheels" \
${source_path}/pythondeps.toml meson || exit 1
diff --git a/python/scripts/vendor.py b/python/scripts/vendor.py
index 1038b14ae0c..07aff97ccad 100755
--- a/python/scripts/vendor.py
+++ b/python/scripts/vendor.py
@@ -43,9 +43,6 @@ def main() -> int:
packages = {
"meson==1.2.3":
"4533a43c34548edd1f63a276a42690fce15bde9409bcf20c4b8fa3d7e4d7cac1",
-
- "tomli==2.0.1":
- "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
}
vendor_dir = Path(__file__, "..", "..", "wheels").resolve()
diff --git a/python/wheels/tomli-2.0.1-py3-none-any.whl b/python/wheels/tomli-2.0.1-py3-none-any.whl
deleted file mode 100644
index 29670b98d16e2bc770d4fea718582e1dc0dd8aca..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 12757
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
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PULL 42/42] python: mkvenv: remove ensure command
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (40 preceding siblings ...)
2024-06-08 8:34 ` [PULL 41/42] Revert "python: use vendored tomli" Paolo Bonzini
@ 2024-06-08 8:34 ` Paolo Bonzini
2024-06-08 20:19 ` [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Richard Henderson
42 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2024-06-08 8:34 UTC (permalink / raw)
To: qemu-devel
This was used to bootstrap the venv with a TOML parser, after which
ensuregroup is used. Now that we expect it to be present as a system
package (either tomli or, for Python 3.11, tomllib), it is not needed
anymore.
Note that this means that, when implemented, the hypothetical "isolated"
mode that does not use any system packages will only work with Python
3.11+.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
python/scripts/mkvenv.py | 105 ---------------------------------------
1 file changed, 105 deletions(-)
diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index d0b9c215ca2..f2526af0a04 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -13,7 +13,6 @@
create create a venv
post_init
post-venv initialization
- ensure Ensure that the specified package is installed.
ensuregroup
Ensure that the specified package group is installed.
@@ -36,18 +35,6 @@
--------------------------------------------------
-usage: mkvenv ensure [-h] [--online] [--dir DIR] dep_spec...
-
-positional arguments:
- dep_spec PEP 508 Dependency specification, e.g. 'meson>=0.61.5'
-
-options:
- -h, --help show this help message and exit
- --online Install packages from PyPI, if necessary.
- --dir DIR Path to vendored packages where we may install from.
-
---------------------------------------------------
-
usage: mkvenv ensuregroup [-h] [--online] [--dir DIR] file group...
positional arguments:
@@ -726,57 +713,6 @@ def _do_ensure(
return None
-def ensure(
- dep_specs: Sequence[str],
- online: bool = False,
- wheels_dir: Optional[Union[str, Path]] = None,
- prog: Optional[str] = None,
-) -> None:
- """
- Use pip to ensure we have the package specified by @dep_specs.
-
- If the package is already installed, do nothing. If online and
- wheels_dir are both provided, prefer packages found in wheels_dir
- first before connecting to PyPI.
-
- :param dep_specs:
- PEP 508 dependency specifications. e.g. ['meson>=0.61.5'].
- :param online: If True, fall back to PyPI.
- :param wheels_dir: If specified, search this path for packages.
- :param prog:
- If specified, use this program name for error diagnostics that will
- be presented to the user. e.g., 'sphinx-build' can be used as a
- bellwether for the presence of 'sphinx'.
- """
-
- if not HAVE_DISTLIB:
- raise Ouch("a usable distlib could not be found, please install it")
-
- # Convert the depspecs to a dictionary, as if they came
- # from a section in a pythondeps.toml file
- group: Dict[str, Dict[str, str]] = {}
- for spec in dep_specs:
- name = distlib.version.LegacyMatcher(spec).name
- group[name] = {}
-
- spec = spec.strip()
- pos = len(name)
- ver = spec[pos:].strip()
- if ver:
- group[name]["accepted"] = ver
-
- if prog:
- group[name]["canary"] = prog
- prog = None
-
- result = _do_ensure(group, online, wheels_dir)
- if result:
- # Well, that's not good.
- if result[1]:
- raise Ouch(result[0])
- raise SystemExit(f"\n{result[0]}\n\n")
-
-
def _parse_groups(file: str) -> Dict[str, Dict[str, Any]]:
if not HAVE_TOMLLIB:
if sys.version_info < (3, 11):
@@ -888,39 +824,6 @@ def _add_ensuregroup_subcommand(subparsers: Any) -> None:
)
-def _add_ensure_subcommand(subparsers: Any) -> None:
- subparser = subparsers.add_parser(
- "ensure", help="Ensure that the specified package is installed."
- )
- subparser.add_argument(
- "--online",
- action="store_true",
- help="Install packages from PyPI, if necessary.",
- )
- subparser.add_argument(
- "--dir",
- type=str,
- action="store",
- help="Path to vendored packages where we may install from.",
- )
- subparser.add_argument(
- "--diagnose",
- type=str,
- action="store",
- help=(
- "Name of a shell utility to use for "
- "diagnostics if this command fails."
- ),
- )
- subparser.add_argument(
- "dep_specs",
- type=str,
- action="store",
- help="PEP 508 Dependency specification, e.g. 'meson>=0.61.5'",
- nargs="+",
- )
-
-
def main() -> int:
"""CLI interface to make_qemu_venv. See module docstring."""
if os.environ.get("DEBUG") or os.environ.get("GITLAB_CI"):
@@ -944,7 +847,6 @@ def main() -> int:
_add_create_subcommand(subparsers)
_add_post_init_subcommand(subparsers)
- _add_ensure_subcommand(subparsers)
_add_ensuregroup_subcommand(subparsers)
args = parser.parse_args()
@@ -957,13 +859,6 @@ def main() -> int:
)
if args.command == "post_init":
post_venv_setup()
- if args.command == "ensure":
- ensure(
- dep_specs=args.dep_specs,
- online=args.online,
- wheels_dir=args.dir,
- prog=args.diagnose,
- )
if args.command == "ensuregroup":
ensure_group(
file=args.file,
--
2.45.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08
2024-06-08 8:33 [PULL 00/42] i386, scsi. hostmem fixes for 2024-06-08 Paolo Bonzini
` (41 preceding siblings ...)
2024-06-08 8:34 ` [PULL 42/42] python: mkvenv: remove ensure command Paolo Bonzini
@ 2024-06-08 20:19 ` Richard Henderson
42 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2024-06-08 20:19 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
On 6/8/24 01:33, Paolo Bonzini wrote:
> The following changes since commit f1572ab94738bd5787b7badcd4bd93a3657f0680:
>
> Merge tag 'for-upstream' ofhttps://gitlab.com/bonzini/qemu into staging (2024-06-05 07:45:23 -0700)
>
> are available in the Git repository at:
>
> https://gitlab.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to fc00123f3abeb027cd51eb58ea8845377794b3bc:
>
> python: mkvenv: remove ensure command (2024-06-08 10:33:39 +0200)
>
> ----------------------------------------------------------------
> * scsi-disk: Don't silently truncate serial number
> * backends/hostmem: Report error on unavailable qemu_madvise() features or unaligned memory sizes
> * target/i386: fixes and documentation for INHIBIT_IRQ/TF/RF and debugging
> * i386/hvf: Adds support for INVTSC cpuid bit
> * i386/hvf: Fixes for dirty memory tracking
> * i386/hvf: Use hv_vcpu_interrupt() and hv_vcpu_run_until()
> * hvf: Cleanups
> * stubs: fixes for --disable-system build
> * i386/kvm: support for FRED
> * i386/kvm: fix MCE handling on AMD hosts
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/9.1 as appropriate.
r~
^ permalink raw reply [flat|nested] 50+ messages in thread