x86emul: split off opcode 0fae handling

There's a fair amount of sub-cases (with some yet to be implemented), so
a separate function seems warranted.

Code moved gets slightly adjusted in a few places, e.g. replacing EXC_*
by X86_EXC_* (such that EXC_* don't need to move as well; we want these
to be phased out anyway).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
Jan Beulich committed 2023-04-03 12:42:44 +02:00
1 parent 9ace97ab9b
commit 3e957de632
6 files changed
+315 -238

No files matched your search

+1 -1
View File
@@ -32,7 +32,7 @@ GCOV_FLAGS := --coverage
$(CC) -c $(CFLAGS) $(GCOV_FLAGS) $< -o $@
OBJS := fuzz-emul.o x86-emulate.o
OBJS += x86_emulate/0f01.o
OBJS += x86_emulate/0f01.o x86_emulate/0fae.o
x86-emulate.h: x86_emulate/x86_emulate.h
x86-emulate.o x86-emulate-cov.o: x86-emulate.h x86_emulate/x86_emulate.c x86_emulate/private.h
+1 -1
View File
@@ -251,7 +251,7 @@ xop.h avx512f.h: simd-fma.c
endif # 32-bit override
OBJS := x86-emulate.o cpuid.o test_x86_emulator.o evex-disp8.o predicates.o wrappers.o
OBJS += x86_emulate/0f01.o
OBJS += x86_emulate/0f01.o x86_emulate/0fae.o
$(TARGET): $(OBJS)
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
+222
View File
@@ -0,0 +1,222 @@
/******************************************************************************
* 0fae.c - helper for x86_emulate.c
*
* Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see <http://www.gnu.org/licenses/>.
*/
#include "private.h"
#if defined(__XEN__) && \
(!defined(X86EMUL_NO_FPU) || !defined(X86EMUL_NO_MMX) || \
!defined(X86EMUL_NO_SIMD))
# include <asm/xstate.h>
#endif
int x86emul_0fae(struct x86_emulate_state *s,
struct cpu_user_regs *regs,
struct operand *dst,
const struct operand *src,
struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops,
enum x86_emulate_fpu_type *fpu_type)
#define fpu_type (*fpu_type) /* for get_fpu() */
{
unsigned long cr4;
int rc;
if ( !s->vex.opcx && (!s->vex.pfx || s->vex.pfx == vex_66) )
{
switch ( s->modrm_reg & 7 )
{
#if !defined(X86EMUL_NO_FPU) || !defined(X86EMUL_NO_MMX) || \
!defined(X86EMUL_NO_SIMD)
case 0: /* fxsave */
case 1: /* fxrstor */
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(fxsr);
generate_exception_if(s->ea.type != OP_MEM, X86_EXC_UD);
generate_exception_if(!is_aligned(s->ea.mem.seg, s->ea.mem.off, 16,
ctxt, ops),
X86_EXC_GP, 0);
fail_if(!ops->blk);
s->op_bytes =
#ifdef __x86_64__
!mode_64bit() ? offsetof(struct x86_fxsr, xmm[8]) :
#endif
sizeof(struct x86_fxsr);
if ( amd_like(ctxt) )
{
uint64_t msr_val;
/* Assume "normal" operation in case of missing hooks. */
if ( !ops->read_cr ||
ops->read_cr(4, &cr4, ctxt) != X86EMUL_OKAY )
cr4 = X86_CR4_OSFXSR;
if ( !ops->read_msr ||
ops->read_msr(MSR_EFER, &msr_val, ctxt) != X86EMUL_OKAY )
msr_val = 0;
if ( !(cr4 & X86_CR4_OSFXSR) ||
(mode_64bit() && mode_ring0() && (msr_val & EFER_FFXSE)) )
s->op_bytes = offsetof(struct x86_fxsr, xmm[0]);
}
/*
* This could also be X86EMUL_FPU_mmx, but it shouldn't be
* X86EMUL_FPU_xmm, as we don't want CR4.OSFXSR checked.
*/
get_fpu(X86EMUL_FPU_fpu);
s->fpu_ctrl = true;
s->blk = s->modrm_reg & 1 ? blk_fxrstor : blk_fxsave;
if ( (rc = ops->blk(s->ea.mem.seg, s->ea.mem.off, NULL,
sizeof(struct x86_fxsr), &regs->eflags,
s, ctxt)) != X86EMUL_OKAY )
goto done;
break;
#endif /* X86EMUL_NO_{FPU,MMX,SIMD} */
#ifndef X86EMUL_NO_SIMD
case 2: /* ldmxcsr */
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(sse);
ldmxcsr:
generate_exception_if(src->type != OP_MEM, X86_EXC_UD);
get_fpu(s->vex.opcx ? X86EMUL_FPU_ymm : X86EMUL_FPU_xmm);
generate_exception_if(src->val & ~mxcsr_mask, X86_EXC_GP, 0);
asm volatile ( "ldmxcsr %0" :: "m" (src->val) );
break;
case 3: /* stmxcsr */
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(sse);
stmxcsr:
generate_exception_if(dst->type != OP_MEM, X86_EXC_UD);
get_fpu(s->vex.opcx ? X86EMUL_FPU_ymm : X86EMUL_FPU_xmm);
asm volatile ( "stmxcsr %0" : "=m" (dst->val) );
break;
#endif /* X86EMUL_NO_SIMD */
case 5: /* lfence */
fail_if(s->modrm_mod != 3);
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(sse2);
asm volatile ( "lfence" ::: "memory" );
break;
case 6:
if ( s->modrm_mod == 3 ) /* mfence */
{
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(sse2);
asm volatile ( "mfence" ::: "memory" );
break;
}
/* else clwb */
fail_if(!s->vex.pfx);
vcpu_must_have(clwb);
fail_if(!ops->cache_op);
if ( (rc = ops->cache_op(x86emul_clwb, s->ea.mem.seg, s->ea.mem.off,
ctxt)) != X86EMUL_OKAY )
goto done;
break;
case 7:
if ( s->modrm_mod == 3 ) /* sfence */
{
generate_exception_if(s->vex.pfx, X86_EXC_UD);
vcpu_must_have(mmxext);
asm volatile ( "sfence" ::: "memory" );
break;
}
/* else clflush{,opt} */
if ( !s->vex.pfx )
vcpu_must_have(clflush);
else
vcpu_must_have(clflushopt);
fail_if(!ops->cache_op);
if ( (rc = ops->cache_op(s->vex.pfx ? x86emul_clflushopt
: x86emul_clflush,
s->ea.mem.seg, s->ea.mem.off,
ctxt)) != X86EMUL_OKAY )
goto done;
break;
default:
return X86EMUL_UNIMPLEMENTED;
}
}
#ifndef X86EMUL_NO_SIMD
else if ( s->vex.opcx && !s->vex.pfx )
{
switch ( s->modrm_reg & 7 )
{
case 2: /* vldmxcsr */
generate_exception_if(s->vex.l || s->vex.reg != 0xf, X86_EXC_UD);
vcpu_must_have(avx);
goto ldmxcsr;
case 3: /* vstmxcsr */
generate_exception_if(s->vex.l || s->vex.reg != 0xf, X86_EXC_UD);
vcpu_must_have(avx);
goto stmxcsr;
}
return X86EMUL_UNRECOGNIZED;
}
#endif /* !X86EMUL_NO_SIMD */
else if ( !s->vex.opcx && s->vex.pfx == vex_f3 )
{
enum x86_segment seg;
struct segment_register sreg;
fail_if(s->modrm_mod != 3);
generate_exception_if((s->modrm_reg & 4) || !mode_64bit(), X86_EXC_UD);
fail_if(!ops->read_cr);
if ( (rc = ops->read_cr(4, &cr4, ctxt)) != X86EMUL_OKAY )
goto done;
generate_exception_if(!(cr4 & X86_CR4_FSGSBASE), X86_EXC_UD);
seg = s->modrm_reg & 1 ? x86_seg_gs : x86_seg_fs;
fail_if(!ops->read_segment);
if ( (rc = ops->read_segment(seg, &sreg, ctxt)) != X86EMUL_OKAY )
goto done;
dst->reg = decode_gpr(regs, s->modrm_rm);
if ( !(s->modrm_reg & 2) )
{
/* rd{f,g}sbase */
dst->type = OP_REG;
dst->bytes = (s->op_bytes == 8) ? 8 : 4;
dst->val = sreg.base;
}
else
{
/* wr{f,g}sbase */
if ( s->op_bytes == 8 )
{
sreg.base = *dst->reg;
generate_exception_if(!is_canonical_address(sreg.base),
X86_EXC_GP, 0);
}
else
sreg.base = (uint32_t)*dst->reg;
fail_if(!ops->write_segment);
if ( (rc = ops->write_segment(seg, &sreg, ctxt)) != X86EMUL_OKAY )
goto done;
}
}
else
{
ASSERT_UNREACHABLE();
return X86EMUL_UNRECOGNIZED;
}
rc = X86EMUL_OKAY;
done:
return rc;
}
+1
View File
@@ -1 +1,2 @@
obj-y += 0f01.o
obj-y += 0fae.o
+77
View File
@@ -22,6 +22,7 @@
# include <xen/kernel.h>
# include <asm/msr-index.h>
# include <asm/x86-vendors.h>
# include <asm/x86_emulate.h>
# ifndef CONFIG_HVM
@@ -308,6 +309,29 @@ struct x86_emulate_state {
#endif
};
struct x86_fxsr {
uint16_t fcw;
uint16_t fsw;
uint8_t ftw, :8;
uint16_t fop;
union {
struct {
uint32_t offs;
uint16_t sel, :16;
};
uint64_t addr;
} fip, fdp;
uint32_t mxcsr;
uint32_t mxcsr_mask;
struct {
uint8_t data[10];
uint16_t :16, :16, :16;
} fpreg[8];
uint64_t __attribute__ ((aligned(16))) xmm[16][2];
uint64_t rsvd[6];
uint64_t avl[6];
};
/*
* Externally visible return codes from x86_emulate() are non-negative.
* Use negative values for internal state change indicators from helpers
@@ -397,6 +421,18 @@ in_protmode(
(_cpl == 0); \
})
static inline bool
_amd_like(const struct cpuid_policy *cp)
{
return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
}
static inline bool
amd_like(const struct x86_emulate_ctxt *ctxt)
{
return _amd_like(ctxt->cpuid);
}
#define vcpu_has_fpu() (ctxt->cpuid->basic.fpu)
#define vcpu_has_sep() (ctxt->cpuid->basic.sep)
#define vcpu_has_cx8() (ctxt->cpuid->basic.cx8)
@@ -502,11 +538,52 @@ in_protmode(
int x86emul_get_cpl(struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops);
int x86emul_get_fpu(enum x86_emulate_fpu_type type,
struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops);
#define get_fpu(type) \
do { \
rc = x86emul_get_fpu(fpu_type = (type), ctxt, ops); \
if ( rc ) goto done; \
} while (0)
int x86emul_0f01(struct x86_emulate_state *s,
struct cpu_user_regs *regs,
struct operand *dst,
struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops);
int x86emul_0fae(struct x86_emulate_state *s,
struct cpu_user_regs *regs,
struct operand *dst,
const struct operand *src,
struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops,
enum x86_emulate_fpu_type *fpu_type);
static inline bool is_aligned(enum x86_segment seg, unsigned long offs,
unsigned int size, struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops)
{
struct segment_register reg;
/* Expecting powers of two only. */
ASSERT(!(size & (size - 1)));
if ( mode_64bit() && seg < x86_seg_fs )
memset(&reg, 0, sizeof(reg));
else
{
/* No alignment checking when we have no way to read segment data. */
if ( !ops->read_segment )
return true;
if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
return false;
}
return !((reg.base + offs) & (size - 1));
}
static inline bool umip_active(struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops)
+13 -236
View File
@@ -695,29 +695,6 @@ typedef union {
uint32_t data32[16];
} mmval_t;
struct x86_fxsr {
uint16_t fcw;
uint16_t fsw;
uint8_t ftw, :8;
uint16_t fop;
union {
struct {
uint32_t offs;
uint16_t sel, :16;
};
uint64_t addr;
} fip, fdp;
uint32_t mxcsr;
uint32_t mxcsr_mask;
struct {
uint8_t data[10];
uint16_t :16, :16, :16;
} fpreg[8];
uint64_t __attribute__ ((aligned(16))) xmm[16][2];
uint64_t rsvd[6];
uint64_t avl[6];
};
/*
* While proper alignment gets specified above, this doesn't get honored by
* the compiler for automatic variables. Use this helper to instantiate a
@@ -1063,7 +1040,7 @@ do { \
ops->write_segment(x86_seg_cs, cs, ctxt); \
})
static int _get_fpu(
int x86emul_get_fpu(
enum x86_emulate_fpu_type type,
struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops)
@@ -1102,7 +1079,7 @@ static int _get_fpu(
break;
}
rc = ops->get_fpu(type, ctxt);
rc = (ops->get_fpu)(type, ctxt);
if ( rc == X86EMUL_OKAY )
{
@@ -1146,12 +1123,6 @@ static int _get_fpu(
return rc;
}
#define get_fpu(type) \
do { \
rc = _get_fpu(fpu_type = (type), ctxt, ops); \
if ( rc ) goto done; \
} while (0)
static void put_fpu(
enum x86_emulate_fpu_type type,
bool failed_late,
@@ -1556,18 +1527,6 @@ static int ioport_access_check(
return rc;
}
static bool
_amd_like(const struct cpuid_policy *cp)
{
return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
}
static bool
amd_like(const struct x86_emulate_ctxt *ctxt)
{
return _amd_like(ctxt->cpuid);
}
/* Initialise output state in x86_emulate_ctxt */
static void init_context(struct x86_emulate_ctxt *ctxt)
{
@@ -1980,30 +1939,6 @@ static unsigned int decode_disp8scale(enum disp8scale scale,
} \
} while ( false )
static bool is_aligned(enum x86_segment seg, unsigned long offs,
unsigned int size, struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops)
{
struct segment_register reg;
/* Expecting powers of two only. */
ASSERT(!(size & (size - 1)));
if ( mode_64bit() && seg < x86_seg_fs )
memset(&reg, 0, sizeof(reg));
else
{
/* No alignment checking when we have no way to read segment data. */
if ( !ops->read_segment )
return true;
if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
return false;
}
return !((reg.base + offs) & (size - 1));
}
static bool is_branch_step(struct x86_emulate_ctxt *ctxt,
const struct x86_emulate_ops *ops)
{
@@ -3346,7 +3281,8 @@ x86_emulate(
#ifndef X86EMUL_NO_SIMD
/* With a memory operand, fetch the mask register in use (if any). */
if ( ea.type == OP_MEM && evex.opmsk &&
_get_fpu(fpu_type = X86EMUL_FPU_opmask, ctxt, ops) == X86EMUL_OKAY )
x86emul_get_fpu(fpu_type = X86EMUL_FPU_opmask,
ctxt, ops) == X86EMUL_OKAY )
{
uint8_t *stb = get_stub(stub);
@@ -3369,7 +3305,7 @@ x86_emulate(
if ( fpu_type == X86EMUL_FPU_opmask )
{
/* Squash (side) effects of the _get_fpu() above. */
/* Squash (side) effects of the x86emul_get_fpu() above. */
x86_emul_reset_event(ctxt);
put_fpu(X86EMUL_FPU_opmask, false, state, ctxt, ops);
fpu_type = X86EMUL_FPU_none;
@@ -7435,173 +7371,14 @@ x86_emulate(
emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
break;
case X86EMUL_OPC(0x0f, 0xae): case X86EMUL_OPC_66(0x0f, 0xae): /* Grp15 */
switch ( modrm_reg & 7 )
{
#if !defined(X86EMUL_NO_FPU) || !defined(X86EMUL_NO_MMX) || \
!defined(X86EMUL_NO_SIMD)
case 0: /* fxsave */
case 1: /* fxrstor */
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(fxsr);
generate_exception_if(ea.type != OP_MEM, EXC_UD);
generate_exception_if(!is_aligned(ea.mem.seg, ea.mem.off, 16,
ctxt, ops),
EXC_GP, 0);
fail_if(!ops->blk);
op_bytes =
#ifdef __x86_64__
!mode_64bit() ? offsetof(struct x86_fxsr, xmm[8]) :
case X86EMUL_OPC(0x0f, 0xae): /* Grp15 */
case X86EMUL_OPC_66(0x0f, 0xae):
case X86EMUL_OPC_F3(0x0f, 0xae):
#ifndef X86EMUL_NO_SIMD
case X86EMUL_OPC_VEX(0x0f, 0xae):
#endif
sizeof(struct x86_fxsr);
if ( amd_like(ctxt) )
{
/* Assume "normal" operation in case of missing hooks. */
if ( !ops->read_cr ||
ops->read_cr(4, &cr4, ctxt) != X86EMUL_OKAY )
cr4 = X86_CR4_OSFXSR;
if ( !ops->read_msr ||
ops->read_msr(MSR_EFER, &msr_val, ctxt) != X86EMUL_OKAY )
msr_val = 0;
if ( !(cr4 & X86_CR4_OSFXSR) ||
(mode_64bit() && mode_ring0() && (msr_val & EFER_FFXSE)) )
op_bytes = offsetof(struct x86_fxsr, xmm[0]);
}
/*
* This could also be X86EMUL_FPU_mmx, but it shouldn't be
* X86EMUL_FPU_xmm, as we don't want CR4.OSFXSR checked.
*/
get_fpu(X86EMUL_FPU_fpu);
state->fpu_ctrl = true;
state->blk = modrm_reg & 1 ? blk_fxrstor : blk_fxsave;
if ( (rc = ops->blk(ea.mem.seg, ea.mem.off, NULL,
sizeof(struct x86_fxsr), &_regs.eflags,
state, ctxt)) != X86EMUL_OKAY )
goto done;
break;
#endif /* X86EMUL_NO_{FPU,MMX,SIMD} */
#ifndef X86EMUL_NO_SIMD
case 2: /* ldmxcsr */
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(sse);
ldmxcsr:
generate_exception_if(src.type != OP_MEM, EXC_UD);
get_fpu(vex.opcx ? X86EMUL_FPU_ymm : X86EMUL_FPU_xmm);
generate_exception_if(src.val & ~mxcsr_mask, EXC_GP, 0);
asm volatile ( "ldmxcsr %0" :: "m" (src.val) );
break;
case 3: /* stmxcsr */
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(sse);
stmxcsr:
generate_exception_if(dst.type != OP_MEM, EXC_UD);
get_fpu(vex.opcx ? X86EMUL_FPU_ymm : X86EMUL_FPU_xmm);
asm volatile ( "stmxcsr %0" : "=m" (dst.val) );
break;
#endif /* X86EMUL_NO_SIMD */
case 5: /* lfence */
fail_if(modrm_mod != 3);
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(sse2);
asm volatile ( "lfence" ::: "memory" );
break;
case 6:
if ( modrm_mod == 3 ) /* mfence */
{
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(sse2);
asm volatile ( "mfence" ::: "memory" );
break;
}
/* else clwb */
fail_if(!vex.pfx);
vcpu_must_have(clwb);
fail_if(!ops->cache_op);
if ( (rc = ops->cache_op(x86emul_clwb, ea.mem.seg, ea.mem.off,
ctxt)) != X86EMUL_OKAY )
goto done;
break;
case 7:
if ( modrm_mod == 3 ) /* sfence */
{
generate_exception_if(vex.pfx, EXC_UD);
vcpu_must_have(mmxext);
asm volatile ( "sfence" ::: "memory" );
break;
}
/* else clflush{,opt} */
if ( !vex.pfx )
vcpu_must_have(clflush);
else
vcpu_must_have(clflushopt);
fail_if(!ops->cache_op);
if ( (rc = ops->cache_op(vex.pfx ? x86emul_clflushopt
: x86emul_clflush,
ea.mem.seg, ea.mem.off,
ctxt)) != X86EMUL_OKAY )
goto done;
break;
default:
goto unimplemented_insn;
}
break;
#ifndef X86EMUL_NO_SIMD
case X86EMUL_OPC_VEX(0x0f, 0xae): /* Grp15 */
switch ( modrm_reg & 7 )
{
case 2: /* vldmxcsr */
generate_exception_if(vex.l || vex.reg != 0xf, EXC_UD);
vcpu_must_have(avx);
goto ldmxcsr;
case 3: /* vstmxcsr */
generate_exception_if(vex.l || vex.reg != 0xf, EXC_UD);
vcpu_must_have(avx);
goto stmxcsr;
}
goto unrecognized_insn;
#endif /* !X86EMUL_NO_SIMD */
case X86EMUL_OPC_F3(0x0f, 0xae): /* Grp15 */
fail_if(modrm_mod != 3);
generate_exception_if((modrm_reg & 4) || !mode_64bit(), EXC_UD);
fail_if(!ops->read_cr);
if ( (rc = ops->read_cr(4, &cr4, ctxt)) != X86EMUL_OKAY )
goto done;
generate_exception_if(!(cr4 & X86_CR4_FSGSBASE), EXC_UD);
seg = modrm_reg & 1 ? x86_seg_gs : x86_seg_fs;
fail_if(!ops->read_segment);
if ( (rc = ops->read_segment(seg, &sreg, ctxt)) != X86EMUL_OKAY )
goto done;
dst.reg = decode_gpr(&_regs, modrm_rm);
if ( !(modrm_reg & 2) )
{
/* rd{f,g}sbase */
dst.type = OP_REG;
dst.bytes = (op_bytes == 8) ? 8 : 4;
dst.val = sreg.base;
}
else
{
/* wr{f,g}sbase */
if ( op_bytes == 8 )
{
sreg.base = *dst.reg;
generate_exception_if(!is_canonical_address(sreg.base),
EXC_GP, 0);
}
else
sreg.base = (uint32_t)*dst.reg;
fail_if(!ops->write_segment);
if ( (rc = ops->write_segment(seg, &sreg, ctxt)) != X86EMUL_OKAY )
goto done;
}
break;
rc = x86emul_0fae(state, &_regs, &dst, &src, ctxt, ops, &fpu_type);
goto dispatch_from_helper;
case X86EMUL_OPC(0x0f, 0xaf): /* imul */
emulate_2op_SrcV_srcmem("imul", src, dst, _regs.eflags);
@@ -10543,7 +10320,7 @@ x86_emulate(
goto unrecognized_insn;
default:
unimplemented_insn:
unimplemented_insn: __maybe_unused;
rc = X86EMUL_UNIMPLEMENTED;
goto done;
unrecognized_insn:
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.