From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Tim Deegan <tim@xen.org>
Cc: Keir Fraser <keir@xen.org>, Jan Beulich <jbeulich@suse.com>,
xen-devel@lists.xen.org
Subject: Re: [PATCH RFC] x86/hvm: unify HVM and PVH hypercall tables.
Date: Thu, 8 May 2014 14:39:43 -0400 [thread overview]
Message-ID: <20140508183943.GA3306@phenom.dumpdata.com> (raw)
In-Reply-To: <1399563090-30081-1-git-send-email-tim@xen.org>
On Thu, May 08, 2014 at 04:31:30PM +0100, Tim Deegan wrote:
> Stage one of many in merging PVH and HVM code in the hypervisor.
>
> This exposes a few new hypercalls to HVM guests, all of which were
> already available to PVH ones:
>
> - XENMEM_memory_map / XENMEM_machine_memory_map / XENMEM_machphys_mapping:
> These are basically harmless, if a bit useless to plain HVM.
>
> - VCPUOP_send_nmi / VCPUOP_initialise / VCPUOP[_is]_up / VCPUOP_down
> This will eventually let HVM guests bring up APs the way PVH ones do.
> For now, the VCPUOP_initialise paths are still gated on is_pvh.
I had a similar patch to enable this under HVM and found out that
if the guest issues VCPUOP_send_nmi we get in Linux:
[ 3.611742] Corrupted low memory at c000fffc (fffc phys) = 00029b00
[ 2.386785] Corrupted low memory at ffff88000000fff8 (fff8 phys) = 2990000000000
http://mid.gmane.org/20140422183443.GA6817@phenom.dumpdata.com
> - VCPUOP_get_physid
> Harmless.
The other VCPUOP_ ones are OK and you can stack an Reviewed-by-and-Tested-by:
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
on that.
>
> - __HYPERVISOR_platform_op (XSM_PRIV callers only).
>
> - __HYPERVISOR_mmuext_op.
> The pagetable manipulation MMUEXT ops are already denied to
> paging_mode_refcounts() domains; the baseptr ones are already
> denied to paging_mode_translate() domains.
> I have restricted MMUEXT[UN]MARK_SUPER to !paging_mode_refcounts()
> domains as well, as I can see no need for them in PVH.
> That leaves TLB and cache flush operations and MMUEXT_CLEAR_PAGE /
> MMUEXT_COPY_PAGE, all of which are OK.
>
> - PHYSDEVOP_* (only for hardware control domains).
> Also make ops that touch PV vcpu state (PHYSDEVOP_set_iopl and
> PHYSDEVOP_set_iobitmap) gate on is_pv rather than !is_pvh.
>
> PVH guests can also see a few hypercalls that they couldn't before,
> but which were already available to HVM guests:
>
> - __HYPERVISOR_set_timer_op
>
> - __HYPERVISOR_tmem_op
>
> Signed-off-by: Tim Deegan <tim@xen.org>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Mukesh Rathor <mukesh.rathor@oracle.com>
> ---
> xen/arch/x86/hvm/hvm.c | 113 +++++++---------------------------------
> xen/arch/x86/mm.c | 12 +++++
> xen/arch/x86/physdev.c | 4 +-
> xen/arch/x86/x86_64/compat/mm.c | 2 -
> xen/include/asm-x86/hypercall.h | 10 ++++
> 5 files changed, 42 insertions(+), 99 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index da220bf..4274151 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -3433,16 +3433,13 @@ static long hvm_memory_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>
> switch ( cmd & MEMOP_CMD_MASK )
> {
> - case XENMEM_memory_map:
> - case XENMEM_machine_memory_map:
> - case XENMEM_machphys_mapping:
> - return -ENOSYS;
> case XENMEM_decrease_reservation:
> rc = do_memory_op(cmd, arg);
> current->domain->arch.hvm_domain.qemu_mapcache_invalidate = 1;
> return rc;
> + default:
> + return do_memory_op(cmd, arg);
> }
> - return do_memory_op(cmd, arg);
> }
>
> static long hvm_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
> @@ -3450,7 +3447,7 @@ static long hvm_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
> switch ( cmd )
> {
> default:
> - if ( !is_pvh_vcpu(current) || !is_hardware_domain(current->domain) )
> + if ( !is_hardware_domain(current->domain) )
> return -ENOSYS;
> /* fall through */
> case PHYSDEVOP_map_pirq:
> @@ -3462,31 +3459,6 @@ static long hvm_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
> }
> }
>
> -static long hvm_vcpu_op(
> - int cmd, int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
> -{
> - long rc;
> -
> - switch ( cmd )
> - {
> - case VCPUOP_register_runstate_memory_area:
> - case VCPUOP_get_runstate_info:
> - case VCPUOP_set_periodic_timer:
> - case VCPUOP_stop_periodic_timer:
> - case VCPUOP_set_singleshot_timer:
> - case VCPUOP_stop_singleshot_timer:
> - case VCPUOP_register_vcpu_info:
> - case VCPUOP_register_vcpu_time_memory_area:
> - rc = do_vcpu_op(cmd, vcpuid, arg);
> - break;
> - default:
> - rc = -ENOSYS;
> - break;
> - }
> -
> - return rc;
> -}
> -
> typedef unsigned long hvm_hypercall_t(
> unsigned long, unsigned long, unsigned long, unsigned long, unsigned long,
> unsigned long);
> @@ -3509,41 +3481,13 @@ static long hvm_memory_op_compat32(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>
> switch ( cmd & MEMOP_CMD_MASK )
> {
> - case XENMEM_memory_map:
> - case XENMEM_machine_memory_map:
> - case XENMEM_machphys_mapping:
> - return -ENOSYS;
> case XENMEM_decrease_reservation:
> rc = compat_memory_op(cmd, arg);
> current->domain->arch.hvm_domain.qemu_mapcache_invalidate = 1;
> return rc;
> - }
> - return compat_memory_op(cmd, arg);
> -}
> -
> -static long hvm_vcpu_op_compat32(
> - int cmd, int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
> -{
> - long rc;
> -
> - switch ( cmd )
> - {
> - case VCPUOP_register_runstate_memory_area:
> - case VCPUOP_get_runstate_info:
> - case VCPUOP_set_periodic_timer:
> - case VCPUOP_stop_periodic_timer:
> - case VCPUOP_set_singleshot_timer:
> - case VCPUOP_stop_singleshot_timer:
> - case VCPUOP_register_vcpu_info:
> - case VCPUOP_register_vcpu_time_memory_area:
> - rc = compat_vcpu_op(cmd, vcpuid, arg);
> - break;
> default:
> - rc = -ENOSYS;
> - break;
> + return compat_memory_op(cmd, arg);
> }
> -
> - return rc;
> }
>
> static long hvm_physdev_op_compat32(
> @@ -3551,27 +3495,29 @@ static long hvm_physdev_op_compat32(
> {
> switch ( cmd )
> {
> + default:
> + if ( !is_hardware_domain(current->domain) )
> + return -ENOSYS;
> + /* fall through */
> case PHYSDEVOP_map_pirq:
> case PHYSDEVOP_unmap_pirq:
> case PHYSDEVOP_eoi:
> case PHYSDEVOP_irq_status_query:
> case PHYSDEVOP_get_free_pirq:
> return compat_physdev_op(cmd, arg);
> - break;
> - default:
> - return -ENOSYS;
> - break;
> }
> }
>
> static hvm_hypercall_t *const hvm_hypercall64_table[NR_hypercalls] = {
> [ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,
> [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
> - [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,
> [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op,
> + HYPERCALL(platform_op),
> HYPERCALL(xen_version),
> HYPERCALL(console_io),
> HYPERCALL(event_channel_op),
> + HYPERCALL(vcpu_op),
> + HYPERCALL(mmuext_op),
> HYPERCALL(sched_op),
> HYPERCALL(set_timer_op),
> HYPERCALL(xsm_op),
> @@ -3587,11 +3533,13 @@ static hvm_hypercall_t *const hvm_hypercall64_table[NR_hypercalls] = {
> static hvm_hypercall_t *const hvm_hypercall32_table[NR_hypercalls] = {
> [ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op_compat32,
> [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op_compat32,
> - [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op_compat32,
> [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op_compat32,
> + HYPERCALL(platform_op),
> COMPAT_CALL(xen_version),
> HYPERCALL(console_io),
> HYPERCALL(event_channel_op),
> + COMPAT_CALL(vcpu_op),
> + COMPAT_CALL(mmuext_op),
> COMPAT_CALL(sched_op),
> COMPAT_CALL(set_timer_op),
> HYPERCALL(xsm_op),
> @@ -3601,24 +3549,6 @@ static hvm_hypercall_t *const hvm_hypercall32_table[NR_hypercalls] = {
> HYPERCALL(tmem_op)
> };
>
> -/* PVH 32bitfixme. */
> -static hvm_hypercall_t *const pvh_hypercall64_table[NR_hypercalls] = {
> - HYPERCALL(platform_op),
> - HYPERCALL(memory_op),
> - HYPERCALL(xen_version),
> - HYPERCALL(console_io),
> - [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
> - HYPERCALL(vcpu_op),
> - HYPERCALL(mmuext_op),
> - HYPERCALL(xsm_op),
> - HYPERCALL(sched_op),
> - HYPERCALL(event_channel_op),
> - [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op,
> - HYPERCALL(hvm_op),
> - HYPERCALL(sysctl),
> - HYPERCALL(domctl)
> -};
> -
> int hvm_do_hypercall(struct cpu_user_regs *regs)
> {
> struct vcpu *curr = current;
> @@ -3645,9 +3575,7 @@ int hvm_do_hypercall(struct cpu_user_regs *regs)
> if ( (eax & 0x80000000) && is_viridian_domain(curr->domain) )
> return viridian_hypercall(regs);
>
> - if ( (eax >= NR_hypercalls) ||
> - (is_pvh_vcpu(curr) ? !pvh_hypercall64_table[eax]
> - : !hvm_hypercall32_table[eax]) )
> + if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] )
> {
> regs->eax = -ENOSYS;
> return HVM_HCALL_completed;
> @@ -3662,14 +3590,9 @@ int hvm_do_hypercall(struct cpu_user_regs *regs)
> regs->r10, regs->r8, regs->r9);
>
> curr->arch.hvm_vcpu.hcall_64bit = 1;
> - if ( is_pvh_vcpu(curr) )
> - regs->rax = pvh_hypercall64_table[eax](regs->rdi, regs->rsi,
> - regs->rdx, regs->r10,
> - regs->r8, regs->r9);
> - else
> - regs->rax = hvm_hypercall64_table[eax](regs->rdi, regs->rsi,
> - regs->rdx, regs->r10,
> - regs->r8, regs->r9);
> + regs->rax = hvm_hypercall64_table[eax](regs->rdi, regs->rsi,
> + regs->rdx, regs->r10,
> + regs->r8, regs->r9);
> curr->arch.hvm_vcpu.hcall_64bit = 0;
> }
> else
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 1a8a5e0..3d5c3c8 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -3310,6 +3310,12 @@ long do_mmuext_op(
> unsigned long mfn;
> struct spage_info *spage;
>
> + if ( paging_mode_refcounts(pg_owner) )
> + {
> + okay = 0;
> + break;
> + }
> +
> mfn = op.arg1.mfn;
> if ( mfn & (L1_PAGETABLE_ENTRIES-1) )
> {
> @@ -3336,6 +3342,12 @@ long do_mmuext_op(
> unsigned long mfn;
> struct spage_info *spage;
>
> + if ( paging_mode_refcounts(pg_owner) )
> + {
> + okay = 0;
> + break;
> + }
> +
> mfn = op.arg1.mfn;
> if ( mfn & (L1_PAGETABLE_ENTRIES-1) )
> {
> diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
> index f178315..a2d2b96 100644
> --- a/xen/arch/x86/physdev.c
> +++ b/xen/arch/x86/physdev.c
> @@ -520,7 +520,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
> struct physdev_set_iopl set_iopl;
>
> ret = -ENOSYS;
> - if ( is_pvh_vcpu(current) )
> + if ( !is_pv_vcpu(current) )
> break;
>
> ret = -EFAULT;
> @@ -538,7 +538,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
> struct physdev_set_iobitmap set_iobitmap;
>
> ret = -ENOSYS;
> - if ( is_pvh_vcpu(current) )
> + if ( !is_pv_vcpu(current) )
> break;
>
> ret = -EFAULT;
> diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c
> index 69c6195..3fa90aa 100644
> --- a/xen/arch/x86/x86_64/compat/mm.c
> +++ b/xen/arch/x86/x86_64/compat/mm.c
> @@ -236,8 +236,6 @@ int compat_update_va_mapping_otherdomain(unsigned long va, u32 lo, u32 hi,
> return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid);
> }
>
> -DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t);
> -
> int compat_mmuext_op(XEN_GUEST_HANDLE_PARAM(mmuext_op_compat_t) cmp_uops,
> unsigned int count,
> XEN_GUEST_HANDLE_PARAM(uint) pdone,
> diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h
> index afa8ba9..cee8817 100644
> --- a/xen/include/asm-x86/hypercall.h
> +++ b/xen/include/asm-x86/hypercall.h
> @@ -8,6 +8,7 @@
> #include <public/physdev.h>
> #include <public/arch-x86/xen-mca.h> /* for do_mca */
> #include <xen/types.h>
> +#include <compat/memory.h>
>
> /*
> * Both do_mmuext_op() and do_mmu_update():
> @@ -110,4 +111,13 @@ extern int
> arch_compat_vcpu_op(
> int cmd, struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg);
>
> +DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t);
> +
> +extern int
> +compat_mmuext_op(
> + XEN_GUEST_HANDLE_PARAM(mmuext_op_compat_t) cmp_uops,
> + unsigned int count,
> + XEN_GUEST_HANDLE_PARAM(uint) pdone,
> + unsigned int foreigndom);
> +
> #endif /* __ASM_X86_HYPERCALL_H__ */
> --
> 1.8.5.2
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2014-05-08 18:39 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-08 15:31 [PATCH RFC] x86/hvm: unify HVM and PVH hypercall tables Tim Deegan
2014-05-08 16:53 ` George Dunlap
2014-05-15 10:25 ` Tim Deegan
2014-05-08 18:39 ` Konrad Rzeszutek Wilk [this message]
2014-05-15 10:30 ` Tim Deegan
2014-05-15 11:58 ` Jan Beulich
2014-05-09 8:08 ` Jan Beulich
2014-05-15 10:34 ` Tim Deegan
2014-05-16 0:19 ` Mukesh Rathor
2014-05-15 10:53 ` [PATCH v2] " Tim Deegan
2014-05-15 12:39 ` Jan Beulich
2014-05-15 13:35 ` [PATCH v2] x86/hvm: unify HVM and PVH hypercall tables.g Tim Deegan
2014-05-15 13:35 ` [PATCH v3] x86/hvm: unify HVM and PVH hypercall tables Tim Deegan
2014-05-19 14:08 ` Jan Beulich
2014-05-19 15:22 ` Tim Deegan
-- strict thread matches above, loose matches on Subject: below --
2014-05-15 14:32 [PATCH RFC] " Konrad Rzeszutek Wilk
2014-05-15 23:35 ` Mukesh Rathor
2014-05-16 12:45 ` Konrad Rzeszutek Wilk
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=20140508183943.GA3306@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=jbeulich@suse.com \
--cc=keir@xen.org \
--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).