All of lore.kernel.org
 help / color / mirror / Atom feed
From: George Dunlap <george.dunlap@eu.citrix.com>
To: xen-devel@lists.xen.org, "Nakajima, Jun" <jun.nakajima@intel.com>,
	"Dong, Eddie" <eddie.dong@intel.com>
Subject: Re: [PATCH v14 12/17] pvh: Use PV handlers for cpuid, and IO
Date: Mon, 4 Nov 2013 16:20:42 +0000	[thread overview]
Message-ID: <5277C95A.8060208@eu.citrix.com> (raw)
In-Reply-To: <1383567306-6636-13-git-send-email-george.dunlap@eu.citrix.com>

On 04/11/13 12:15, George Dunlap wrote:
> For cpuid, this means putting hooks into the vmexit handler to call it instead
> of the hvm one.
>
> For IO, this now means putting a hook into the emulation code to call the PV
> guest_io_{read,write} functions.
>
> NB at this point this won't do the full "copy and execute on the stack
> with full GPRs" work-around; this may need to be sorted out for dom0 to allow
> these instructions to happen in guest context.
>
> Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
> Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com>
> ---
> v14-hvmio:
>   - Use HVM path to emulate IO, calling into PV just for the final IO
>   - Don't support forced invalid ops any more (so we can avoid PV emulation altogether)
> v13:
>   - Remove unnecessary privilege check in PIO path, update related comment
>   - Move ? and : to end of line rather than beginning, as requested
>
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Tim Deegan <tim@xen.org>
> CC: Keir Fraser <keir@xen.org>
> ---
>   xen/arch/x86/hvm/emulate.c      |   75 ++++++++++++++++++++++++++++++++++-----
>   xen/arch/x86/hvm/vmx/vmx.c      |    3 +-
>   xen/arch/x86/traps.c            |    6 ++--
>   xen/include/asm-x86/processor.h |    2 ++
>   xen/include/asm-x86/traps.h     |    8 +++++
>   5 files changed, 81 insertions(+), 13 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index a41eaa1..0d767c2 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -16,14 +16,14 @@
>   #include <xen/paging.h>
>   #include <xen/trace.h>
>   #include <asm/event.h>
> +#include <asm/traps.h>
>   #include <asm/xstate.h>
>   #include <asm/hvm/emulate.h>
>   #include <asm/hvm/hvm.h>
>   #include <asm/hvm/trace.h>
>   #include <asm/hvm/support.h>
>   
> -static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
> -{
> +static void trace_io_assist(int is_mmio, int dir, int data_valid, paddr_t addr, unsigned int data) {
>       unsigned int size, event;
>       unsigned char buffer[12];
>   
> @@ -31,22 +31,28 @@ static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>           return;
>   
>       if ( is_mmio )
> -        event = p->dir ? TRC_HVM_IOMEM_READ : TRC_HVM_IOMEM_WRITE;
> +        event = dir ? TRC_HVM_IOMEM_READ : TRC_HVM_IOMEM_WRITE;
>       else
> -        event = p->dir ? TRC_HVM_IOPORT_READ : TRC_HVM_IOPORT_WRITE;
> +        event = dir ? TRC_HVM_IOPORT_READ : TRC_HVM_IOPORT_WRITE;
>   
> -    *(uint64_t *)buffer = p->addr;
> -    size = (p->addr != (u32)p->addr) ? 8 : 4;
> +    *(uint64_t *)buffer = addr;
> +    size = (addr != (u32)addr) ? 8 : 4;
>       if ( size == 8 )
>           event |= TRC_64_FLAG;
>   
> -    if ( !p->data_is_ptr )
> +    if ( data_valid )
>       {
> -        *(uint32_t *)&buffer[size] = p->data;
> +        *(uint32_t *)&buffer[size] = data;
>           size += 4;
>       }
>   
>       trace_var(event, 0/*!cycles*/, size, buffer);
> +
> +}
> +
> +static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
> +{
> +    trace_io_assist(is_mmio, p->dir, !p->data_is_ptr, p->addr, p->data);
>   }
>   
>   static int hvmemul_do_io(
> @@ -140,6 +146,9 @@ static int hvmemul_do_io(
>           }
>       }
>   
> +    if ( is_pvh_vcpu(curr) )
> +        ASSERT(vio->io_state == HVMIO_none);
> +
>       switch ( vio->io_state )
>       {
>       case HVMIO_none:
> @@ -284,11 +293,59 @@ static int hvmemul_do_io(
>       return X86EMUL_OKAY;
>   }
>   
> +static int pvhemul_do_pio(
> +    unsigned long port, int size, paddr_t ram_gpa, int dir, void *p_data)
> +{
> +    paddr_t value = ram_gpa;
> +    struct vcpu *curr = current;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +
> +    /*
> +     * Weird-sized accesses have undefined behaviour: we discard writes
> +     * and read all-ones.
> +     */
> +    if ( unlikely((size > sizeof(long)) || (size & (size - 1))) )
> +    {
> +        gdprintk(XENLOG_WARNING, "bad mmio size %d\n", size);
> +        ASSERT(p_data != NULL); /* cannot happen with a REP prefix */
> +        if ( dir == IOREQ_READ )
> +            memset(p_data, ~0, size);
> +        return X86EMUL_UNHANDLEABLE;
> +    }
> +
> +    if ( dir == IOREQ_WRITE ) {
> +        if ( (p_data != NULL) )
> +        {
> +            memcpy(&value, p_data, size);
> +            p_data = NULL;
> +        }
> +
> +    if ( dir == IOREQ_WRITE )
> +        trace_io_assist(0, dir, 1, port, value);
> +
> +        guest_io_write(port, size, value, curr, regs);
> +    }
> +    else
> +    {
> +        value = guest_io_read(port, size, curr, regs);
> +        trace_io_assist(0, dir, 1, port, value);
> +        if ( (p_data != NULL) )
> +            memcpy(p_data, &value, size);
> +        memcpy(&regs->eax, &value, size);
> +    }
> +
> +    return X86EMUL_OKAY;
> +}
> +
> +
>   int hvmemul_do_pio(
>       unsigned long port, unsigned long *reps, int size,
>       paddr_t ram_gpa, int dir, int df, void *p_data)
>   {
> -    return hvmemul_do_io(0, port, reps, size, ram_gpa, dir, df, p_data);
> +    return is_hvm_vcpu(current) ?
> +        hvmemul_do_io(0, port, reps, size, ram_gpa, dir, df, p_data) :
> +        pvhemul_do_pio(port, size, ram_gpa, dir, p_data);
> +
>   }
>   
>   static int hvmemul_do_mmio(
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 94e9e21..5d1e367 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -56,6 +56,7 @@
>   #include <asm/apic.h>
>   #include <asm/hvm/nestedhvm.h>
>   #include <asm/event.h>
> +#include <asm/traps.h>
>   
>   enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised };
>   
> @@ -2694,8 +2695,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>           break;
>       }
>       case EXIT_REASON_CPUID:
> +        is_pvh_vcpu(v) ? pv_cpuid(regs) : vmx_do_cpuid(regs);
>           update_guest_eip(); /* Safe: CPUID */
> -        vmx_do_cpuid(regs);
>           break;
>       case EXIT_REASON_HLT:
>           update_guest_eip(); /* Safe: HLT */
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
> index edb7a6a..6c278bc 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -729,7 +729,7 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
>       return 1;
>   }
>   
> -static void pv_cpuid(struct cpu_user_regs *regs)
> +void pv_cpuid(struct cpu_user_regs *regs)
>   {
>       uint32_t a, b, c, d;
>   
> @@ -1681,7 +1681,7 @@ static int pci_cfg_ok(struct domain *d, int write, int size)
>       return 1;
>   }
>   
> -static uint32_t guest_io_read(
> +uint32_t guest_io_read(
>       unsigned int port, unsigned int bytes,
>       struct vcpu *v, struct cpu_user_regs *regs)
>   {
> @@ -1748,7 +1748,7 @@ static uint32_t guest_io_read(
>       return data;
>   }
>   
> -static void guest_io_write(
> +void guest_io_write(
>       unsigned int port, unsigned int bytes, uint32_t data,
>       struct vcpu *v, struct cpu_user_regs *regs)
>   {
> diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
> index 893afa3..551036d 100644
> --- a/xen/include/asm-x86/processor.h
> +++ b/xen/include/asm-x86/processor.h
> @@ -567,6 +567,8 @@ void microcode_set_module(unsigned int);
>   int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void), unsigned long len);
>   int microcode_resume_cpu(int cpu);
>   
> +void pv_cpuid(struct cpu_user_regs *regs);
> +
>   #endif /* !__ASSEMBLY__ */
>   
>   #endif /* __ASM_X86_PROCESSOR_H */
> diff --git a/xen/include/asm-x86/traps.h b/xen/include/asm-x86/traps.h
> index 82cbcee..a26b318 100644
> --- a/xen/include/asm-x86/traps.h
> +++ b/xen/include/asm-x86/traps.h
> @@ -49,4 +49,12 @@ extern int guest_has_trap_callback(struct domain *d, uint16_t vcpuid,
>   extern int send_guest_trap(struct domain *d, uint16_t vcpuid,
>   				unsigned int trap_nr);
>   
> +uint32_t guest_io_read(
> +    unsigned int port, unsigned int bytes,
> +    struct vcpu *v, struct cpu_user_regs *regs);
> +void guest_io_write(
> +    unsigned int port, unsigned int bytes, uint32_t data,
> +    struct vcpu *v, struct cpu_user_regs *regs);
> +
> +
>   #endif /* ASM_TRAP_H */

  reply	other threads:[~2013-11-04 16:20 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-04 12:14 [PATCH v14 00/20] Introduce PVH domU support George Dunlap
2013-11-04 12:14 ` [PATCH v14 01/17] Allow vmx_update_debug_state to be called when v!=current George Dunlap
2013-11-04 16:01   ` Jan Beulich
2013-11-04 16:18   ` George Dunlap
2013-11-04 12:14 ` [PATCH v14 02/17] libxc: Move temporary grant table mapping to end of memory George Dunlap
2013-11-05 10:57   ` Roger Pau Monné
2013-11-05 11:01     ` Ian Campbell
2013-11-04 12:14 ` [PATCH v14 03/17] pvh prep: code motion George Dunlap
2013-11-04 16:14   ` Jan Beulich
2013-11-07 10:48     ` George Dunlap
2013-11-04 12:14 ` [PATCH v14 04/17] Introduce pv guest type and has_hvm_container macros George Dunlap
2013-11-04 16:20   ` Jan Beulich
2013-11-04 16:26     ` George Dunlap
2013-11-04 16:39     ` George Dunlap
2013-11-07 10:55     ` George Dunlap
2013-11-07 11:04       ` Jan Beulich
2013-11-07 11:11         ` George Dunlap
2013-11-04 12:14 ` [PATCH v14 05/17] pvh: Introduce PVH guest type George Dunlap
2013-11-06 23:28   ` Tim Deegan
2013-11-07 11:21     ` George Dunlap
2013-11-07 16:59       ` Tim Deegan
2013-11-04 12:14 ` [PATCH v14 06/17] pvh: Disable unneeded features of HVM containers George Dunlap
2013-11-04 16:21   ` George Dunlap
2013-11-04 16:37   ` Jan Beulich
2013-11-06 23:54   ` Tim Deegan
2013-11-07  9:00     ` Jan Beulich
2013-11-07 17:02       ` Tim Deegan
2013-11-04 12:14 ` [PATCH v14 07/17] pvh: vmx-specific changes George Dunlap
2013-11-04 16:19   ` George Dunlap
2013-11-04 16:42   ` Jan Beulich
2013-11-07  0:28     ` Tim Deegan
2013-11-07  0:27   ` Tim Deegan
2013-11-07 14:50     ` George Dunlap
2013-11-07 15:40       ` Andrew Cooper
2013-11-07 15:43         ` George Dunlap
2013-11-07 17:00       ` Tim Deegan
2013-11-04 12:14 ` [PATCH v14 08/17] pvh: Do not allow PVH guests to change paging modes George Dunlap
2013-11-04 12:14 ` [PATCH v14 09/17] pvh: PVH access to hypercalls George Dunlap
2013-11-04 12:14 ` [PATCH v14 10/17] pvh: Use PV e820 George Dunlap
2013-11-04 12:15 ` [PATCH v14 11/17] pvh: Set up more PV stuff in set_info_guest George Dunlap
2013-11-04 16:20   ` George Dunlap
2013-11-04 16:53   ` Jan Beulich
2013-11-07 15:51     ` George Dunlap
2013-11-07 16:10       ` Jan Beulich
2013-11-07 16:33         ` George Dunlap
2013-11-04 12:15 ` [PATCH v14 12/17] pvh: Use PV handlers for cpuid, and IO George Dunlap
2013-11-04 16:20   ` George Dunlap [this message]
2013-11-05  8:42   ` Jan Beulich
2013-11-07 16:50     ` George Dunlap
2013-11-04 12:15 ` [PATCH v14 13/17] pvh: Disable 32-bit guest support for now George Dunlap
2013-11-04 12:15 ` [PATCH v14 14/17] pvh: Restrict tsc_mode to NEVER_EMULATE " George Dunlap
2013-11-04 12:15 ` [PATCH v14 15/17] pvh: Documentation George Dunlap
2013-11-04 12:15 ` [PATCH v14 16/17] PVH xen tools: libxc changes to build a PVH guest George Dunlap
2013-11-04 12:15 ` [PATCH v14 17/17] PVH xen tools: libxl changes to create " George Dunlap
2013-11-04 16:59 ` [PATCH v14 00/20] Introduce PVH domU support Konrad Rzeszutek Wilk
2013-11-04 17:23   ` George Dunlap
2013-11-04 17:34     ` Tim Deegan
2013-11-08 15:41       ` George Dunlap
2013-11-08 15:53         ` George Dunlap
2013-11-08 17:01           ` Tim Deegan
2013-11-08 17:06             ` George Dunlap
2013-11-08 15:58         ` Konrad Rzeszutek Wilk
2013-11-07  1:11 ` Tim Deegan
2013-11-11 12:37 ` Roger Pau Monné

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=5277C95A.8060208@eu.citrix.com \
    --to=george.dunlap@eu.citrix.com \
    --cc=eddie.dong@intel.com \
    --cc=jun.nakajima@intel.com \
    --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 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.