All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] target/i386/mshv: Fix segment regression in MMIO emu
@ 2026-04-10 14:26 Magnus Kulke
  2026-04-10 16:19 ` Mohamed Mediouni
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Magnus Kulke @ 2026-04-10 14:26 UTC (permalink / raw)
  To: qemu-devel
  Cc: Magnus Kulke, Doru Blânzeanu, Magnus Kulke, Mohamed Mediouni,
	Wei Liu, Wei Liu

When the segmentation code has been reworked, there is now an
unconditional call to emul_ops->read_segment_descriptor(). The MSHV impl
was delegating this to x86_read_segement_descriptor(), which read from
the GDT in guest memory. This fails for selector.idx == 0 and when no
GDT is set up (which is the case in real mode).

In the fix we change the MSHV impl to fill segment descriptor from
SegmentCache, that was populated from the hypervisor by mshv_load_regs()
before instruction emulation.

Fixes: 09442d98ab (target/i386: emulate: segmentation rework)

Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
---
 target/i386/mshv/mshv-cpu.c | 39 ++++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 2bc978deb2..4ed6e7548f 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1552,17 +1552,42 @@ static void read_segment_descriptor(CPUState *cpu,
                                     struct x86_segment_descriptor *desc,
                                     enum X86Seg seg_idx)
 {
-    bool ret;
     X86CPU *x86_cpu = X86_CPU(cpu);
     CPUX86State *env = &x86_cpu->env;
     SegmentCache *seg = &env->segs[seg_idx];
-    x86_segment_selector sel = { .sel = seg->selector & 0xFFFF };
-
-    ret = x86_read_segment_descriptor(cpu, desc, sel);
-    if (ret == false) {
-        error_report("failed to read segment descriptor");
-        abort();
+    uint32_t limit;
+
+    memset(desc, 0, sizeof(struct x86_segment_descriptor));
+
+    desc->type = (seg->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT;
+    desc->s    = (seg->flags & DESC_S_MASK)    >> DESC_S_SHIFT;
+    desc->dpl  = (seg->flags & DESC_DPL_MASK)  >> DESC_DPL_SHIFT;
+    desc->p    = (seg->flags & DESC_P_MASK)    >> DESC_P_SHIFT;
+    desc->avl  = (seg->flags & DESC_AVL_MASK)  >> DESC_AVL_SHIFT;
+    desc->l    = (seg->flags & DESC_L_MASK)    >> DESC_L_SHIFT;
+    desc->db   = (seg->flags & DESC_B_MASK)    >> DESC_B_SHIFT;
+    desc->g    = (seg->flags & DESC_G_MASK)    >> DESC_G_SHIFT;
+
+    /*
+     * SegmentCache stores the hypervisor-provided value verbatim (populated by
+     * mshv_load_regs). We need to convert it to format expected by the
+     * instruction emulator. We can have a limit value > 0xfffff with
+     * granularity of 0 (byte granularity), which is not representable
+     * in real x86_segment_descriptor. In this case we set granularity to 1
+     * (4k granularity) and shift the limit accordingly.
+     *
+     * This quirk has been adopted from "whpx_segment_to_x86_description()"
+     */
+
+    if (!desc->g && seg->limit <= 0xfffff) {
+        limit = seg->limit;
+    } else {
+        limit = seg->limit >> 12;
+        desc->g = 1;
     }
+
+    x86_set_segment_limit(desc, limit);
+    x86_set_segment_base(desc, seg->base);
 }
 
 static const struct x86_emul_ops mshv_x86_emul_ops = {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] target/i386/mshv: Fix segment regression in MMIO emu
  2026-04-10 14:26 [PATCH] target/i386/mshv: Fix segment regression in MMIO emu Magnus Kulke
@ 2026-04-10 16:19 ` Mohamed Mediouni
  2026-04-11 12:26 ` Paolo Bonzini
  2026-04-24 21:35 ` Michael Tokarev
  2 siblings, 0 replies; 5+ messages in thread
From: Mohamed Mediouni @ 2026-04-10 16:19 UTC (permalink / raw)
  To: Magnus Kulke
  Cc: qemu-devel, Magnus Kulke, Doru Blânzeanu, Wei Liu, Wei Liu



