xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC] x86/hvm: unify HVM and PVH hypercall tables.
@ 2014-05-08 15:31 Tim Deegan
  2014-05-08 16:53 ` George Dunlap
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Tim Deegan @ 2014-05-08 15:31 UTC (permalink / raw)
  To: xen-devel; +Cc: Keir Fraser, Jan Beulich

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.
 - VCPUOP_get_physid
   Harmless.

 - __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

^ permalink raw reply related	[flat|nested] 18+ messages in thread
* Re: [PATCH RFC] x86/hvm: unify HVM and PVH hypercall tables.
@ 2014-05-15 14:32 Konrad Rzeszutek Wilk
  2014-05-15 23:35 ` Mukesh Rathor
  0 siblings, 1 reply; 18+ messages in thread
From: Konrad Rzeszutek Wilk @ 2014-05-15 14:32 UTC (permalink / raw)
  To: Tim Deegan; +Cc: George Dunlap, Keir Fraser, Jan Beulich, xen-devel


On May 15, 2014 6:30 AM, Tim Deegan <tim@xen.org> wrote:
>
> At 14:39 -0400 on 08 May (1399556383), Konrad Rzeszutek Wilk wrote: 
> > 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 
>
> Right, thanks.  Do you think that's likely to be a hypervisor bug, or 
> just a "don't do that then"?

It is a bug. But I don't know where and had not had a chance to investigate this further.

My feeling is that it is APIC emulation but I might be quite off.
>
> AFAICT PVH domains need this as they have no other way of sending 
> NMIs. 
>

Perhaps. The vAPIC that Boris had been looking at could make this work via the APIC path.
> Tim. 
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

end of thread, other threads:[~2014-05-19 15:22 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).