From: Paul Durrant <Paul.Durrant@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>,
Julien Grall <julien.grall@arm.com>,
"Tim (Xen.org)" <tim@xen.org>, Jan Beulich <JBeulich@suse.com>
Subject: Re: [PATCH for 4.9 5/6] x86/emul: Drop swint_emulate infrastructure
Date: Mon, 3 Apr 2017 08:36:08 +0000 [thread overview]
Message-ID: <d0a945c3c91042e986e77c3b9054038e@AMSPEX02CL03.citrite.net> (raw)
In-Reply-To: <1490989853-21879-6-git-send-email-andrew.cooper3@citrix.com>
> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@citrix.com]
> Sent: 31 March 2017 20:51
> To: Xen-devel <xen-devel@lists.xen.org>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; Jan Beulich
> <JBeulich@suse.com>; Paul Durrant <Paul.Durrant@citrix.com>; Tim
> (Xen.org) <tim@xen.org>; Julien Grall <julien.grall@arm.com>
> Subject: [PATCH for 4.9 5/6] x86/emul: Drop swint_emulate infrastructure
>
> With the SVM injection logic capable of doing its own emulation, there is no
> need for this hardware-specific assistance in the common emulator.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
emulate parts...
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Paul Durrant <paul.durrant@citrix.com>
> CC: Tim Deegan <tim@xen.org>
> CC: Julien Grall <julien.grall@arm.com>
> ---
> tools/fuzz/x86_instruction_emulator/fuzz-emul.c | 18 +--
> xen/arch/x86/hvm/emulate.c | 7 -
> xen/arch/x86/mm.c | 2 -
> xen/arch/x86/mm/shadow/common.c | 1 -
> xen/arch/x86/x86_emulate/x86_emulate.c | 187 ++++--------------------
> xen/arch/x86/x86_emulate/x86_emulate.h | 53 -------
> 6 files changed, 30 insertions(+), 238 deletions(-)
>
> diff --git a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
> b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
> index 890642c..8488816 100644
> --- a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
> +++ b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
> @@ -536,8 +536,7 @@ enum {
> HOOK_put_fpu,
> HOOK_invlpg,
> HOOK_vmfunc,
> - OPTION_swint_emulation, /* Two bits */
> - CANONICALIZE_rip = OPTION_swint_emulation + 2,
> + CANONICALIZE_rip,
> CANONICALIZE_rsp,
> CANONICALIZE_rbp
> };
> @@ -577,19 +576,6 @@ static void disable_hooks(void)
> MAYBE_DISABLE_HOOK(invlpg);
> }
>
> -static void set_swint_support(struct x86_emulate_ctxt *ctxt)
> -{
> - unsigned int swint_opt = (input.options >> OPTION_swint_emulation) &
> 3;
> - static const enum x86_swint_emulation map[4] = {
> - x86_swint_emulate_none,
> - x86_swint_emulate_none,
> - x86_swint_emulate_icebp,
> - x86_swint_emulate_all
> - };
> -
> - ctxt->swint_emulate = map[swint_opt];
> -}
> -
> /*
> * Constrain input to architecturally-possible states where
> * the emulator relies on these
> @@ -693,8 +679,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data_p,
> size_t size)
>
> disable_hooks();
>
> - set_swint_support(&ctxt);
> -
> do {
> /* FIXME: Until we actually implement SIGFPE handling properly */
> setup_fpu_exception_handler();
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index f578796..efac2e9 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -2036,13 +2036,6 @@ void hvm_emulate_init_once(
> hvmemul_ctxt->ctxt.regs = regs;
> hvmemul_ctxt->ctxt.vendor = curr->domain->arch.cpuid->x86_vendor;
> hvmemul_ctxt->ctxt.force_writeback = true;
> -
> - if ( cpu_has_vmx )
> - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_none;
> - else if ( cpu_has_svm_nrips )
> - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_icebp;
> - else
> - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_all;
> }
>
> void hvm_emulate_init_per_insn(
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index be4e308..3918a37 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -5412,7 +5412,6 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned
> long addr,
> .vendor = d->arch.cpuid->x86_vendor,
> .addr_size = is_pv_32bit_domain(d) ? 32 : BITS_PER_LONG,
> .sp_size = is_pv_32bit_domain(d) ? 32 : BITS_PER_LONG,
> - .swint_emulate = x86_swint_emulate_none,
> },
> };
> int rc;
> @@ -5567,7 +5566,6 @@ int mmio_ro_do_page_fault(struct vcpu *v,
> unsigned long addr,
> .vendor = v->domain->arch.cpuid->x86_vendor,
> .addr_size = addr_size,
> .sp_size = addr_size,
> - .swint_emulate = x86_swint_emulate_none,
> .data = &mmio_ro_ctxt
> };
> int rc;
> diff --git a/xen/arch/x86/mm/shadow/common.c
> b/xen/arch/x86/mm/shadow/common.c
> index 551a7d3..2fc796b 100644
> --- a/xen/arch/x86/mm/shadow/common.c
> +++ b/xen/arch/x86/mm/shadow/common.c
> @@ -328,7 +328,6 @@ const struct x86_emulate_ops
> *shadow_init_emulation(
>
> sh_ctxt->ctxt.regs = regs;
> sh_ctxt->ctxt.vendor = v->domain->arch.cpuid->x86_vendor;
> - sh_ctxt->ctxt.swint_emulate = x86_swint_emulate_none;
>
> /* Segment cache initialisation. Primed with CS. */
> creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt);
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
> b/xen/arch/x86/x86_emulate/x86_emulate.c
> index 7af8a42..7315ca6 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -1999,142 +1999,6 @@ static bool umip_active(struct x86_emulate_ctxt
> *ctxt,
> (cr4 & X86_CR4_UMIP);
> }
>
> -/* Inject a software interrupt/exception, emulating if needed. */
> -static int inject_swint(enum x86_swint_type type,
> - uint8_t vector, uint8_t insn_len,
> - struct x86_emulate_ctxt *ctxt,
> - const struct x86_emulate_ops *ops)
> -{
> - int rc, error_code, fault_type = EXC_GP;
> -
> - /*
> - * Without hardware support, injecting software interrupts/exceptions is
> - * problematic.
> - *
> - * All software methods of generating exceptions (other than BOUND)
> yield
> - * traps, so eip in the exception frame needs to point after the
> - * instruction, not at it.
> - *
> - * However, if injecting it as a hardware exception causes a fault during
> - * delivery, our adjustment of eip will cause the fault to be reported
> - * after the faulting instruction, not pointing to it.
> - *
> - * Therefore, eip can only safely be wound forwards if we are certain that
> - * injecting an equivalent hardware exception won't fault, which means
> - * emulating everything the processor would do on a control transfer.
> - *
> - * However, emulation of complete control transfers is very complicated.
> - * All we care about is that guest userspace cannot avoid the descriptor
> - * DPL check by using the Xen emulator, and successfully invoke DPL=0
> - * descriptors.
> - *
> - * Any OS which would further fault during injection is going to receive a
> - * double fault anyway, and won't be in a position to care that the
> - * faulting eip is incorrect.
> - */
> -
> - if ( (ctxt->swint_emulate == x86_swint_emulate_all) ||
> - ((ctxt->swint_emulate == x86_swint_emulate_icebp) &&
> - (type == x86_swint_icebp)) )
> - {
> - if ( !in_realmode(ctxt, ops) )
> - {
> - unsigned int idte_size, idte_offset;
> - struct { uint32_t a, b, c, d; } idte = {};
> - int lm = in_longmode(ctxt, ops);
> -
> - if ( lm < 0 )
> - return X86EMUL_UNHANDLEABLE;
> -
> - idte_size = lm ? 16 : 8;
> - idte_offset = vector * idte_size;
> -
> - /* icebp sets the External Event bit despite being an instruction. */
> - error_code = (vector << 3) | ECODE_IDT |
> - (type == x86_swint_icebp ? ECODE_EXT : 0);
> -
> - /*
> - * TODO - this does not cover the v8086 mode with CR4.VME case
> - * correctly, but falls on the safe side from the point of view of
> - * a 32bit OS. Someone with many TUITs can see about reading the
> - * TSS Software Interrupt Redirection bitmap.
> - */
> - if ( (ctxt->regs->eflags & X86_EFLAGS_VM) &&
> - ((ctxt->regs->eflags & X86_EFLAGS_IOPL) != X86_EFLAGS_IOPL) )
> - goto raise_exn;
> -
> - /*
> - * Read all 8/16 bytes so the idtr limit check is applied properly
> - * to this entry, even though we only end up looking at the 2nd
> - * word.
> - */
> - switch ( rc = ops->read(x86_seg_idtr, idte_offset,
> - &idte, idte_size, ctxt) )
> - {
> - case X86EMUL_OKAY:
> - break;
> -
> - case X86EMUL_EXCEPTION:
> - if ( !ctxt->event_pending )
> - goto raise_exn;
> - /* fallthrough */
> -
> - default:
> - return rc;
> - }
> -
> - /* This must be an interrupt, trap, or task gate. */
> -#ifdef __XEN__
> - switch ( (idte.b >> 8) & 0x1f )
> - {
> - case SYS_DESC_irq_gate:
> - case SYS_DESC_trap_gate:
> - break;
> - case SYS_DESC_irq_gate16:
> - case SYS_DESC_trap_gate16:
> - case SYS_DESC_task_gate:
> - if ( !lm )
> - break;
> - /* fall through */
> - default:
> - goto raise_exn;
> - }
> -#endif
> -
> - /* The 64-bit high half's type must be zero. */
> - if ( idte.d & 0x1f00 )
> - goto raise_exn;
> -
> - /* icebp counts as a hardware event, and bypasses the dpl check. */
> - if ( type != x86_swint_icebp )
> - {
> - int cpl = get_cpl(ctxt, ops);
> -
> - fail_if(cpl < 0);
> -
> - if ( cpl > ((idte.b >> 13) & 3) )
> - goto raise_exn;
> - }
> -
> - /* Is this entry present? */
> - if ( !(idte.b & (1u << 15)) )
> - {
> - fault_type = EXC_NP;
> - goto raise_exn;
> - }
> - }
> - }
> -
> - x86_emul_software_event(type, vector, insn_len, ctxt);
> - rc = X86EMUL_OKAY;
> -
> - done:
> - return rc;
> -
> - raise_exn:
> - generate_exception(fault_type, error_code);
> -}
> -
> static void adjust_bnd(struct x86_emulate_ctxt *ctxt,
> const struct x86_emulate_ops *ops, enum vex_pfx pfx)
> {
> @@ -3101,7 +2965,6 @@ x86_emulate(
> struct operand src = { .reg = PTR_POISON };
> struct operand dst = { .reg = PTR_POISON };
> unsigned long cr4;
> - enum x86_swint_type swint_type;
> struct fpu_insn_ctxt fic = { .type = X86EMUL_FPU_none, .exn_raised = -1
> };
> struct x86_emulate_stub stub = {};
> DECLARE_ALIGNED(mmval_t, mmval);
> @@ -4103,25 +3966,38 @@ x86_emulate(
> goto done;
> break;
>
> - case 0xcc: /* int3 */
> - src.val = EXC_BP;
> - swint_type = x86_swint_int3;
> - goto swint;
> -
> - case 0xcd: /* int imm8 */
> - swint_type = x86_swint_int;
> - swint:
> - rc = inject_swint(swint_type, (uint8_t)src.val,
> - _regs.r(ip) - ctxt->regs->r(ip),
> - ctxt, ops) ? : X86EMUL_EXCEPTION;
> - goto done;
> -
> case 0xce: /* into */
> if ( !(_regs.eflags & X86_EFLAGS_OF) )
> break;
> - src.val = EXC_OF;
> - swint_type = x86_swint_into;
> - goto swint;
> + /* Fallthrough */
> + case 0xcc: /* int3 */
> + case 0xcd: /* int imm8 */
> + case 0xf1: /* int1 (icebp) */
> + ASSERT(!ctxt->event_pending);
> + switch ( ctxt->opcode )
> + {
> + case 0xcc: /* int3 */
> + ctxt->event.vector = EXC_BP;
> + ctxt->event.type = X86_EVENTTYPE_SW_EXCEPTION;
> + break;
> + case 0xcd: /* int imm8 */
> + ctxt->event.vector = src.val;
> + ctxt->event.type = X86_EVENTTYPE_SW_INTERRUPT;
> + break;
> + case 0xce: /* into */
> + ctxt->event.vector = EXC_OF;
> + ctxt->event.type = X86_EVENTTYPE_SW_EXCEPTION;
> + break;
> + case 0xf1: /* icebp */
> + ctxt->event.vector = EXC_DB;
> + ctxt->event.type = X86_EVENTTYPE_PRI_SW_EXCEPTION;
> + break;
> + }
> + ctxt->event.error_code = X86_EVENT_NO_EC;
> + ctxt->event.insn_len = _regs.r(ip) - ctxt->regs->r(ip);
> + ctxt->event_pending = true;
> + rc = X86EMUL_EXCEPTION;
> + goto done;
>
> case 0xcf: /* iret */ {
> unsigned long sel, eip, eflags;
> @@ -4782,11 +4658,6 @@ x86_emulate(
> goto done;
> break;
>
> - case 0xf1: /* int1 (icebp) */
> - src.val = EXC_DB;
> - swint_type = x86_swint_icebp;
> - goto swint;
> -
> case 0xf4: /* hlt */
> generate_exception_if(!mode_ring0(), EXC_GP, 0);
> ctxt->retire.hlt = true;
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h
> b/xen/arch/x86/x86_emulate/x86_emulate.h
> index 9c5fcde..215adf6 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
> @@ -60,27 +60,6 @@ static inline bool is_x86_system_segment(enum
> x86_segment seg)
> return seg >= x86_seg_tr && seg < x86_seg_none;
> }
>
> -/* Classification of the types of software generated interrupts/exceptions.
> */
> -enum x86_swint_type {
> - x86_swint_icebp, /* 0xf1 */
> - x86_swint_int3, /* 0xcc */
> - x86_swint_into, /* 0xce */
> - x86_swint_int, /* 0xcd $n */
> -};
> -
> -/*
> - * How much help is required with software event injection?
> - *
> - * All software events return from x86_emulate() with
> X86EMUL_EXCEPTION and
> - * fault-like semantics. This just controls whether the emulator performs
> - * presence/dpl/etc checks and possibly raises exceptions instead.
> - */
> -enum x86_swint_emulation {
> - x86_swint_emulate_none, /* Hardware supports all software injection
> properly */
> - x86_swint_emulate_icebp,/* Help needed with `icebp` (0xf1) */
> - x86_swint_emulate_all, /* Help needed with all software events */
> -};
> -
> /*
> * x86 event types. This enumeration is valid for:
> * Intel VMX: {VM_ENTRY,VM_EXIT,IDT_VECTORING}_INTR_INFO[10:8]
> @@ -472,9 +451,6 @@ struct x86_emulate_ctxt
> * Input-only state:
> */
>
> - /* Software event injection support. */
> - enum x86_swint_emulation swint_emulate;
> -
> /* CPU vendor (X86_VENDOR_UNKNOWN for "don't care") */
> unsigned char vendor;
>
> @@ -699,35 +675,6 @@ static inline void x86_emul_pagefault(
> ctxt->event_pending = true;
> }
>
> -static inline void x86_emul_software_event(
> - enum x86_swint_type type, uint8_t vector, uint8_t insn_len,
> - struct x86_emulate_ctxt *ctxt)
> -{
> - ASSERT(!ctxt->event_pending);
> -
> - switch ( type )
> - {
> - case x86_swint_icebp:
> - ctxt->event.type = X86_EVENTTYPE_PRI_SW_EXCEPTION;
> - break;
> -
> - case x86_swint_int3:
> - case x86_swint_into:
> - ctxt->event.type = X86_EVENTTYPE_SW_EXCEPTION;
> - break;
> -
> - case x86_swint_int:
> - ctxt->event.type = X86_EVENTTYPE_SW_INTERRUPT;
> - break;
> - }
> -
> - ctxt->event.vector = vector;
> - ctxt->event.error_code = X86_EVENT_NO_EC;
> - ctxt->event.insn_len = insn_len;
> -
> - ctxt->event_pending = true;
> -}
> -
> static inline void x86_emul_reset_event(struct x86_emulate_ctxt *ctxt)
> {
> ctxt->event_pending = false;
> --
> 2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-04-03 8:36 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-31 19:50 [PATCH for 4.9 0/6] x86/emul: Fixes Andrew Cooper
2017-03-31 19:50 ` [PATCH for 4.9 1/6] x86/hvm: Correct some address space terminology Andrew Cooper
2017-04-03 8:24 ` Paul Durrant
2017-04-03 8:24 ` Jan Beulich
2017-04-03 10:19 ` Andrew Cooper
2017-04-03 10:29 ` Jan Beulich
2017-03-31 19:50 ` [PATCH for 4.9 2/6] x86/hvm: Correct long mode predicate Andrew Cooper
2017-04-03 8:26 ` Paul Durrant
2017-04-03 8:30 ` Jan Beulich
2017-04-03 8:50 ` George Dunlap
2017-04-05 7:08 ` Tian, Kevin
2017-03-31 19:50 ` [PATCH for 4.9 3/6] x86/hvm: Fix segmentation logic for system segments Andrew Cooper
2017-04-03 8:31 ` Paul Durrant
2017-04-03 9:13 ` Jan Beulich
2017-04-03 14:27 ` Andrew Cooper
2017-04-03 15:07 ` Jan Beulich
2017-04-03 15:42 ` Andrew Cooper
2017-04-03 16:08 ` Jan Beulich
2017-04-03 17:37 ` Andrew Cooper
2017-04-04 10:18 ` Andrew Cooper
2017-04-04 10:32 ` Jan Beulich
2017-03-31 19:50 ` [PATCH for 4.9 4/6] x86/svm: Introduce svm_emul_swint_injection() Andrew Cooper
2017-04-03 9:30 ` Jan Beulich
2017-04-03 14:04 ` Boris Ostrovsky
2017-03-31 19:50 ` [PATCH for 4.9 5/6] x86/emul: Drop swint_emulate infrastructure Andrew Cooper
2017-04-03 8:36 ` Paul Durrant [this message]
2017-04-03 9:38 ` Jan Beulich
2017-03-31 19:50 ` [PATCH for 4.9 6/6] x86/emul: Require callers to provide LMA in the emulation context Andrew Cooper
2017-04-03 8:40 ` Paul Durrant
2017-04-03 10:10 ` Jan Beulich
2017-04-05 16:24 ` Andrew Cooper
2017-04-06 6:58 ` Jan Beulich
2017-04-06 9:47 ` Andrew Cooper
2017-04-06 14:14 ` Jan Beulich
2017-04-06 16:32 ` Andrew Cooper
2017-04-07 8:35 ` Jan Beulich
2017-04-05 16:07 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d0a945c3c91042e986e77c3b9054038e@AMSPEX02CL03.citrite.net \
--to=paul.durrant@citrix.com \
--cc=Andrew.Cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=julien.grall@arm.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).