> On 10. Apr 2026, at 16:26, Magnus Kulke <magnuskulke@linux.microsoft.com> wrote:
> 
> When the segmentation code has been reworked, there is now an
> unconditional call to emul_ops->read_segment_descriptor(). The MSHV impl
> was delegating this to x86_read_segement_descriptor(), which read from
> the GDT in guest memory. This fails for selector.idx == 0 and when no
> GDT is set up (which is the case in real mode).
> 
> In the fix we change the MSHV impl to fill segment descriptor from
> SegmentCache, that was populated from the hypervisor by mshv_load_regs()
> before instruction emulation.
> 
> Fixes: 09442d98ab (target/i386: emulate: segmentation rework)
> 
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr>

> ---
> target/i386/mshv/mshv-cpu.c | 39 ++++++++++++++++++++++++++++++-------
> 1 file changed, 32 insertions(+), 7 deletions(-)
> 
> diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
> index 2bc978deb2..4ed6e7548f 100644
> --- a/target/i386/mshv/mshv-cpu.c
> +++ b/target/i386/mshv/mshv-cpu.c
> @@ -1552,17 +1552,42 @@ static void read_segment_descriptor(CPUState *cpu,
>                                     struct x86_segment_descriptor *desc,
>                                     enum X86Seg seg_idx)
> {
> -    bool ret;
>     X86CPU *x86_cpu = X86_CPU(cpu);
>     CPUX86State *env = &x86_cpu->env;
>     SegmentCache *seg = &env->segs[seg_idx];
> -    x86_segment_selector sel = { .sel = seg->selector & 0xFFFF };
> -
> -    ret = x86_read_segment_descriptor(cpu, desc, sel);
> -    if (ret == false) {
> -        error_report("failed to read segment descriptor");
> -        abort();
> +    uint32_t limit;
> +
> +    memset(desc, 0, sizeof(struct x86_segment_descriptor));
> +
> +    desc->type = (seg->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT;
> +    desc->s    = (seg->flags & DESC_S_MASK)    >> DESC_S_SHIFT;
> +    desc->dpl  = (seg->flags & DESC_DPL_MASK)  >> DESC_DPL_SHIFT;
> +    desc->p    = (seg->flags & DESC_P_MASK)    >> DESC_P_SHIFT;
> +    desc->avl  = (seg->flags & DESC_AVL_MASK)  >> DESC_AVL_SHIFT;
> +    desc->l    = (seg->flags & DESC_L_MASK)    >> DESC_L_SHIFT;
> +    desc->db   = (seg->flags & DESC_B_MASK)    >> DESC_B_SHIFT;
> +    desc->g    = (seg->flags & DESC_G_MASK)    >> DESC_G_SHIFT;
> +
> +    /*
> +     * SegmentCache stores the hypervisor-provided value verbatim (populated by
> +     * mshv_load_regs). We need to convert it to format expected by the
> +     * instruction emulator. We can have a limit value > 0xfffff with
> +     * granularity of 0 (byte granularity), which is not representable
> +     * in real x86_segment_descriptor. In this case we set granularity to 1
> +     * (4k granularity) and shift the limit accordingly.
> +     *
> +     * This quirk has been adopted from "whpx_segment_to_x86_description()"
> +     */
> +
> +    if (!desc->g && seg->limit <= 0xfffff) {
> +        limit = seg->limit;
> +    } else {
> +        limit = seg->limit >> 12;
> +        desc->g = 1;
>     }
> +
> +    x86_set_segment_limit(desc, limit);
> +    x86_set_segment_base(desc, seg->base);
> }
> 
> static const struct x86_emul_ops mshv_x86_emul_ops = {
> -- 
> 2.34.1
> 
> 



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] target/i386/mshv: Fix segment regression in MMIO emu
  2026-04-10 14:26 [PATCH] target/i386/mshv: Fix segment regression in MMIO emu Magnus Kulke
  2026-04-10 16:19 ` Mohamed Mediouni
@ 2026-04-11 12:26 ` Paolo Bonzini
  2026-04-24 21:35 ` Michael Tokarev
  2 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2026-04-11 12:26 UTC (permalink / raw)
  To: Magnus Kulke
  Cc: qemu-devel, Magnus Kulke, Doru Blânzeanu, Mohamed Mediouni,
	Wei Liu, Wei Liu

Queued, thanks.

Paolo



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] target/i386/mshv: Fix segment regression in MMIO emu
  2026-04-10 14:26 [PATCH] target/i386/mshv: Fix segment regression in MMIO emu Magnus Kulke
  2026-04-10 16:19 ` Mohamed Mediouni
  2026-04-11 12:26 ` Paolo Bonzini
@ 2026-04-24 21:35 ` Michael Tokarev
  2026-04-25  8:10   ` Magnus Kulke
  2 siblings, 1 reply; 5+ messages in thread
From: Michael Tokarev @ 2026-04-24 21:35 UTC (permalink / raw)
  To: Magnus Kulke, qemu-devel
  Cc: Magnus Kulke, Doru Blânzeanu, Mohamed Mediouni, Wei Liu,
	Wei Liu, Paolo Bonzini, qemu-stable

On 10.04.2026 17:26, Magnus Kulke wrote:
> When the segmentation code has been reworked, there is now an
> unconditional call to emul_ops->read_segment_descriptor(). The MSHV impl
> was delegating this to x86_read_segement_descriptor(), which read from
> the GDT in guest memory. This fails for selector.idx == 0 and when no
> GDT is set up (which is the case in real mode).
> 
> In the fix we change the MSHV impl to fill segment descriptor from
> SegmentCache, that was populated from the hypervisor by mshv_load_regs()
> before instruction emulation.
> 
> Fixes: 09442d98ab (target/i386: emulate: segmentation rework)
> 
> Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> ---
>   target/i386/mshv/mshv-cpu.c | 39 ++++++++++++++++++++++++++++++-------
>   1 file changed, 32 insertions(+), 7 deletions(-)

This looks like a qemu-stable material (11.0.x).

Please let me know if it isn't.

Thanks,

/mjt



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] target/i386/mshv: Fix segment regression in MMIO emu
  2026-04-24 21:35 ` Michael Tokarev
@ 2026-04-25  8:10   ` Magnus Kulke
  0 siblings, 0 replies; 5+ messages in thread
From: Magnus Kulke @ 2026-04-25  8:10 UTC (permalink / raw)
  To: Michael Tokarev
  Cc: qemu-devel, Magnus Kulke, Doru Blânzeanu, Mohamed Mediouni,
	Wei Liu, Wei Liu, Paolo Bonzini, qemu-stable

On Sat, Apr 25, 2026 at 12:35:27AM +0300, Michael Tokarev wrote:
> On 10.04.2026 17:26, Magnus Kulke wrote:
> > When the segmentation code has been reworked, there is now an
> > unconditional call to emul_ops->read_segment_descriptor(). The MSHV impl
> > was delegating this to x86_read_segement_descriptor(), which read from
> > the GDT in guest memory. This fails for selector.idx == 0 and when no
> > GDT is set up (which is the case in real mode).
> > 
> > In the fix we change the MSHV impl to fill segment descriptor from
> > SegmentCache, that was populated from the hypervisor by mshv_load_regs()
> > before instruction emulation.
> > 
> > Fixes: 09442d98ab (target/i386: emulate: segmentation rework)
> > 
> > Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
> > ---
> >   target/i386/mshv/mshv-cpu.c | 39 ++++++++++++++++++++++++++++++-------
> >   1 file changed, 32 insertions(+), 7 deletions(-)
> 
> This looks like a qemu-stable material (11.0.x).
> 
> Please let me know if it isn't.
> 
> Thanks,
> 
> /mjt

I think so, yes. real mode mmio-emu will not work, which affects pretty
much all (x86) workloads for mshv.

best,

magnus


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-04-25  8:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-10 14:26 [PATCH] target/i386/mshv: Fix segment regression in MMIO emu Magnus Kulke
2026-04-10 16:19 ` Mohamed Mediouni
2026-04-11 12:26 ` Paolo Bonzini
2026-04-24 21:35 ` Michael Tokarev
2026-04-25  8:10   ` Magnus Kulke

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.