[Xen-devel] [PATCH v9] x86/altp2m: support for setting restrictions for an array of pages

2017-12-12 Thread Petre Pircalabu
From: Razvan Cojocaru 

For the default EPT view we have xc_set_mem_access_multi(), which
is able to set an array of pages to an array of access rights with
a single hypercall. However, this functionality was lacking for the
altp2m subsystem, which could only set page restrictions for one
page at a time. This patch addresses the gap.

HVMOP_altp2m_set_mem_access_multi has been added as a HVMOP (as opposed to a
DOMCTL) for consistency with its HVMOP_altp2m_set_mem_access counterpart (and
hence with the original altp2m design, where domains are allowed - with the
proper altp2m access rights - to alter these settings), in the absence of an
official position on the issue from the original altp2m designers.

Signed-off-by: Razvan Cojocaru 
Signed-off-by: Petre Pircalabu 

---

Changed since v2:
* Added support for compat arguments translation

Changed since v3:
* Replaced  __copy_to_guest with __copy_field_to_guest
* Removed the un-needed parentheses.
* Fixed xlat.lst ordering
* Added comment to patch description explaining why the
functionality was added as an HVMOP.
* Guard using XEN_GENERATING_COMPAT_HEADERS the hvmmem_type_t definition.
This will prevent suplicate definitions to be generated for the
compat equivalent.
* Added comment describing the manual translation of
xen_hvm_altp2m_op_t generic fields from compat_hvm_altp2m_op_t.

Changed since v4:
* Changed the mask parameter to 0x3F.
* Split long lines.
* Added "improperly named HVMMEM_(*)" to the comment explaining the
XEN_GENERATING_COMPAT_HEADERS guard.
* Removed typedef and XEN_GUEST_HANDLE for 
xen_hvm_altp2m_set_mem_access_multi.
* Copied the "opaque" field to guest in compat_altp2m_op.
* Added build time test to check if the size of
xen_hvm_altp2m_set_mem_access_multi at least equal to the size of
compat_hvm_altp2m_set_mem_access_multi.

Changed since v5:
* Changed the domid parameter type to uint32_t to match 5b42c82f.
* Added comment to explain why the 0x3F value was chosen.
* Fixed switch indentation in compat_altp2m_op.
* Changed the condition used to check if the opaque field has to
be copied to the guest.
* Added CHECK_hvm_altp2m_op and CHECK_hvm_altp2m_set_mem_access_multi.

Changed since v6:
* Removed trailing semicolon from the definitions of CHECK_hvm_altp2m_op
and CHECK_hvm_altp2m_set_mem_access_multi.
* Removed BUILD_BUG_ON check.
* Added comment describing the reason for manually defining the CHECK_
macros.
* Added ASSERT_UNREACHABLE as the default switch label action in
compat_altp2m_op.
* Added ASSERT(rc == __HYPERVISOR_hvm_op) to make sure the return
code was actually sey by hypercall_create_continuation.

Changed since v7:
* Changed the patch title.

Changed since v8:
* Use sizeof *var for portability
* Added "must be set to 0" to opaque's comment
* Reordered alphabetically the compat headers
* Added blanks to switch statements at the end of each "case" block
* Do not return -EINVAL when nr is 0
---
 tools/libxc/include/xenctrl.h   |   3 +
 tools/libxc/xc_altp2m.c |  41 
 xen/arch/x86/hvm/hvm.c  | 142 +++-
 xen/include/Makefile|   3 +-
 xen/include/public/hvm/hvm_op.h |  39 +--
 xen/include/xlat.lst|   1 +
 6 files changed, 222 insertions(+), 7 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 666db0b..f171668 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1974,6 +1974,9 @@ int xc_altp2m_set_mem_access(xc_interface *handle, 
uint32_t domid,
 int xc_altp2m_change_gfn(xc_interface *handle, uint32_t domid,
  uint16_t view_id, xen_pfn_t old_gfn,
  xen_pfn_t new_gfn);
+int xc_altp2m_set_mem_access_multi(xc_interface *handle, uint32_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *pages, uint32_t nr);
 
 /** 
  * Mem paging operations.
diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c
index 07fcd18..0f792b5 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -213,3 +213,44 @@ int xc_altp2m_change_gfn(xc_interface *handle, uint32_t 
domid,
 return rc;
 }
 
+int xc_altp2m_set_mem_access_multi(xc_interface *xch, uint32_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *pages, uint32_t nr)
+{
+int rc;
+
+DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
+DECLARE_HYPERCALL_BOUNCE(access, nr * sizeof(*access),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+DECLARE_HYPERCALL_BOUNCE(pages, nr * sizeof(*pages),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+arg = xc_hypercall_

[Xen-devel] [PATCH v10] x86/altp2m: support for setting restrictions for an array of pages

2017-12-13 Thread Petre Pircalabu
From: Razvan Cojocaru 

For the default EPT view we have xc_set_mem_access_multi(), which
is able to set an array of pages to an array of access rights with
a single hypercall. However, this functionality was lacking for the
altp2m subsystem, which could only set page restrictions for one
page at a time. This patch addresses the gap.

HVMOP_altp2m_set_mem_access_multi has been added as a HVMOP (as opposed to a
DOMCTL) for consistency with its HVMOP_altp2m_set_mem_access counterpart (and
hence with the original altp2m design, where domains are allowed - with the
proper altp2m access rights - to alter these settings), in the absence of an
official position on the issue from the original altp2m designers.

Signed-off-by: Razvan Cojocaru 
Signed-off-by: Petre Pircalabu 

---

Changed since v2:
* Added support for compat arguments translation

Changed since v3:
* Replaced  __copy_to_guest with __copy_field_to_guest
* Removed the un-needed parentheses.
* Fixed xlat.lst ordering
* Added comment to patch description explaining why the
functionality was added as an HVMOP.
* Guard using XEN_GENERATING_COMPAT_HEADERS the hvmmem_type_t definition.
This will prevent suplicate definitions to be generated for the
compat equivalent.
* Added comment describing the manual translation of
xen_hvm_altp2m_op_t generic fields from compat_hvm_altp2m_op_t.

Changed since v4:
* Changed the mask parameter to 0x3F.
* Split long lines.
* Added "improperly named HVMMEM_(*)" to the comment explaining the
XEN_GENERATING_COMPAT_HEADERS guard.
* Removed typedef and XEN_GUEST_HANDLE for 
xen_hvm_altp2m_set_mem_access_multi.
* Copied the "opaque" field to guest in compat_altp2m_op.
* Added build time test to check if the size of
xen_hvm_altp2m_set_mem_access_multi at least equal to the size of
compat_hvm_altp2m_set_mem_access_multi.

Changed since v5:
* Changed the domid parameter type to uint32_t to match 5b42c82f.
* Added comment to explain why the 0x3F value was chosen.
* Fixed switch indentation in compat_altp2m_op.
* Changed the condition used to check if the opaque field has to
be copied to the guest.
* Added CHECK_hvm_altp2m_op and CHECK_hvm_altp2m_set_mem_access_multi.

Changed since v6:
* Removed trailing semicolon from the definitions of CHECK_hvm_altp2m_op
and CHECK_hvm_altp2m_set_mem_access_multi.
* Removed BUILD_BUG_ON check.
* Added comment describing the reason for manually defining the CHECK_
macros.
* Added ASSERT_UNREACHABLE as the default switch label action in
compat_altp2m_op.
* Added ASSERT(rc == __HYPERVISOR_hvm_op) to make sure the return
code was actually sey by hypercall_create_continuation.

Changed since v7:
* Changed the patch title.

Changed since v8:
* Use sizeof *var for portability
* Added "must be set to 0" to opaque's comment
* Reordered alphabetically the compat headers
* Added blanks to switch statements at the end of each "case" block
* Do not return -EINVAL when nr is 0

Changed since v9:
* Return -EINVAL only if "opaque" is greater than "nr" when handling
HVMOP_altp2m_set_mem_access_multi.
---
 tools/libxc/include/xenctrl.h   |   3 +
 tools/libxc/xc_altp2m.c |  41 
 xen/arch/x86/hvm/hvm.c  | 141 +++-
 xen/include/Makefile|   3 +-
 xen/include/public/hvm/hvm_op.h |  39 +--
 xen/include/xlat.lst|   1 +
 6 files changed, 221 insertions(+), 7 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 666db0b..f171668 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1974,6 +1974,9 @@ int xc_altp2m_set_mem_access(xc_interface *handle, 
uint32_t domid,
 int xc_altp2m_change_gfn(xc_interface *handle, uint32_t domid,
  uint16_t view_id, xen_pfn_t old_gfn,
  xen_pfn_t new_gfn);
+int xc_altp2m_set_mem_access_multi(xc_interface *handle, uint32_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *pages, uint32_t nr);
 
 /** 
  * Mem paging operations.
diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c
index 07fcd18..0f792b5 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -213,3 +213,44 @@ int xc_altp2m_change_gfn(xc_interface *handle, uint32_t 
domid,
 return rc;
 }
 
+int xc_altp2m_set_mem_access_multi(xc_interface *xch, uint32_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *pages, uint32_t nr)
+{
+int rc;
+
+DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
+DECLARE_HYPERCALL_BOUNCE(access, nr * sizeof(*access),
+ XC_HYPERCALL_BUFFER_BO

[Xen-devel] [PATCH 1/9] tools/libxc: Consistent usage of xc_vm_event_* interface

2019-05-30 Thread Petre Pircalabu
Modified xc_mem_paging_enable to use directly xc_vm_event_enable and
moved the ring_page handling from client to libxc (xenpaging).

Restricted vm_event_control usage only to simplest domctls which do
not expect any return values and change xc_vm_event_enable to call do_domctl
directly.

Removed xc_memshr_ring_enable/disable and xc_memshr_domain_resume.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h | 49 +
 tools/libxc/xc_mem_paging.c   | 23 +---
 tools/libxc/xc_memshr.c   | 34 ---
 tools/libxc/xc_monitor.c  | 31 +
 tools/libxc/xc_private.h  |  2 +-
 tools/libxc/xc_vm_event.c | 64 ---
 tools/xenpaging/xenpaging.c   | 42 +++-
 7 files changed, 62 insertions(+), 183 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 538007a..28fdbc0 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1949,7 +1949,7 @@ int xc_altp2m_change_gfn(xc_interface *handle, uint32_t 
domid,
  * Hardware-Assisted Paging (i.e. Intel EPT, AMD NPT). Moreover, AMD NPT
  * support is considered experimental.
  */
-int xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, uint32_t 
*port);
+void *xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, uint32_t 
*port);
 int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id);
 int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id);
 int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id,
@@ -2082,53 +2082,6 @@ int xc_memshr_control(xc_interface *xch,
   uint32_t domid,
   int enable);
 
-/* Create a communication ring in which the hypervisor will place ENOMEM
- * notifications.
- *
- * ENOMEM happens when unsharing pages: a Copy-on-Write duplicate needs to be
- * allocated, and thus the out-of-memory error occurr.
- *
- * For complete examples on how to plumb a notification ring, look into
- * xenpaging or xen-access.
- *
- * On receipt of a notification, the helper should ensure there is memory
- * available to the domain before retrying.
- *
- * If a domain encounters an ENOMEM condition when sharing and this ring
- * has not been set up, the hypervisor will crash the domain.
- *
- * Fails with:
- *  EINVAL if port is NULL
- *  EINVAL if the sharing ring has already been enabled
- *  ENOSYS if no guest gfn has been specified to host the ring via an hvm param
- *  EINVAL if the gfn for the ring has not been populated
- *  ENOENT if the gfn for the ring is paged out, or cannot be unshared
- *  EINVAL if the gfn for the ring cannot be written to
- *  EINVAL if the domain is dying
- *  ENOSPC if an event channel cannot be allocated for the ring
- *  ENOMEM if memory cannot be allocated for internal data structures
- *  EINVAL or EACCESS if the request is denied by the security policy
- */
-
-int xc_memshr_ring_enable(xc_interface *xch, 
-  uint32_t domid,
-  uint32_t *port);
-/* Disable the ring for ENOMEM communication.
- * May fail with EINVAL if the ring was not enabled in the first place.
- */
-int xc_memshr_ring_disable(xc_interface *xch, 
-   uint32_t domid);
-
-/*
- * Calls below return EINVAL if sharing has not been enabled for the domain
- * Calls below return EINVAL if the domain is dying
- */
-/* Once a reponse to an ENOMEM notification is prepared, the tool can
- * notify the hypervisor to re-schedule the faulting vcpu of the domain with an
- * event channel kick and/or this call. */
-int xc_memshr_domain_resume(xc_interface *xch,
-uint32_t domid);
-
 /* Select a page for sharing. 
  *
  * A 64 bit opaque handle will be stored in handle.  The hypervisor ensures
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index a067706..08468fb 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -37,35 +37,26 @@ static int xc_mem_paging_memop(xc_interface *xch, uint32_t 
domain_id,
 return do_memory_op(xch, XENMEM_paging_op, &mpo, sizeof(mpo));
 }
 
-int xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id,
- uint32_t *port)
+void *xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id,
+   uint32_t *port)
 {
-if ( !port )
-{
-errno = EINVAL;
-return -1;
-}
-
-return xc_vm_event_control(xch, domain_id,
-   XEN_VM_EVENT_ENABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING,
-   port);
+return xc_vm_event_enable(xch, domain_id,
+  XEN_DOMCTL_VM_EVENT_OP_PAGING,
+  port);
 }
 
 int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domai

[Xen-devel] [PATCH 6/9] vm_event: Move struct vm_event_domain to vm_event.c

2019-05-30 Thread Petre Pircalabu
The vm_event_domain members are not accessed outside vm_event.c so it's
better to hide de implementation details.

Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c   | 27 +++
 xen/include/xen/sched.h | 27 +--
 2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 3e87bbc..02c5853 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -39,6 +39,33 @@
 #define vm_event_ring_lock(_ved)   spin_lock(&(_ved)->ring_lock)
 #define vm_event_ring_unlock(_ved) spin_unlock(&(_ved)->ring_lock)
 
+/* VM event */
+struct vm_event_domain
+{
+/* Domain reference */
+struct domain *d;
+/* ring lock */
+spinlock_t ring_lock;
+/* The ring has 64 entries */
+unsigned char foreign_producers;
+unsigned char target_producers;
+/* shared ring page */
+void *ring_page;
+struct page_info *ring_pg_struct;
+/* front-end ring */
+vm_event_front_ring_t front_ring;
+/* event channel port (vcpu0 only) */
+int xen_port;
+/* vm_event bit for vcpu->pause_flags */
+int pause_flag;
+/* list of vcpus waiting for room in the ring */
+struct waitqueue_head wq;
+/* the number of vCPUs blocked */
+unsigned int blocked;
+/* The last vcpu woken up */
+unsigned int last_vcpu_wake_up;
+};
+
 static int vm_event_enable(
 struct domain *d,
 struct xen_domctl_vm_event_op *vec,
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 7dee022..207fbc4 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -279,32 +279,7 @@ struct vcpu
 #define domain_lock(d) spin_lock_recursive(&(d)->domain_lock)
 #define domain_unlock(d) spin_unlock_recursive(&(d)->domain_lock)
 
-/* VM event */
-struct vm_event_domain
-{
-/* Domain reference */
-struct domain *d;
-/* ring lock */
-spinlock_t ring_lock;
-/* The ring has 64 entries */
-unsigned char foreign_producers;
-unsigned char target_producers;
-/* shared ring page */
-void *ring_page;
-struct page_info *ring_pg_struct;
-/* front-end ring */
-vm_event_front_ring_t front_ring;
-/* event channel port (vcpu0 only) */
-int xen_port;
-/* vm_event bit for vcpu->pause_flags */
-int pause_flag;
-/* list of vcpus waiting for room in the ring */
-struct waitqueue_head wq;
-/* the number of vCPUs blocked */
-unsigned int blocked;
-/* The last vcpu woken up */
-unsigned int last_vcpu_wake_up;
-};
+struct vm_event_domain;
 
 struct evtchn_port_ops;
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH 4/9] vm_event: Remove "ring" suffix from vm_event_check_ring

2019-05-30 Thread Petre Pircalabu
Decouple implementation from interface to allow vm_event_check to be
used regardless of the vm_event underlying implementation.

Signed-off-by: Petre Pircalabu 
---
 xen/arch/arm/mem_access.c |  2 +-
 xen/arch/x86/mm/mem_access.c  |  4 ++--
 xen/arch/x86/mm/mem_paging.c  |  2 +-
 xen/common/mem_access.c   |  2 +-
 xen/common/vm_event.c | 24 
 xen/drivers/passthrough/pci.c |  2 +-
 xen/include/xen/vm_event.h|  4 ++--
 7 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/mem_access.c b/xen/arch/arm/mem_access.c
index 3e36202..d54760b 100644
--- a/xen/arch/arm/mem_access.c
+++ b/xen/arch/arm/mem_access.c
@@ -290,7 +290,7 @@ bool p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const 
struct npfec npfec)
 }
 
 /* Otherwise, check if there is a vm_event monitor subscriber */
-if ( !vm_event_check_ring(v->domain->vm_event_monitor) )
+if ( !vm_event_check(v->domain->vm_event_monitor) )
 {
 /* No listener */
 if ( p2m->access_required )
diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c
index 0144f92..640352e 100644
--- a/xen/arch/x86/mm/mem_access.c
+++ b/xen/arch/x86/mm/mem_access.c
@@ -182,7 +182,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 gfn_unlock(p2m, gfn, 0);
 
 /* Otherwise, check if there is a memory event listener, and send the 
message along */
-if ( !vm_event_check_ring(d->vm_event_monitor) || !req_ptr )
+if ( !vm_event_check(d->vm_event_monitor) || !req_ptr )
 {
 /* No listener */
 if ( p2m->access_required )
@@ -210,7 +210,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 return true;
 }
 }
-if ( vm_event_check_ring(d->vm_event_monitor) &&
+if ( vm_event_check(d->vm_event_monitor) &&
  d->arch.monitor.inguest_pagefault_disabled &&
  npfec.kind != npfec_kind_with_gla ) /* don't send a mem_event */
 {
diff --git a/xen/arch/x86/mm/mem_paging.c b/xen/arch/x86/mm/mem_paging.c
index 54a94fa..dc2a59a 100644
--- a/xen/arch/x86/mm/mem_paging.c
+++ b/xen/arch/x86/mm/mem_paging.c
@@ -44,7 +44,7 @@ int 
mem_paging_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_paging_op_t) arg)
 goto out;
 
 rc = -ENODEV;
-if ( unlikely(!vm_event_check_ring(d->vm_event_paging)) )
+if ( unlikely(!vm_event_check(d->vm_event_paging)) )
 goto out;
 
 switch( mpo.op )
diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c
index 010e6f8..51e4e2b 100644
--- a/xen/common/mem_access.c
+++ b/xen/common/mem_access.c
@@ -52,7 +52,7 @@ int mem_access_memop(unsigned long cmd,
 goto out;
 
 rc = -ENODEV;
-if ( unlikely(!vm_event_check_ring(d->vm_event_monitor)) )
+if ( unlikely(!vm_event_check(d->vm_event_monitor)) )
 goto out;
 
 switch ( mao.op )
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 3505589..1dd3e48 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -196,7 +196,7 @@ void vm_event_wake(struct domain *d, struct vm_event_domain 
*ved)
 
 static int vm_event_disable(struct domain *d, struct vm_event_domain **ved)
 {
-if ( vm_event_check_ring(*ved) )
+if ( vm_event_check(*ved) )
 {
 struct vcpu *v;
 
@@ -277,7 +277,7 @@ void vm_event_put_request(struct domain *d,
 RING_IDX req_prod;
 struct vcpu *curr = current;
 
-if( !vm_event_check_ring(ved))
+if( !vm_event_check(ved))
 return;
 
 if ( curr->domain != d )
@@ -380,7 +380,7 @@ static int vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
  */
 ASSERT(d != current->domain);
 
-if ( unlikely(!vm_event_check_ring(ved)) )
+if ( unlikely(!vm_event_check(ved)) )
  return -ENODEV;
 
 /* Pull all responses off the ring. */
@@ -452,7 +452,7 @@ static int vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
 
 void vm_event_cancel_slot(struct domain *d, struct vm_event_domain *ved)
 {
-if( !vm_event_check_ring(ved) )
+if( !vm_event_check(ved) )
 return;
 
 vm_event_ring_lock(ved);
@@ -501,7 +501,7 @@ static int vm_event_wait_slot(struct vm_event_domain *ved)
 return rc;
 }
 
-bool vm_event_check_ring(struct vm_event_domain *ved)
+bool vm_event_check(struct vm_event_domain *ved)
 {
 return (ved && ved->ring_page);
 }
@@ -521,7 +521,7 @@ bool vm_event_check_ring(struct vm_event_domain *ved)
 int __vm_event_claim_slot(struct domain *d, struct vm_event_domain *ved,
   bool allow_sleep)
 {
-if ( !vm_event_check_ring(ved) )
+if ( !vm_event_check(ved) )
 return -EOPNOTSUPP;
 
 if ( (current->domain == d) && allow_sleep )
@@ -556,7 +556,7 @@ static void mem_sharing_notification(struct vcpu *v, 
unsigned int port)
 void vm_event_cleanup(struct domain *d)
 {
 #ifdef CONFIG_HAS_MEM_

[Xen-devel] [PATCH 7/9] vm_event: Decouple implementation details from interface.

2019-05-30 Thread Petre Pircalabu
To accommodate a second implementation of the vm_event subsystem, the
current one (ring) should be decoupled from the xen/vm_event.h interface.

Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c  | 407 ++---
 xen/include/xen/vm_event.h |  56 ++-
 2 files changed, 252 insertions(+), 211 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 02c5853..1d85f3e 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -35,17 +35,13 @@
 #define xen_rmb()  smp_rmb()
 #define xen_wmb()  smp_wmb()
 
-#define vm_event_ring_lock_init(_ved)  spin_lock_init(&(_ved)->ring_lock)
-#define vm_event_ring_lock(_ved)   spin_lock(&(_ved)->ring_lock)
-#define vm_event_ring_unlock(_ved) spin_unlock(&(_ved)->ring_lock)
+#define to_ring(_ved) container_of((_ved), struct vm_event_ring_domain, ved)
 
-/* VM event */
-struct vm_event_domain
+/* VM event ring implementation */
+struct vm_event_ring_domain
 {
-/* Domain reference */
-struct domain *d;
-/* ring lock */
-spinlock_t ring_lock;
+/* VM event domain */
+struct vm_event_domain ved;
 /* The ring has 64 entries */
 unsigned char foreign_producers;
 unsigned char target_producers;
@@ -56,8 +52,6 @@ struct vm_event_domain
 vm_event_front_ring_t front_ring;
 /* event channel port (vcpu0 only) */
 int xen_port;
-/* vm_event bit for vcpu->pause_flags */
-int pause_flag;
 /* list of vcpus waiting for room in the ring */
 struct waitqueue_head wq;
 /* the number of vCPUs blocked */
@@ -66,48 +60,54 @@ struct vm_event_domain
 unsigned int last_vcpu_wake_up;
 };
 
-static int vm_event_enable(
+static const struct vm_event_ops vm_event_ring_ops;
+
+static int vm_event_ring_enable(
 struct domain *d,
 struct xen_domctl_vm_event_op *vec,
-struct vm_event_domain **ved,
+struct vm_event_domain **_ved,
 int pause_flag,
 int param,
 xen_event_channel_notification_t notification_fn)
 {
 int rc;
 unsigned long ring_gfn = d->arch.hvm.params[param];
+struct vm_event_ring_domain *impl;
 
-if ( !*ved )
-*ved = xzalloc(struct vm_event_domain);
-if ( !*ved )
+impl = (*_ved) ? to_ring(*_ved) :
+xzalloc(struct vm_event_ring_domain);
+if ( !impl )
 return -ENOMEM;
 
 /* Only one helper at a time. If the helper crashed,
  * the ring is in an undefined state and so is the guest.
  */
-if ( (*ved)->ring_page )
-return -EBUSY;;
+if ( impl->ring_page )
+return -EBUSY;
 
 /* The parameter defaults to zero, and it should be
  * set to something */
 if ( ring_gfn == 0 )
 return -EOPNOTSUPP;
 
-vm_event_ring_lock_init(*ved);
-vm_event_ring_lock(*ved);
+spin_lock_init(&impl->ved.lock);
+spin_lock(&impl->ved.lock);
 
 rc = vm_event_init_domain(d);
 
 if ( rc < 0 )
 goto err;
 
-rc = prepare_ring_for_helper(d, ring_gfn, &(*ved)->ring_pg_struct,
- &(*ved)->ring_page);
+impl->ved.d = d;
+impl->ved.ops = &vm_event_ring_ops;
+
+rc = prepare_ring_for_helper(d, ring_gfn, &impl->ring_pg_struct,
+ &impl->ring_page);
 if ( rc < 0 )
 goto err;
 
 /* Set the number of currently blocked vCPUs to 0. */
-(*ved)->blocked = 0;
+impl->blocked = 0;
 
 /* Allocate event channel */
 rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
@@ -115,37 +115,37 @@ static int vm_event_enable(
 if ( rc < 0 )
 goto err;
 
-(*ved)->xen_port = vec->u.enable.port = rc;
+impl->xen_port = vec->u.enable.port = rc;
 
 /* Prepare ring buffer */
-FRONT_RING_INIT(&(*ved)->front_ring,
-(vm_event_sring_t *)(*ved)->ring_page,
+FRONT_RING_INIT(&impl->front_ring,
+(vm_event_sring_t *)impl->ring_page,
 PAGE_SIZE);
 
 /* Save the pause flag for this particular ring. */
-(*ved)->pause_flag = pause_flag;
+impl->ved.pause_flag = pause_flag;
 
 /* Initialize the last-chance wait queue. */
-init_waitqueue_head(&(*ved)->wq);
+init_waitqueue_head(&impl->wq);
 
-vm_event_ring_unlock(*ved);
+spin_unlock(&impl->ved.lock);
+*_ved = &impl->ved;
 return 0;
 
  err:
-destroy_ring_for_helper(&(*ved)->ring_page,
-(*ved)->ring_pg_struct);
-vm_event_ring_unlock(*ved);
-xfree(*ved);
-*ved = NULL;
+destroy_ring_for_helper(&impl->ring_page,
+impl->ring_pg_struct);
+spin_unlock(&impl->ved.lock);
+XFREE(impl);
 
 return rc;
 }
 
-static unsigned int vm_event_ring_available(struct vm_event_domain *ved)
+stat

[Xen-devel] [PATCH 0/9] Per vcpu vm_event channels

2019-05-30 Thread Petre Pircalabu
This patchset adds a new mechanism of sending synchronous vm_event
requests and handling vm_event responses without using a ring.
As each synchronous request pauses the vcpu until the corresponding
response is handled, it can be stored in a slotted memory buffer
(one per vcpu) shared between the hypervisor and the controlling domain.

The main advantages of this approach are:
- the ability to dynamicaly allocate the necessary memory used to hold
the requests/responses (the size of vm_event_request_t/vm_event_response_t
can grow unrestricted by the ring's one page limitation)
- the ring's waitqueue logic is unnecessary in this case because the
vcpu sending the request is blocked until a response is received.



Petre Pircalabu (9):
  tools/libxc: Consistent usage of xc_vm_event_* interface
  vm_event: Define VM_EVENT type
  vm_event: Make ‘local’ functions ‘static’
  vm_event: Remove "ring" suffix from vm_event_check_ring
  vm_event: Simplify vm_event interface
  vm_event: Move struct vm_event_domain to vm_event.c
  vm_event: Decouple implementation details from interface.
  vm_event: Add vm_event_ng interface
  xen-access: Add support for vm_event_ng interface

 tools/libxc/include/xenctrl.h|  56 +---
 tools/libxc/xc_mem_paging.c  |  23 +-
 tools/libxc/xc_memshr.c  |  34 ---
 tools/libxc/xc_monitor.c |  46 ++-
 tools/libxc/xc_private.h |  16 +-
 tools/libxc/xc_vm_event.c| 175 +++-
 tools/tests/xen-access/Makefile  |   7 +-
 tools/tests/xen-access/vm-event-ng.c | 210 ++
 tools/tests/xen-access/vm-event.c| 193 +
 tools/tests/xen-access/xen-access.c  | 408 ++-
 tools/tests/xen-access/xen-access.h  |  91 ++
 tools/xenpaging/xenpaging.c  |  42 +--
 xen/arch/arm/mem_access.c|   2 +-
 xen/arch/x86/mm.c|   5 +
 xen/arch/x86/mm/mem_access.c |   4 +-
 xen/arch/x86/mm/mem_paging.c |   2 +-
 xen/arch/x86/mm/mem_sharing.c|   5 +-
 xen/arch/x86/mm/p2m.c|  11 +-
 xen/common/Makefile  |   1 +
 xen/common/domctl.c  |   7 +
 xen/common/mem_access.c  |   2 +-
 xen/common/monitor.c |   4 +-
 xen/common/vm_event.c| 527 ++-
 xen/common/vm_event_ng.c | 449 +
 xen/drivers/passthrough/pci.c|   2 +-
 xen/include/public/domctl.h  | 101 +++
 xen/include/public/memory.h  |   2 +
 xen/include/public/vm_event.h|  47 
 xen/include/xen/sched.h  |  25 +-
 xen/include/xen/vm_event.h   |  80 +-
 30 files changed, 1720 insertions(+), 857 deletions(-)
 create mode 100644 tools/tests/xen-access/vm-event-ng.c
 create mode 100644 tools/tests/xen-access/vm-event.c
 create mode 100644 tools/tests/xen-access/xen-access.h
 create mode 100644 xen/common/vm_event_ng.c

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH 5/9] vm_event: Simplify vm_event interface

2019-05-30 Thread Petre Pircalabu
The domain reference can be part of the vm_event_domain structure
because for every call to a vm_event interface function both the latter
and it's corresponding domain are passed as parameters.

Affected functions:
- __vm_event_claim_slot / vm_event_claim_slot / vm_event_claim_slot_nosleep
- vm_event_cancel_slot
- vm_event_put_request

Signed-off-by: Petre Pircalabu 
---
 xen/arch/x86/mm/mem_sharing.c |  5 ++---
 xen/arch/x86/mm/p2m.c | 11 +--
 xen/common/monitor.c  |  4 ++--
 xen/common/vm_event.c | 37 ++---
 xen/include/xen/sched.h   |  2 ++
 xen/include/xen/vm_event.h| 17 +++--
 6 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index f16a3f5..9d80389 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -557,8 +557,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 .u.mem_sharing.p2mt = p2m_ram_shared
 };
 
-if ( (rc = __vm_event_claim_slot(d, 
-d->vm_event_share, allow_sleep)) < 0 )
+if ( (rc = __vm_event_claim_slot(d->vm_event_share, allow_sleep)) < 0 )
 return rc;
 
 if ( v->domain == d )
@@ -567,7 +566,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 vm_event_vcpu_pause(v);
 }
 
-vm_event_put_request(d, d->vm_event_share, &req);
+vm_event_put_request(d->vm_event_share, &req);
 
 return 0;
 }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4c99548..625fc9b 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1652,7 +1652,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
  * correctness of the guest execution at this point.  If this is the only
  * page that happens to be paged-out, we'll be okay..  but it's likely the
  * guest will crash shortly anyways. */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
+int rc = vm_event_claim_slot(d->vm_event_paging);
 if ( rc < 0 )
 return;
 
@@ -1666,7 +1666,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
 /* Evict will fail now, tag this request for pager */
 req.u.mem_paging.flags |= MEM_PAGING_EVICT_FAIL;
 
-vm_event_put_request(d, d->vm_event_paging, &req);
+vm_event_put_request(d->vm_event_paging, &req);
 }
 
 /**
@@ -1704,8 +1704,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
 /* We're paging. There should be a ring */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
-
+int rc = vm_event_claim_slot(d->vm_event_paging);
 if ( rc == -EOPNOTSUPP )
 {
 gdprintk(XENLOG_ERR, "Domain %hu paging gfn %lx yet no ring "
@@ -1746,7 +1745,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 {
 /* gfn is already on its way back and vcpu is not paused */
 out_cancel:
-vm_event_cancel_slot(d, d->vm_event_paging);
+vm_event_cancel_slot(d->vm_event_paging);
 return;
 }
 
@@ -1754,7 +1753,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 req.u.mem_paging.p2mt = p2mt;
 req.vcpu_id = v->vcpu_id;
 
-vm_event_put_request(d, d->vm_event_paging, &req);
+vm_event_put_request(d->vm_event_paging, &req);
 }
 
 /**
diff --git a/xen/common/monitor.c b/xen/common/monitor.c
index d5c9ff1..b8d33c4 100644
--- a/xen/common/monitor.c
+++ b/xen/common/monitor.c
@@ -93,7 +93,7 @@ int monitor_traps(struct vcpu *v, bool sync, 
vm_event_request_t *req)
 int rc;
 struct domain *d = v->domain;
 
-rc = vm_event_claim_slot(d, d->vm_event_monitor);
+rc = vm_event_claim_slot(d->vm_event_monitor);
 switch ( rc )
 {
 case 0:
@@ -125,7 +125,7 @@ int monitor_traps(struct vcpu *v, bool sync, 
vm_event_request_t *req)
 }
 
 vm_event_fill_regs(req);
-vm_event_put_request(d, d->vm_event_monitor, req);
+vm_event_put_request(d->vm_event_monitor, req);
 
 return rc;
 }
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 1dd3e48..3e87bbc 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -131,10 +131,11 @@ static unsigned int vm_event_ring_available(struct 
vm_event_domain *ved)
  * but need to be resumed where the ring is capable of processing at least
  * one event from them.
  */
-static void vm_event_wake_blocked(struct domain *d, struct vm_event_domain 
*ved)
+static void vm_event_wake_blocked(struct vm_event_domain *ved)
 {
 struct vcpu *v;
 unsigned int avail_req = vm_event_ring_available(ved);
+struct domain *d = ved->d;
 
 if ( avail_req == 0 || ved->blocked == 0 )
 return;
@@ -171,7 +172,7 @@ static void vm_

[Xen-devel] [PATCH 8/9] vm_event: Add vm_event_ng interface

2019-05-30 Thread Petre Pircalabu
In high throughput introspection scenarios where lots of monitor
vm_events are generated, the ring buffer can fill up before the monitor
application gets a chance to handle all the requests thus blocking
other vcpus which will have to wait for a slot to become available.

This patch adds support for a different mechanism to handle synchronous
vm_event requests / responses. As each synchronous request pauses the
vcpu until the corresponding response is handled, it can be stored in
a slotted memory buffer (one per vcpu) shared between the hypervisor and
the controlling domain.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |   6 +
 tools/libxc/xc_monitor.c  |  15 ++
 tools/libxc/xc_private.h  |   8 +
 tools/libxc/xc_vm_event.c |  53 +
 xen/arch/x86/mm.c |   5 +
 xen/common/Makefile   |   1 +
 xen/common/domctl.c   |   7 +
 xen/common/vm_event.c |  94 -
 xen/common/vm_event_ng.c  | 449 ++
 xen/include/public/domctl.h   |  20 ++
 xen/include/public/memory.h   |   2 +
 xen/include/public/vm_event.h |  16 ++
 xen/include/xen/vm_event.h|  10 +
 13 files changed, 642 insertions(+), 44 deletions(-)
 create mode 100644 xen/common/vm_event_ng.c

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 943b933..c36b623 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1993,6 +1993,7 @@ int xc_get_mem_access(xc_interface *xch, uint32_t 
domain_id,
  * Returns the VM_EVENT_INTERFACE version.
  */
 int xc_vm_event_get_version(xc_interface *xch);
+int xc_vm_event_ng_get_version(xc_interface *xch);
 
 /***
  * Monitor control operations.
@@ -2007,6 +2008,11 @@ int xc_vm_event_get_version(xc_interface *xch);
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port);
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id);
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id);
+
+/* Monitor NG interface */
+int xc_monitor_ng_create(xc_interface *xch, uint32_t domain_id);
+int xc_monitor_ng_destroy(xc_interface *xch, uint32_t domain_id);
+int xc_monitor_ng_set_state(xc_interface *xch, uint32_t domain_id, bool 
enabled);
 /*
  * Get a bitmap of supported monitor events in the form
  * (1 << XEN_DOMCTL_MONITOR_EVENT_*).
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 718fe8b..4c7ef2b 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -265,6 +265,21 @@ int xc_monitor_emul_unimplemented(xc_interface *xch, 
uint32_t domain_id,
 return do_domctl(xch, &domctl);
 }
 
+int xc_monitor_ng_create(xc_interface *xch, uint32_t domain_id)
+{
+return xc_vm_event_ng_create(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR);
+}
+
+int xc_monitor_ng_destroy(xc_interface *xch, uint32_t domain_id)
+{
+return xc_vm_event_ng_destroy(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR);
+}
+
+int xc_monitor_ng_set_state(xc_interface *xch, uint32_t domain_id, bool 
enabled)
+{
+return xc_vm_event_ng_set_state(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR, 
enabled);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 482451c..1904a1e 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -420,6 +420,14 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
+/**
+ * VM_EVENT NG operations. Internal use only.
+ */
+int xc_vm_event_ng_create(xc_interface *xch, uint32_t domain_id, int type);
+int xc_vm_event_ng_destroy(xc_interface *xch, uint32_t domain_id, int type);
+int xc_vm_event_ng_set_state(xc_interface *xch, uint32_t domain_id, int type, 
bool enabled);
+
+
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
 
 #endif /* __XC_PRIVATE_H__ */
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index 3b1018b..07243a6 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -154,6 +154,59 @@ int xc_vm_event_get_version(xc_interface *xch)
 return rc;
 }
 
+int xc_vm_event_ng_get_version(xc_interface *xch)
+{
+DECLARE_DOMCTL;
+int rc;
+
+domctl.cmd = XEN_DOMCTL_vm_event_ng_op;
+domctl.domain = DOMID_INVALID;
+domctl.u.vm_event_op.op = XEN_VM_EVENT_NG_GET_VERSION;
+domctl.u.vm_event_op.type = XEN_VM_EVENT_TYPE_MONITOR;
+
+rc = do_domctl(xch, &domctl);
+if ( !rc )
+rc = domctl.u.vm_event_ng_op.u.version;
+return rc;
+}
+
+int xc_vm_event_ng_create(xc_interface *xch, uint32_t domain_id, int type)
+{
+DECLARE_DOMCTL;
+
+domctl.cmd = XEN_DOMCTL_vm_event_ng_op;
+domctl.domain = domain_id;
+domctl.u.vm_event_ng_op.op = XEN_VM_EVENT_NG_CREATE;
+domctl.u.vm_event_ng_op.type = type;
+
+return do_domctl(xch, &domctl);
+}
+
+int xc_v

[Xen-devel] [PATCH 9/9] xen-access: Add support for vm_event_ng interface

2019-05-30 Thread Petre Pircalabu
Split xen-access in order to accommodate both vm_event interfaces
(legacy and NG). By default, the legacy vm_event is selected but
this can be changed by adding the '-n' flag in the command line.

Signed-off-by: Petre Pircalabu 
---
 tools/tests/xen-access/Makefile  |   7 +-
 tools/tests/xen-access/vm-event-ng.c | 210 ++
 tools/tests/xen-access/vm-event.c| 193 +
 tools/tests/xen-access/xen-access.c  | 408 +--
 tools/tests/xen-access/xen-access.h  |  91 
 5 files changed, 644 insertions(+), 265 deletions(-)
 create mode 100644 tools/tests/xen-access/vm-event-ng.c
 create mode 100644 tools/tests/xen-access/vm-event.c
 create mode 100644 tools/tests/xen-access/xen-access.h

diff --git a/tools/tests/xen-access/Makefile b/tools/tests/xen-access/Makefile
index 131c9f3..17760d8 100644
--- a/tools/tests/xen-access/Makefile
+++ b/tools/tests/xen-access/Makefile
@@ -7,6 +7,7 @@ CFLAGS += -DXC_WANT_COMPAT_DEVICEMODEL_API
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_libxenguest)
 CFLAGS += $(CFLAGS_libxenevtchn)
+CFLAGS += $(CFLAGS_libxenforeignmemory)
 CFLAGS += $(CFLAGS_xeninclude)
 
 TARGETS-y := xen-access
@@ -25,8 +26,10 @@ clean:
 .PHONY: distclean
 distclean: clean
 
-xen-access: xen-access.o Makefile
-   $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) 
$(LDLIBS_libxenevtchn)
+OBJS = xen-access.o vm-event.o vm-event-ng.o
+
+xen-access: $(OBJS) Makefile
+   $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS_libxenctrl) 
$(LDLIBS_libxenguest) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenforeignmemory)
 
 install uninstall:
 
diff --git a/tools/tests/xen-access/vm-event-ng.c 
b/tools/tests/xen-access/vm-event-ng.c
new file mode 100644
index 000..9177cfc
--- /dev/null
+++ b/tools/tests/xen-access/vm-event-ng.c
@@ -0,0 +1,210 @@
+/*
+ * vm-event-ng.c
+ *
+ * Copyright (c) 2019 Bitdefender S.R.L.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "xen-access.h"
+
+#ifndef PFN_UP
+#define PFN_UP(x) (((x) + XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT)
+#endif /* PFN_UP */
+
+typedef struct vm_event_channels
+{
+vm_event_t vme;
+int num_vcpus;
+xenforeignmemory_handle *fmem;
+xenforeignmemory_resource_handle *fres;
+struct vm_event_slot *slots;
+int ports[0];
+} vm_event_channels_t;
+
+#define to_channels(_vme) container_of((_vme), vm_event_channels_t, vme)
+
+static int vm_event_channels_init(xc_interface *xch, xenevtchn_handle *xce,
+  domid_t domain_id, vm_event_ops_t *ops,
+  vm_event_t **vm_event)
+{
+vm_event_channels_t *impl = NULL;
+int rc, i, num_vcpus;
+xc_dominfo_t info;
+unsigned long nr_frames;
+
+/* Get the numbers of vcpus */
+rc = xc_domain_getinfo(xch, domain_id, 1, &info);
+if ( rc != 1 )
+{
+ERROR("xc_domain_getinfo failed. rc = %d\n", rc);
+return rc;
+}
+
+num_vcpus = info.max_vcpu_id + 1;
+
+impl = (vm_event_channels_t *)calloc(1, sizeof(vm_event_channels_t) +
+num_vcpus * sizeof(int));
+if ( !impl )
+return -ENOMEM;
+
+impl->num_vcpus = num_vcpus;
+
+impl->fmem = xenforeignmemory_open(0,0);
+if ( !impl->fmem )
+{
+rc = -errno;
+goto err;
+}
+
+rc = xc_monitor_ng_create(xch, domain_id);
+if ( rc )
+{
+ERROR("Failed to enable monitor");
+goto err;
+}
+
+nr_frames = PFN_UP(num_vcpus * sizeof(struct vm_event_slot));
+
+impl->fres = xenforeignmemory_map_resource(impl->fmem, domain_id,
+   XENMEM_resource_vm_event,
+   XEN_VM_EVENT_TYPE_MO

[Xen-devel] [PATCH 2/9] vm_event: Define VM_EVENT type

2019-05-30 Thread Petre Pircalabu
Define the type for each of the supported vm_event rings (paging,
monitor and sharing) and replace the ring param field with this type.

Replace XEN_DOMCTL_VM_EVENT_OP_ occurrences with their corresponding
XEN_VM_EVENT_TYPE_ counterpart.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |  1 +
 tools/libxc/xc_mem_paging.c   |  6 ++--
 tools/libxc/xc_monitor.c  |  6 ++--
 tools/libxc/xc_private.h  |  8 ++---
 tools/libxc/xc_vm_event.c | 70 ++---
 xen/common/vm_event.c | 12 +++
 xen/include/public/domctl.h   | 81 ++-
 xen/include/public/vm_event.h | 31 +
 8 files changed, 93 insertions(+), 122 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 28fdbc0..943b933 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "xentoollog.h"
 
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index 08468fb..37a8224 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -41,7 +41,7 @@ void *xc_mem_paging_enable(xc_interface *xch, uint32_t 
domain_id,
uint32_t *port)
 {
 return xc_vm_event_enable(xch, domain_id,
-  XEN_DOMCTL_VM_EVENT_OP_PAGING,
+  XEN_VM_EVENT_TYPE_PAGING,
   port);
 }
 
@@ -49,14 +49,14 @@ int xc_mem_paging_disable(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING);
+   XEN_VM_EVENT_TYPE_PAGING);
 }
 
 int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING);
+   XEN_VM_EVENT_TYPE_PAGING);
 }
 
 int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id, uint64_t gfn)
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index d190c29..718fe8b 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -35,7 +35,7 @@ void *xc_monitor_enable(xc_interface *xch, uint32_t 
domain_id, uint32_t *port)
 }
 
 buffer = xc_vm_event_enable(xch, domain_id,
-HVM_PARAM_MONITOR_RING_PFN,
+XEN_VM_EVENT_TYPE_MONITOR,
 port);
 saved_errno = errno;
 if ( xc_domain_unpause(xch, domain_id) )
@@ -53,14 +53,14 @@ int xc_monitor_disable(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR);
+   XEN_VM_EVENT_TYPE_MONITOR);
 }
 
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR);
+   XEN_VM_EVENT_TYPE_MONITOR);
 }
 
 int xc_monitor_get_capabilities(xc_interface *xch, uint32_t domain_id,
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 663e78b..482451c 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -412,12 +412,12 @@ int xc_ffs64(uint64_t x);
  * vm_event operations. Internal use only.
  */
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
-unsigned int mode);
+unsigned int type);
 /*
- * Enables vm_event and returns the mapped ring page indicated by param.
- * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN
+ * Enables vm_event and returns the mapped ring page indicated by type.
+ * type can be XEN_VM_EVENT_TYPE_(PAGING/MONITOR/SHARING)
  */
-void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param,
+void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index ea10366..3b1018b 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -23,29 +23,54 @@
 #include "xc_private.h"
 
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
-unsigned int mode)
+unsigned int type)
 {
 DECLARE_DOMCTL;
 
 domctl.cmd = XEN_DOMCTL_vm_event_op;
 domctl.domain = domain_id;
 domctl.u.vm_event_op.op = op;
-domctl.u.vm_

[Xen-devel] [PATCH 3/9] vm_event: Make ‘local’ functions ‘static’

2019-05-30 Thread Petre Pircalabu
vm_event_get_response, vm_event_resume, and vm_event_mark_and_pause are
used only in xen/common/vm_event.c.

Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c  | 6 +++---
 xen/include/xen/vm_event.h | 3 ---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index d7c5f22..3505589 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -252,7 +252,7 @@ static inline void vm_event_release_slot(struct domain *d,
  * vm_event_mark_and_pause() tags vcpu and put it to sleep.
  * The vcpu will resume execution in vm_event_wake_blocked().
  */
-void vm_event_mark_and_pause(struct vcpu *v, struct vm_event_domain *ved)
+static void vm_event_mark_and_pause(struct vcpu *v, struct vm_event_domain 
*ved)
 {
 if ( !test_and_set_bit(ved->pause_flag, &v->pause_flags) )
 {
@@ -324,8 +324,8 @@ void vm_event_put_request(struct domain *d,
 notify_via_xen_event_channel(d, ved->xen_port);
 }
 
-int vm_event_get_response(struct domain *d, struct vm_event_domain *ved,
-  vm_event_response_t *rsp)
+static int vm_event_get_response(struct domain *d, struct vm_event_domain *ved,
+ vm_event_response_t *rsp)
 {
 vm_event_front_ring_t *front_ring;
 RING_IDX rsp_cons;
diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h
index 53af2d5..7f6fb6d 100644
--- a/xen/include/xen/vm_event.h
+++ b/xen/include/xen/vm_event.h
@@ -64,9 +64,6 @@ void vm_event_cancel_slot(struct domain *d, struct 
vm_event_domain *ved);
 void vm_event_put_request(struct domain *d, struct vm_event_domain *ved,
   vm_event_request_t *req);
 
-int vm_event_get_response(struct domain *d, struct vm_event_domain *ved,
-  vm_event_response_t *rsp);
-
 int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec,
 XEN_GUEST_HANDLE_PARAM(void) u_domctl);
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v2 1/4] xtf-runner: split into logical components

2018-12-28 Thread Petre Pircalabu
Split the xtf-runner script file into multiple modules in order to
support multiple test types.

Features:
  - 2 abstract types (TestInfo and TestInstance) to represent the
  test information (info.json) and, respectively to implement the test
  execution.
TestInfo has to implement the "all_instances" method to create the
list of TestInstance objects.
TestInstance has to implement "set_up", "run", and "clean-up"
methods.
  - TestResult - represents an XTF test result (SUCCESS, SKIP, ERROR,
  FAILURE, CRASH). The values should be kept in sync with the C code
  from report.h
  - Dynamic test class loading. Each info.json shoudl contain a
  "class_name" field which specifies the test info class describing the
  test. This value defaults to "xtf.domu_test.DomuTestInfo"
  - custom test info parameters. info.json can have the "extra"
  field, implemented as a dictionary,  which contains parameters
  specific for a certain test info class.
e.g. TEST-EXTRA-INFO := arg1='--address=0x8000 --id=4' arg2=42
  - logger class (print depending on the quiet field)
  - DomuTestInfo/DomuTest instance. Simple test which loads a XEN DomU
  and checks the output for a specific pattern.
  - toolstack abstraction using a wrapper class (e.g.
  (xtf.xl_domu.XLDomU)

Signed-off-by: Petre Pircalabu 
---
 build/gen.mk  |  13 ++-
 build/mkinfo.py   |  84 +++---
 xtf-runner| 334 +-
 xtf/__init__.py   |  12 ++
 xtf/domu_test.py  | 179 +
 xtf/exceptions.py |   6 +
 xtf/logger.py |  23 
 xtf/suite.py  |  97 
 xtf/test.py   | 139 +++
 xtf/xl_domu.py| 121 
 10 files changed, 687 insertions(+), 321 deletions(-)
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/xl_domu.py

diff --git a/build/gen.mk b/build/gen.mk
index 8d7a6bf..c19ca6a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -27,12 +27,23 @@ else
 TEST-CFGS := $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME).cfg)
 endif
 
+CLASS ?= "xtf.domu_test.DomuTestInfo"
+
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
 
+MKINFO-OPTS := -n "$(NAME)"
+MKINFO-OPTS += -c "$(CLASS)"
+MKINFO-OPTS += -t "$(CATEGORY)"
+MKINFO-OPTS += -e "$(TEST-ENVS)"
+MKINFO-OPTS += -v "$(VARY-CFG)"
+ifneq (x$(TEST-EXTRA-INFO), x)
+MKINFO-OPTS += -x "$(TEST-EXTRA-INFO)"
+endif
+
 info.json: $(ROOT)/build/mkinfo.py FORCE
-   @$(PYTHON) $< $@.tmp "$(NAME)" "$(CATEGORY)" "$(TEST-ENVS)" 
"$(VARY-CFG)"
+   @$(PYTHON) $< $(MKINFO-OPTS) $@.tmp
@$(call move-if-changed,$@.tmp,$@)
 
 .PHONY: install install-each-env
diff --git a/build/mkinfo.py b/build/mkinfo.py
index 94891a9..afa355c 100644
--- a/build/mkinfo.py
+++ b/build/mkinfo.py
@@ -1,24 +1,74 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+""" mkinfo.py
 
-import sys, os, json
+Generates a test info json file.
+The script is ran at build stage using the parameters specified
+in the test's Makefile.
+"""
 
-# Usage: mkcfg.py $OUT $NAME $CATEGORY $ENVS $VARIATIONS
-_, out, name, cat, envs, variations = sys.argv
+import json
+import sys
+import shlex
+from   optparse import OptionParser
 
-template = {
-"name": name,
-"category": cat,
-"environments": [],
-"variations": [],
-}
+def main():
+""" Main entrypoint """
+# Avoid wrapping the epilog text
+OptionParser.format_epilog = lambda self, formatter: self.epilog
 
-if envs:
-template["environments"] = envs.split(" ")
-if variations:
-template["variations"] = variations.split(" ")
+parser = OptionParser(
+usage = "%prog [OPTIONS] out_file",
+description = "Xen Test Framework json generation tool",
+)
 
-open(out, "w").write(
-json.dumps(template, indent=4, separators=(',', ': '))
-+ "\n"
-)
+parser.add_option("-n", "--name", action = "store",
+  dest = "name",
+  help = "Test name",
+  )
+parser.add_option("-c", "--class", action = "store",
+  dest = "class_name",
+  help = "Test class name",
+  )
+parser.add_option("-t", "--category", action = &

[Xen-devel] [PATCH XTF v2 4/4] xtf: Add monitor mem_access test

2018-12-28 Thread Petre Pircalabu
The monitor application resets the execute permisions on a specific page
of the DOMU and handles the generated vm_event request.

Signed-off-by: Petre Pircalabu 
---
 docs/all-tests.dox |   1 +
 tests/monitor-mem-access/Makefile  |  14 
 tests/monitor-mem-access/main.c|  37 +
 tests/monitor-mem-access/monitor.c | 159 +
 4 files changed, 211 insertions(+)
 create mode 100644 tests/monitor-mem-access/Makefile
 create mode 100644 tests/monitor-mem-access/main.c
 create mode 100644 tests/monitor-mem-access/monitor.c

diff --git a/docs/all-tests.dox b/docs/all-tests.dox
index 11b7f41..644cc71 100644
--- a/docs/all-tests.dox
+++ b/docs/all-tests.dox
@@ -148,4 +148,5 @@ enable BTS.
 
 
 @section index-monitor Monitor
+@subpage test-monitor-mem-access - memory access monitor test
 */
diff --git a/tests/monitor-mem-access/Makefile 
b/tests/monitor-mem-access/Makefile
new file mode 100644
index 000..45aaedb
--- /dev/null
+++ b/tests/monitor-mem-access/Makefile
@@ -0,0 +1,14 @@
+include $(ROOT)/build/common.mk
+
+NAME   := monitor-mem-access
+CATEGORY   := monitor
+TEST-ENVS  := hvm64
+CLASS  := xtf.monitor_test.MonitorTestInfo
+TEST-EXTRA-INFO:= monitor_args='--address=0x\$$(nm --defined-only 
@@VM_PATH@@ | grep test_fn | cut -d \  -f 1)'
+
+obj-perenv += main.o
+
+obj-monitor += monitor.o
+
+include $(ROOT)/build/gen.mk
+
diff --git a/tests/monitor-mem-access/main.c b/tests/monitor-mem-access/main.c
new file mode 100644
index 000..f5ef795
--- /dev/null
+++ b/tests/monitor-mem-access/main.c
@@ -0,0 +1,37 @@
+/**
+ * @file tests/monitor-mem-access/main.c
+ * @ref test-monitor-mem-access
+ *
+ * @page test-monitor-mem-access monitor-mem-access
+ */
+
+#include 
+
+const char test_title[] = "Test monitor mem-access event";
+
+static int count;
+
+static void __attribute__((section(".text.protected"))) 
__attribute__((noinline)) test_fn(void)
+{
+count++;
+}
+
+void test_main(void)
+{
+test_fn();
+
+if ( count )
+xtf_success(NULL);
+else
+xtf_failure(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tests/monitor-mem-access/monitor.c 
b/tests/monitor-mem-access/monitor.c
new file mode 100644
index 000..a008117
--- /dev/null
+++ b/tests/monitor-mem-access/monitor.c
@@ -0,0 +1,159 @@
+/**
+ * @file tests/emul-unimpl/monitor.c
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+typedef struct mem_access_monitor
+{
+xtf_monitor_t mon;
+uint64_t address;
+unsigned long gfn;
+} mem_access_monitor_t;
+
+static const char mem_access_test_help[] = \
+"Usage: test-monitor-mem_access [options] \n"
+"\t -a : the start address of the execution protected page\n"
+;
+
+static int mem_access_setup(int argc, char *argv[]);
+static int mem_access_init();
+static int mem_access_get_result();
+
+static mem_access_monitor_t monitor_instance =
+{
+.mon =
+{
+.help_message = mem_access_test_help,
+.ops =
+{
+.setup  = mem_access_setup,
+.init   = mem_access_init,
+.get_result = mem_access_get_result,
+}
+}
+};
+
+static int test_mem_access(vm_event_request_t *req, vm_event_response_t *rsp);
+
+static int mem_access_setup(int argc, char *argv[])
+{
+int ret, c;
+static struct option long_options[] = {
+{"help",no_argument,0,  'h'},
+{"address", required_argument,0,  'a'},
+{0, 0, 0, 0}
+};
+mem_access_monitor_t *pmon = (mem_access_monitor_t *)monitor;
+
+if ( !pmon )
+return -EINVAL;
+
+if ( argc == 1 )
+{
+usage();
+return -EINVAL;
+}
+while ( 1 )
+{
+int option_index = 0;
+c = getopt_long(argc, argv, "ha:", long_options, &option_index);
+if ( c == -1 ) break;
+
+switch ( c )
+{
+case 'h':
+usage();
+exit(0);
+break;
+case 'a':
+pmon->address = strtoul(optarg, NULL, 0);
+break;
+default:
+XTF_MON_ERROR("%s: Invalid option %s\n", argv[0], optarg);
+return -EINVAL;
+}
+
+if ( !pmon->address )
+{
+XTF_MON_ERROR("%s: Please specify a valid instruction injection 
address\n", argv[0]);
+return -EINVAL;
+}
+
+if ( optind != argc - 1 )
+{
+XTF_MON_ERROR("%s: Please specify the domain id\n", argv[0]);
+return -EINVAL;
+}
+}
+
+monitor->domain_id 

[Xen-devel] [PATCH XTF v2 2/4] xtf: Add executable test class

2018-12-28 Thread Petre Pircalabu
The Executable test class runs on host (dom0). The class spawns a
process and searches the program output(stdio) for a specific pattern.

Signed-off-by: Petre Pircalabu 
---
 xtf/__init__.py|  2 +-
 xtf/executable_test.py | 83 ++
 xtf/suite.py   |  5 ++-
 3 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 xtf/executable_test.py

diff --git a/xtf/__init__.py b/xtf/__init__.py
index 889c1d5..07c269a 100644
--- a/xtf/__init__.py
+++ b/xtf/__init__.py
@@ -3,7 +3,7 @@
 
 # All test categories
 default_categories = set(("functional", "xsa"))
-non_default_categories = set(("special", "utility", "in-development"))
+non_default_categories = set(("special", "utility", "in-development", "host"))
 all_categories = default_categories | non_default_categories
 
 # All test environments
diff --git a/xtf/executable_test.py b/xtf/executable_test.py
new file mode 100644
index 000..31aa6e4
--- /dev/null
+++ b/xtf/executable_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Executable test classes
+
+Spawns a process and waits for a specific pattern
+"""
+
+import StringIO
+import pexpect
+
+from xtf.logger import Logger
+from xtf.test import TestInstance, TestInfo, TestResult
+
+class ExecutableTestInstance(TestInstance):
+"""Executable Test Instance"""
+def __init__(self, name, cmd, args, pattern):
+super(ExecutableTestInstance, self).__init__(name)
+
+self._cmd = cmd
+self._args = [x.encode('utf-8') for x in args]
+self._pattern = [x.encode('utf-8') for x in pattern]
+self._proc = None
+self.env = "dom0"
+self.output = StringIO.StringIO()
+
+def __repr__(self):
+return "test-%s-%s" %(self.env, self.name)
+
+def wait_pattern(self, pattern):
+"""Expect the pattern given as parameter."""
+return self._proc.expect(pattern + [pexpect.TIMEOUT, pexpect.EOF])
+
+def set_up(self, opts, result):
+self._proc = pexpect.spawn(self._cmd, self._args, logfile = 
self.output)
+print self._cmd, self._args
+
+if self._proc is None:
+result.set(TestResult.ERROR)
+
+def run(self, result):
+"""Executes the test instance"""
+if self.wait_pattern(self._pattern) > len(self._pattern):
+result.set(TestResult.FAILURE)
+return
+
+result.set(TestResult.SUCCESS)
+
+def clean_up(self, result):
+if self.output:
+Logger().log(self.output.getvalue())
+self.output.close()
+
+class ExecutableTestInfo(TestInfo):
+""" Object representing a tests info.json, in a more convenient form. """
+
+def __init__(self, test_json):
+super(ExecutableTestInfo, self).__init__(test_json)
+self.instance_class = ExecutableTestInstance
+
+cmd = test_json["cmd"]
+if not isinstance(cmd, (str, unicode)):
+raise TypeError("Expected string for 'cmd', got '%s')"
+% (type(cmd), ))
+self.cmd = cmd
+
+args = test_json["args"]
+if not isinstance(args, list):
+raise TypeError("Expected list for 'args', got '%s')"
+% (type(args), ))
+self.args = args
+
+pattern = test_json["pattern"]
+if not isinstance(pattern, list):
+raise TypeError("Expected list for 'pattern', got '%s')"
+% (type(pattern), ))
+self.pattern = pattern
+
+def all_instances(self, env_filter = None, vary_filter = None):
+"""Returns an ExecutableTestInstance object"""
+return [self.instance_class(self.name, self.cmd, self.args,
+self.pattern),]
diff --git a/xtf/suite.py b/xtf/suite.py
index ad7d30f..2e0727c 100644
--- a/xtf/suite.py
+++ b/xtf/suite.py
@@ -75,7 +75,10 @@ def gather_all_test_info():
 try:
 info_file = open(path.join("tests", test, "info.json"))
 except IOError:
-continue
+try:
+info_file = open(path.join("tests", test, "host.json"))
+except IOError:
+continue
 
 # Ignore tests which have bad JSON
 try:
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v2 0/4] Add monitor tests to XTF

2018-12-28 Thread Petre Pircalabu
Extend the framework to support (simple) monitor related tests.

Changes from v1:
- Refactored the monitor test (cleanup)
- Replace the "emul-unimplemented" test with a simpler mem_access test


Petre Pircalabu (4):
  xtf-runner: split into logical components
  xtf: Add executable test class
  xtf: Add monitor test class
  xtf: Add monitor mem_access test

 Makefile   |   6 +-
 build/common.mk|  22 +-
 build/files.mk |   3 +
 build/gen.mk   |  25 +-
 build/mkinfo.py|  84 +--
 common/report.c|   8 -
 docs/all-tests.dox |   4 +
 include/monitor/monitor.h  | 136 +++
 include/xtf/report.h   |   8 +
 monitor/Makefile   |  20 ++
 monitor/monitor.c  | 481 +
 tests/monitor-mem-access/Makefile  |  14 ++
 tests/monitor-mem-access/main.c|  37 +++
 tests/monitor-mem-access/monitor.c | 159 
 xtf-runner | 334 +++--
 xtf/__init__.py|  12 +
 xtf/domu_test.py   | 179 ++
 xtf/exceptions.py  |   6 +
 xtf/executable_test.py |  83 +++
 xtf/logger.py  |  23 ++
 xtf/monitor_test.py| 132 ++
 xtf/suite.py   | 100 
 xtf/test.py| 139 +++
 xtf/utils.py   |  17 ++
 xtf/xl_domu.py | 121 ++
 25 files changed, 1821 insertions(+), 332 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 tests/monitor-mem-access/Makefile
 create mode 100644 tests/monitor-mem-access/main.c
 create mode 100644 tests/monitor-mem-access/monitor.c
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/executable_test.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/utils.py
 create mode 100644 xtf/xl_domu.py

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v2 3/4] xtf: Add monitor test class

2018-12-28 Thread Petre Pircalabu
This class starts alongside the domain a monitor application which opens
an event channel corresponding to that domain and handles the received
requests.
Use the "monitor_args" key to pass test specific arguments to the
monitor application.
The arguments will be added in the test's Makefile using the
TEST-EXTRA-INFO variable.

Signed-off-by: Petre Pircalabu 
---
 Makefile  |   6 +-
 build/common.mk   |  22 ++-
 build/files.mk|   3 +
 build/gen.mk  |  12 ++
 common/report.c   |   8 -
 docs/all-tests.dox|   3 +
 include/monitor/monitor.h | 136 +
 include/xtf/report.h  |   8 +
 monitor/Makefile  |  20 ++
 monitor/monitor.c | 481 ++
 xtf/__init__.py   |   2 +-
 xtf/monitor_test.py   | 132 +
 xtf/utils.py  |  17 ++
 13 files changed, 838 insertions(+), 12 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/utils.py

diff --git a/Makefile b/Makefile
index 15a865f..db28075 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,9 @@ INSTALL_PROGRAM := $(INSTALL) -p
 OBJCOPY := $(CROSS_COMPILE)objcopy
 PYTHON  := python
 
-export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON
+HOSTCC  := gcc
+
+export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON 
HOSTCC
 
 .PHONY: all
 all:
@@ -51,7 +53,7 @@ install:
done
 
 define all_sources
-   find include/ arch/ common/ tests/ -name "*.[hcsS]"
+   find include/ arch/ common/ tests/ monitor/ -name "*.[hcsS]"
 endef
 
 .PHONY: cscope
diff --git a/build/common.mk b/build/common.mk
index b786ddf..1ec0fa4 100644
--- a/build/common.mk
+++ b/build/common.mk
@@ -1,4 +1,4 @@
-ALL_CATEGORIES := special functional xsa utility in-development
+ALL_CATEGORIES := special functional xsa utility in-development monitor
 
 ALL_ENVIRONMENTS   := pv64 pv32pae hvm64 hvm32pae hvm32pse hvm32
 
@@ -35,11 +35,20 @@ COMMON_AFLAGS-x86_64 := -m64
 COMMON_CFLAGS-x86_32 := -m32
 COMMON_CFLAGS-x86_64 := -m64
 
+#HOSTCFLAGS := -Wall -Werror
+HOSTCFLAGS  :=
+HOSTLDFLAGS :=
+HOSTLDLIBS  :=
+HOSTCFLAGS  += -D__XEN_TOOLS__ -g -O3 -I$(ROOT)/include/monitor
+HOSTCFLAGS  += -DXC_WANT_COMPAT_DEVICEMODEL_API 
-DXC_WANT_COMPAT_MAP_FOREIGN_API
+HOSTLDLIBS  += -lxenctrl -lxenstore -lxenevtchn
+
 defcfg-pv:= $(ROOT)/config/default-pv.cfg.in
 defcfg-hvm   := $(ROOT)/config/default-hvm.cfg.in
 
 obj-perarch :=
 obj-perenv  :=
+obj-monitor :=
 include $(ROOT)/build/files.mk
 
 
@@ -90,8 +99,19 @@ DEPS-$(1) = $$(head-$(1)) \
 
 endef
 
+# Setup monitor rules
+define MONITOR_setup
+DEPS-MONITOR = \
+   $$(obj-monitor:%.o=%-monitor.o)
+
+%-monitor.o: %.c
+   $$(HOSTCC) $$(HOSTCFLAGS) -c $$< -o $$@
+endef
+
 $(foreach env,$(ALL_ENVIRONMENTS),$(eval $(call PERENV_setup,$(env
 
+$(eval $(call MONITOR_setup))
+
 define move-if-changed
if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
 endef
diff --git a/build/files.mk b/build/files.mk
index dfa27e4..972c797 100644
--- a/build/files.mk
+++ b/build/files.mk
@@ -54,3 +54,6 @@ $(foreach env,$(32BIT_ENVIRONMENTS),$(eval obj-$(env) += 
$(obj-32)))
 # 64bit specific objects
 obj-64  += $(ROOT)/arch/x86/entry_64.o
 $(foreach env,$(64BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-64)))
+
+# Monitor common objects
+obj-monitor += $(ROOT)/monitor/monitor.o
diff --git a/build/gen.mk b/build/gen.mk
index c19ca6a..1e6773a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -32,6 +32,9 @@ CLASS ?= "xtf.domu_test.DomuTestInfo"
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
+ifeq (x$(CATEGORY),xmonitor)
+build: test-monitor-$(NAME)
+endif
 
 MKINFO-OPTS := -n "$(NAME)"
 MKINFO-OPTS += -c "$(CLASS)"
@@ -100,6 +103,15 @@ install-each-env: install-$(1) install-$(1).cfg
 endef
 $(foreach env,$(TEST-ENVS),$(eval $(call PERENV_build,$(env
 
+define MONITOR_build
+test-monitor-$(NAME): $(DEPS-MONITOR)
+   @echo $(obj-monitor)
+   @echo $(DEPS-MONITOR)
+   $(HOSTCC) $(HOSTLDFLAGS) $(DEPS-MONITOR) $(HOSTLDLIBS) -o $$@
+endef
+
+$(eval $(call MONITOR_build))
+
 .PHONY: clean
 clean:
find $(ROOT) \( -name "*.o" -o -name "*.d" \) -delete
diff --git a/common/report.c b/common/report.c
index ffdf098..745713a 100644
--- a/common/report.c
+++ b/common/report.c
@@ -2,14 +2,6 @@
 #include 
 #include 
 
-enum test_status {
-STATUS_RUNNING, /**< Test not yet completed.   */
-STATUS_SUCCESS, /**< Test was successful.  */
-STATUS_SKIP,/**< Test cannot be completed. */
-STATUS_ERROR,   /**< Issue with the test itself.   */
-STATUS_FAILURE, /**< Issue with the tes

[Xen-devel] [PATCH] vm_event: Add a new opcode to get VM_EVENT_INTERFACE_VERSION

2019-02-13 Thread Petre Pircalabu
Currently, the VM_EVENT_INTERFACE_VERSION is determined at runtime, by
inspecting the corresponding field in a vm_event_request. This helper
opcode will query the hypervisor supported version before the vm_event
related structures and layout are set-up.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |  5 +
 tools/libxc/xc_vm_event.c | 18 +-
 xen/common/domctl.c   |  1 +
 xen/common/vm_event.c | 15 ++-
 xen/include/public/domctl.h   | 17 +
 5 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 31cdda7..b801b85 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2003,6 +2003,11 @@ int xc_set_mem_access_multi(xc_interface *xch, uint32_t 
domain_id,
 int xc_get_mem_access(xc_interface *xch, uint32_t domain_id,
   uint64_t pfn, xenmem_access_t *access);
 
+/*
+ * Returns the VM_EVENT_INTERFACE version.
+ */
+int xc_vm_event_get_interface_version(xc_interface *xch);
+
 /***
  * Monitor control operations.
  *
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index 8674607..10ebc3c 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -35,7 +35,7 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 
 rc = do_domctl(xch, &domctl);
 if ( !rc && port )
-*port = domctl.u.vm_event_op.port;
+*port = domctl.u.vm_event_op.u.enable.port;
 return rc;
 }
 
@@ -156,6 +156,22 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t 
domain_id, int param,
 return ring_page;
 }
 
+int xc_vm_event_get_interface_version(xc_interface *xch)
+{
+DECLARE_DOMCTL;
+int rc;
+
+domctl.cmd = XEN_DOMCTL_vm_event_op;
+domctl.domain = DOMID_INVALID;
+domctl.u.vm_event_op.op = XEN_VM_EVENT_GET_INTERFACE_VERSION;
+domctl.u.vm_event_op.mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR;
+
+rc = do_domctl(xch, &domctl);
+if ( !rc )
+rc = domctl.u.vm_event_op.u.get_interface_version.value;
+return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index d08b627..bade9a6 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -392,6 +392,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
 switch ( op->cmd )
 {
 case XEN_DOMCTL_test_assign_device:
+case XEN_DOMCTL_vm_event_op:
 if ( op->domain == DOMID_INVALID )
 {
 case XEN_DOMCTL_createdomain:
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 26cfa2c..cbdade3 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -88,7 +88,7 @@ static int vm_event_enable(
 if ( rc < 0 )
 goto err;
 
-(*ved)->xen_port = vec->port = rc;
+(*ved)->xen_port = vec->u.enable.port = rc;
 
 /* Prepare ring buffer */
 FRONT_RING_INIT(&(*ved)->front_ring,
@@ -592,6 +592,19 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 {
 int rc;
 
+if ( vec->op == XEN_VM_EVENT_GET_INTERFACE_VERSION )
+{
+vec->u.get_interface_version.value = VM_EVENT_INTERFACE_VERSION;
+return 0;
+}
+
+if ( unlikely(d == NULL) )
+{
+gdprintk(XENLOG_INFO,
+ "Tried to do a memory event op on an invalid domain.\n");
+return -EINVAL;
+}
+
 rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
 if ( rc )
 return rc;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 7e1cf21..f222d1e 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -778,9 +778,10 @@ struct xen_domctl_gdbsx_domstatus {
  * to the hypervisor to pull responses (resume) from the given
  * ring.
  */
-#define XEN_VM_EVENT_ENABLE   0
-#define XEN_VM_EVENT_DISABLE  1
-#define XEN_VM_EVENT_RESUME   2
+#define XEN_VM_EVENT_ENABLE 0
+#define XEN_VM_EVENT_DISABLE1
+#define XEN_VM_EVENT_RESUME 2
+#define XEN_VM_EVENT_GET_INTERFACE_VERSION  3
 
 /*
  * Domain memory paging
@@ -843,7 +844,15 @@ struct xen_domctl_vm_event_op {
 uint32_t   op;   /* XEN_VM_EVENT_* */
 uint32_t   mode; /* XEN_DOMCTL_VM_EVENT_OP_* */
 
-uint32_t port;  /* OUT: event channel for ring */
+union {
+struct {
+uint32_t port;   /* OUT: event channel for ring */
+} enable;
+
+struct {
+uint32_t value;
+} get_interface_version;
+} u;
 };
 
 /*
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2] vm_event: Add a new opcode to get VM_EVENT_INTERFACE_VERSION

2019-02-14 Thread Petre Pircalabu
Currently, the VM_EVENT_INTERFACE_VERSION is determined at runtime, by
inspecting the corresponding field in a vm_event_request. This helper
opcode will query the hypervisor supported version before the vm_event
related structures and layout are set-up.

Signed-off-by: Petre Pircalabu 

---
Changes from v1:
 - Return -ESRCH instead of -EINVAL if DOMID_INVALID if given as
   parameter to XEN_DOMCTL_vm_event_op and op is not
   XEN_VM_EVENT_GET_VERSION. Also the log message was removed.
 - Replace XEN_VM_EVENT_GET_INTERFACE_VERSION with
   XEN_VM_EVENT_GET_VERSION.
 - Replace the "get_interface_version" wrapper struct with a single
   "version" field.
 - Rename the libxc wrapper to xc_vm_event_get_version.
---
 tools/libxc/include/xenctrl.h |  5 +
 tools/libxc/xc_vm_event.c | 18 +-
 xen/common/domctl.c   |  1 +
 xen/common/vm_event.c | 11 ++-
 xen/include/public/domctl.h   |  9 -
 5 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 31cdda7..a3628e5 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2003,6 +2003,11 @@ int xc_set_mem_access_multi(xc_interface *xch, uint32_t 
domain_id,
 int xc_get_mem_access(xc_interface *xch, uint32_t domain_id,
   uint64_t pfn, xenmem_access_t *access);
 
+/*
+ * Returns the VM_EVENT_INTERFACE version.
+ */
+int xc_vm_event_get_version(xc_interface *xch);
+
 /***
  * Monitor control operations.
  *
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index 8674607..a97c615 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -35,7 +35,7 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 
 rc = do_domctl(xch, &domctl);
 if ( !rc && port )
-*port = domctl.u.vm_event_op.port;
+*port = domctl.u.vm_event_op.u.enable.port;
 return rc;
 }
 
@@ -156,6 +156,22 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t 
domain_id, int param,
 return ring_page;
 }
 
+int xc_vm_event_get_version(xc_interface *xch)
+{
+DECLARE_DOMCTL;
+int rc;
+
+domctl.cmd = XEN_DOMCTL_vm_event_op;
+domctl.domain = DOMID_INVALID;
+domctl.u.vm_event_op.op = XEN_VM_EVENT_GET_VERSION;
+domctl.u.vm_event_op.mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR;
+
+rc = do_domctl(xch, &domctl);
+if ( !rc )
+rc = domctl.u.vm_event_op.u.version;
+return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index d08b627..bade9a6 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -392,6 +392,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
 switch ( op->cmd )
 {
 case XEN_DOMCTL_test_assign_device:
+case XEN_DOMCTL_vm_event_op:
 if ( op->domain == DOMID_INVALID )
 {
 case XEN_DOMCTL_createdomain:
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 26cfa2c..19c983c 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -88,7 +88,7 @@ static int vm_event_enable(
 if ( rc < 0 )
 goto err;
 
-(*ved)->xen_port = vec->port = rc;
+(*ved)->xen_port = vec->u.enable.port = rc;
 
 /* Prepare ring buffer */
 FRONT_RING_INIT(&(*ved)->front_ring,
@@ -592,6 +592,15 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 {
 int rc;
 
+if ( vec->op == XEN_VM_EVENT_GET_VERSION )
+{
+vec->u.version = VM_EVENT_INTERFACE_VERSION;
+return 0;
+}
+
+if ( unlikely(d == NULL) )
+return -ESRCH;
+
 rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op);
 if ( rc )
 return rc;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 7e1cf21..19486d5 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -781,6 +781,7 @@ struct xen_domctl_gdbsx_domstatus {
 #define XEN_VM_EVENT_ENABLE   0
 #define XEN_VM_EVENT_DISABLE  1
 #define XEN_VM_EVENT_RESUME   2
+#define XEN_VM_EVENT_GET_VERSION  3
 
 /*
  * Domain memory paging
@@ -843,7 +844,13 @@ struct xen_domctl_vm_event_op {
 uint32_t   op;   /* XEN_VM_EVENT_* */
 uint32_t   mode; /* XEN_DOMCTL_VM_EVENT_OP_* */
 
-uint32_t port;  /* OUT: event channel for ring */
+union {
+struct {
+uint32_t port;   /* OUT: event channel for ring */
+} enable;
+
+uint32_t version;
+} u;
 };
 
 /*
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v3 0/4] Add monitor tests to XTF

2019-02-18 Thread Petre Pircalabu
Extend the framework to support (simple) monitor related tests.

Changes from v2
- Check the returned value from xc_translate_foreign_address.

Changes from v1:
- Refactored the monitor test (cleanup)
- Replace the "emul-unimplemented" test with a simpler mem_access test

Petre Pircalabu (4):
  xtf-runner: split into logical components
  xtf: Add executable test class
  xtf: Add monitor test class
  xtf: Add monitor mem_access test

 Makefile   |   6 +-
 build/common.mk|  22 +-
 build/files.mk |   3 +
 build/gen.mk   |  25 +-
 build/mkinfo.py|  84 +--
 common/report.c|   8 -
 docs/all-tests.dox |   4 +
 include/monitor/monitor.h  | 136 +++
 include/xtf/report.h   |   8 +
 monitor/Makefile   |  20 ++
 monitor/monitor.c  | 481 +
 tests/monitor-mem-access/Makefile  |  14 ++
 tests/monitor-mem-access/main.c|  37 +++
 tests/monitor-mem-access/monitor.c | 164 +
 xtf-runner | 334 +++--
 xtf/__init__.py|  12 +
 xtf/domu_test.py   | 179 ++
 xtf/exceptions.py  |   6 +
 xtf/executable_test.py |  83 +++
 xtf/logger.py  |  23 ++
 xtf/monitor_test.py| 132 ++
 xtf/suite.py   | 100 
 xtf/test.py| 139 +++
 xtf/utils.py   |  17 ++
 xtf/xl_domu.py | 121 ++
 25 files changed, 1826 insertions(+), 332 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 tests/monitor-mem-access/Makefile
 create mode 100644 tests/monitor-mem-access/main.c
 create mode 100644 tests/monitor-mem-access/monitor.c
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/executable_test.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/utils.py
 create mode 100644 xtf/xl_domu.py

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v3 4/4] xtf: Add monitor mem_access test

2019-02-18 Thread Petre Pircalabu
The monitor application resets the execute permisions on a specific page
of the DOMU and handles the generated vm_event request.

Signed-off-by: Petre Pircalabu 
---
 docs/all-tests.dox |   1 +
 tests/monitor-mem-access/Makefile  |  14 
 tests/monitor-mem-access/main.c|  37 +
 tests/monitor-mem-access/monitor.c | 164 +
 4 files changed, 216 insertions(+)
 create mode 100644 tests/monitor-mem-access/Makefile
 create mode 100644 tests/monitor-mem-access/main.c
 create mode 100644 tests/monitor-mem-access/monitor.c

diff --git a/docs/all-tests.dox b/docs/all-tests.dox
index 11b7f41..644cc71 100644
--- a/docs/all-tests.dox
+++ b/docs/all-tests.dox
@@ -148,4 +148,5 @@ enable BTS.
 
 
 @section index-monitor Monitor
+@subpage test-monitor-mem-access - memory access monitor test
 */
diff --git a/tests/monitor-mem-access/Makefile 
b/tests/monitor-mem-access/Makefile
new file mode 100644
index 000..45aaedb
--- /dev/null
+++ b/tests/monitor-mem-access/Makefile
@@ -0,0 +1,14 @@
+include $(ROOT)/build/common.mk
+
+NAME   := monitor-mem-access
+CATEGORY   := monitor
+TEST-ENVS  := hvm64
+CLASS  := xtf.monitor_test.MonitorTestInfo
+TEST-EXTRA-INFO:= monitor_args='--address=0x\$$(nm --defined-only 
@@VM_PATH@@ | grep test_fn | cut -d \  -f 1)'
+
+obj-perenv += main.o
+
+obj-monitor += monitor.o
+
+include $(ROOT)/build/gen.mk
+
diff --git a/tests/monitor-mem-access/main.c b/tests/monitor-mem-access/main.c
new file mode 100644
index 000..f5ef795
--- /dev/null
+++ b/tests/monitor-mem-access/main.c
@@ -0,0 +1,37 @@
+/**
+ * @file tests/monitor-mem-access/main.c
+ * @ref test-monitor-mem-access
+ *
+ * @page test-monitor-mem-access monitor-mem-access
+ */
+
+#include 
+
+const char test_title[] = "Test monitor mem-access event";
+
+static int count;
+
+static void __attribute__((section(".text.protected"))) 
__attribute__((noinline)) test_fn(void)
+{
+count++;
+}
+
+void test_main(void)
+{
+test_fn();
+
+if ( count )
+xtf_success(NULL);
+else
+xtf_failure(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tests/monitor-mem-access/monitor.c 
b/tests/monitor-mem-access/monitor.c
new file mode 100644
index 000..50cca9a
--- /dev/null
+++ b/tests/monitor-mem-access/monitor.c
@@ -0,0 +1,164 @@
+/**
+ * @file tests/emul-unimpl/monitor.c
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+typedef struct mem_access_monitor
+{
+xtf_monitor_t mon;
+uint64_t address;
+unsigned long gfn;
+} mem_access_monitor_t;
+
+static const char mem_access_test_help[] = \
+"Usage: test-monitor-mem_access [options] \n"
+"\t -a : the start address of the execution protected page\n"
+;
+
+static int mem_access_setup(int argc, char *argv[]);
+static int mem_access_init();
+static int mem_access_get_result();
+
+static mem_access_monitor_t monitor_instance =
+{
+.mon =
+{
+.help_message = mem_access_test_help,
+.ops =
+{
+.setup  = mem_access_setup,
+.init   = mem_access_init,
+.get_result = mem_access_get_result,
+}
+}
+};
+
+static int test_mem_access(vm_event_request_t *req, vm_event_response_t *rsp);
+
+static int mem_access_setup(int argc, char *argv[])
+{
+int ret, c;
+static struct option long_options[] = {
+{"help",no_argument,0,  'h'},
+{"address", required_argument,0,  'a'},
+{0, 0, 0, 0}
+};
+mem_access_monitor_t *pmon = (mem_access_monitor_t *)monitor;
+
+if ( !pmon )
+return -EINVAL;
+
+if ( argc == 1 )
+{
+usage();
+return -EINVAL;
+}
+while ( 1 )
+{
+int option_index = 0;
+c = getopt_long(argc, argv, "ha:", long_options, &option_index);
+if ( c == -1 ) break;
+
+switch ( c )
+{
+case 'h':
+usage();
+exit(0);
+break;
+case 'a':
+pmon->address = strtoul(optarg, NULL, 0);
+break;
+default:
+XTF_MON_ERROR("%s: Invalid option %s\n", argv[0], optarg);
+return -EINVAL;
+}
+
+if ( !pmon->address )
+{
+XTF_MON_ERROR("%s: Please specify a valid instruction injection 
address\n", argv[0]);
+return -EINVAL;
+}
+
+if ( optind != argc - 1 )
+{
+XTF_MON_ERROR("%s: Please specify the domain id\n", argv[0]);
+return -EINVAL;
+}
+}
+
+monitor->domain_id 

[Xen-devel] [PATCH XTF v3 3/4] xtf: Add monitor test class

2019-02-18 Thread Petre Pircalabu
This class starts alongside the domain a monitor application which opens
an event channel corresponding to that domain and handles the received
requests.
Use the "monitor_args" key to pass test specific arguments to the
monitor application.
The arguments will be added in the test's Makefile using the
TEST-EXTRA-INFO variable.

Signed-off-by: Petre Pircalabu 
---
 Makefile  |   6 +-
 build/common.mk   |  22 ++-
 build/files.mk|   3 +
 build/gen.mk  |  12 ++
 common/report.c   |   8 -
 docs/all-tests.dox|   3 +
 include/monitor/monitor.h | 136 +
 include/xtf/report.h  |   8 +
 monitor/Makefile  |  20 ++
 monitor/monitor.c | 481 ++
 xtf/__init__.py   |   2 +-
 xtf/monitor_test.py   | 132 +
 xtf/utils.py  |  17 ++
 13 files changed, 838 insertions(+), 12 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/utils.py

diff --git a/Makefile b/Makefile
index 15a865f..db28075 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,9 @@ INSTALL_PROGRAM := $(INSTALL) -p
 OBJCOPY := $(CROSS_COMPILE)objcopy
 PYTHON  := python
 
-export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON
+HOSTCC  := gcc
+
+export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON 
HOSTCC
 
 .PHONY: all
 all:
@@ -51,7 +53,7 @@ install:
done
 
 define all_sources
-   find include/ arch/ common/ tests/ -name "*.[hcsS]"
+   find include/ arch/ common/ tests/ monitor/ -name "*.[hcsS]"
 endef
 
 .PHONY: cscope
diff --git a/build/common.mk b/build/common.mk
index b786ddf..1ec0fa4 100644
--- a/build/common.mk
+++ b/build/common.mk
@@ -1,4 +1,4 @@
-ALL_CATEGORIES := special functional xsa utility in-development
+ALL_CATEGORIES := special functional xsa utility in-development monitor
 
 ALL_ENVIRONMENTS   := pv64 pv32pae hvm64 hvm32pae hvm32pse hvm32
 
@@ -35,11 +35,20 @@ COMMON_AFLAGS-x86_64 := -m64
 COMMON_CFLAGS-x86_32 := -m32
 COMMON_CFLAGS-x86_64 := -m64
 
+#HOSTCFLAGS := -Wall -Werror
+HOSTCFLAGS  :=
+HOSTLDFLAGS :=
+HOSTLDLIBS  :=
+HOSTCFLAGS  += -D__XEN_TOOLS__ -g -O3 -I$(ROOT)/include/monitor
+HOSTCFLAGS  += -DXC_WANT_COMPAT_DEVICEMODEL_API 
-DXC_WANT_COMPAT_MAP_FOREIGN_API
+HOSTLDLIBS  += -lxenctrl -lxenstore -lxenevtchn
+
 defcfg-pv:= $(ROOT)/config/default-pv.cfg.in
 defcfg-hvm   := $(ROOT)/config/default-hvm.cfg.in
 
 obj-perarch :=
 obj-perenv  :=
+obj-monitor :=
 include $(ROOT)/build/files.mk
 
 
@@ -90,8 +99,19 @@ DEPS-$(1) = $$(head-$(1)) \
 
 endef
 
+# Setup monitor rules
+define MONITOR_setup
+DEPS-MONITOR = \
+   $$(obj-monitor:%.o=%-monitor.o)
+
+%-monitor.o: %.c
+   $$(HOSTCC) $$(HOSTCFLAGS) -c $$< -o $$@
+endef
+
 $(foreach env,$(ALL_ENVIRONMENTS),$(eval $(call PERENV_setup,$(env
 
+$(eval $(call MONITOR_setup))
+
 define move-if-changed
if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
 endef
diff --git a/build/files.mk b/build/files.mk
index dfa27e4..972c797 100644
--- a/build/files.mk
+++ b/build/files.mk
@@ -54,3 +54,6 @@ $(foreach env,$(32BIT_ENVIRONMENTS),$(eval obj-$(env) += 
$(obj-32)))
 # 64bit specific objects
 obj-64  += $(ROOT)/arch/x86/entry_64.o
 $(foreach env,$(64BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-64)))
+
+# Monitor common objects
+obj-monitor += $(ROOT)/monitor/monitor.o
diff --git a/build/gen.mk b/build/gen.mk
index c19ca6a..1e6773a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -32,6 +32,9 @@ CLASS ?= "xtf.domu_test.DomuTestInfo"
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
+ifeq (x$(CATEGORY),xmonitor)
+build: test-monitor-$(NAME)
+endif
 
 MKINFO-OPTS := -n "$(NAME)"
 MKINFO-OPTS += -c "$(CLASS)"
@@ -100,6 +103,15 @@ install-each-env: install-$(1) install-$(1).cfg
 endef
 $(foreach env,$(TEST-ENVS),$(eval $(call PERENV_build,$(env
 
+define MONITOR_build
+test-monitor-$(NAME): $(DEPS-MONITOR)
+   @echo $(obj-monitor)
+   @echo $(DEPS-MONITOR)
+   $(HOSTCC) $(HOSTLDFLAGS) $(DEPS-MONITOR) $(HOSTLDLIBS) -o $$@
+endef
+
+$(eval $(call MONITOR_build))
+
 .PHONY: clean
 clean:
find $(ROOT) \( -name "*.o" -o -name "*.d" \) -delete
diff --git a/common/report.c b/common/report.c
index ffdf098..745713a 100644
--- a/common/report.c
+++ b/common/report.c
@@ -2,14 +2,6 @@
 #include 
 #include 
 
-enum test_status {
-STATUS_RUNNING, /**< Test not yet completed.   */
-STATUS_SUCCESS, /**< Test was successful.  */
-STATUS_SKIP,/**< Test cannot be completed. */
-STATUS_ERROR,   /**< Issue with the test itself.   */
-STATUS_FAILURE, /**< Issue with the tes

[Xen-devel] [PATCH XTF v3 2/4] xtf: Add executable test class

2019-02-18 Thread Petre Pircalabu
The Executable test class runs on host (dom0). The class spawns a
process and searches the program output(stdio) for a specific pattern.

Signed-off-by: Petre Pircalabu 
---
 xtf/__init__.py|  2 +-
 xtf/executable_test.py | 83 ++
 xtf/suite.py   |  5 ++-
 3 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 xtf/executable_test.py

diff --git a/xtf/__init__.py b/xtf/__init__.py
index 889c1d5..07c269a 100644
--- a/xtf/__init__.py
+++ b/xtf/__init__.py
@@ -3,7 +3,7 @@
 
 # All test categories
 default_categories = set(("functional", "xsa"))
-non_default_categories = set(("special", "utility", "in-development"))
+non_default_categories = set(("special", "utility", "in-development", "host"))
 all_categories = default_categories | non_default_categories
 
 # All test environments
diff --git a/xtf/executable_test.py b/xtf/executable_test.py
new file mode 100644
index 000..31aa6e4
--- /dev/null
+++ b/xtf/executable_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Executable test classes
+
+Spawns a process and waits for a specific pattern
+"""
+
+import StringIO
+import pexpect
+
+from xtf.logger import Logger
+from xtf.test import TestInstance, TestInfo, TestResult
+
+class ExecutableTestInstance(TestInstance):
+"""Executable Test Instance"""
+def __init__(self, name, cmd, args, pattern):
+super(ExecutableTestInstance, self).__init__(name)
+
+self._cmd = cmd
+self._args = [x.encode('utf-8') for x in args]
+self._pattern = [x.encode('utf-8') for x in pattern]
+self._proc = None
+self.env = "dom0"
+self.output = StringIO.StringIO()
+
+def __repr__(self):
+return "test-%s-%s" %(self.env, self.name)
+
+def wait_pattern(self, pattern):
+"""Expect the pattern given as parameter."""
+return self._proc.expect(pattern + [pexpect.TIMEOUT, pexpect.EOF])
+
+def set_up(self, opts, result):
+self._proc = pexpect.spawn(self._cmd, self._args, logfile = 
self.output)
+print self._cmd, self._args
+
+if self._proc is None:
+result.set(TestResult.ERROR)
+
+def run(self, result):
+"""Executes the test instance"""
+if self.wait_pattern(self._pattern) > len(self._pattern):
+result.set(TestResult.FAILURE)
+return
+
+result.set(TestResult.SUCCESS)
+
+def clean_up(self, result):
+if self.output:
+Logger().log(self.output.getvalue())
+self.output.close()
+
+class ExecutableTestInfo(TestInfo):
+""" Object representing a tests info.json, in a more convenient form. """
+
+def __init__(self, test_json):
+super(ExecutableTestInfo, self).__init__(test_json)
+self.instance_class = ExecutableTestInstance
+
+cmd = test_json["cmd"]
+if not isinstance(cmd, (str, unicode)):
+raise TypeError("Expected string for 'cmd', got '%s')"
+% (type(cmd), ))
+self.cmd = cmd
+
+args = test_json["args"]
+if not isinstance(args, list):
+raise TypeError("Expected list for 'args', got '%s')"
+% (type(args), ))
+self.args = args
+
+pattern = test_json["pattern"]
+if not isinstance(pattern, list):
+raise TypeError("Expected list for 'pattern', got '%s')"
+% (type(pattern), ))
+self.pattern = pattern
+
+def all_instances(self, env_filter = None, vary_filter = None):
+"""Returns an ExecutableTestInstance object"""
+return [self.instance_class(self.name, self.cmd, self.args,
+self.pattern),]
diff --git a/xtf/suite.py b/xtf/suite.py
index ad7d30f..2e0727c 100644
--- a/xtf/suite.py
+++ b/xtf/suite.py
@@ -75,7 +75,10 @@ def gather_all_test_info():
 try:
 info_file = open(path.join("tests", test, "info.json"))
 except IOError:
-continue
+try:
+info_file = open(path.join("tests", test, "host.json"))
+except IOError:
+continue
 
 # Ignore tests which have bad JSON
 try:
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF v3 1/4] xtf-runner: split into logical components

2019-02-18 Thread Petre Pircalabu
Split the xtf-runner script file into multiple modules in order to
support multiple test types.

Features:
  - 2 abstract types (TestInfo and TestInstance) to represent the
  test information (info.json) and, respectively to implement the test
  execution.
TestInfo has to implement the "all_instances" method to create the
list of TestInstance objects.
TestInstance has to implement "set_up", "run", and "clean-up"
methods.
  - TestResult - represents an XTF test result (SUCCESS, SKIP, ERROR,
  FAILURE, CRASH). The values should be kept in sync with the C code
  from report.h
  - Dynamic test class loading. Each info.json shoudl contain a
  "class_name" field which specifies the test info class describing the
  test. This value defaults to "xtf.domu_test.DomuTestInfo"
  - custom test info parameters. info.json can have the "extra"
  field, implemented as a dictionary,  which contains parameters
  specific for a certain test info class.
e.g. TEST-EXTRA-INFO := arg1='--address=0x8000 --id=4' arg2=42
  - logger class (print depending on the quiet field)
  - DomuTestInfo/DomuTest instance. Simple test which loads a XEN DomU
  and checks the output for a specific pattern.
  - toolstack abstraction using a wrapper class (e.g.
  (xtf.xl_domu.XLDomU)

Signed-off-by: Petre Pircalabu 
---
 build/gen.mk  |  13 ++-
 build/mkinfo.py   |  84 +++---
 xtf-runner| 334 +-
 xtf/__init__.py   |  12 ++
 xtf/domu_test.py  | 179 +
 xtf/exceptions.py |   6 +
 xtf/logger.py |  23 
 xtf/suite.py  |  97 
 xtf/test.py   | 139 +++
 xtf/xl_domu.py| 121 
 10 files changed, 687 insertions(+), 321 deletions(-)
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/xl_domu.py

diff --git a/build/gen.mk b/build/gen.mk
index 8d7a6bf..c19ca6a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -27,12 +27,23 @@ else
 TEST-CFGS := $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME).cfg)
 endif
 
+CLASS ?= "xtf.domu_test.DomuTestInfo"
+
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
 
+MKINFO-OPTS := -n "$(NAME)"
+MKINFO-OPTS += -c "$(CLASS)"
+MKINFO-OPTS += -t "$(CATEGORY)"
+MKINFO-OPTS += -e "$(TEST-ENVS)"
+MKINFO-OPTS += -v "$(VARY-CFG)"
+ifneq (x$(TEST-EXTRA-INFO), x)
+MKINFO-OPTS += -x "$(TEST-EXTRA-INFO)"
+endif
+
 info.json: $(ROOT)/build/mkinfo.py FORCE
-   @$(PYTHON) $< $@.tmp "$(NAME)" "$(CATEGORY)" "$(TEST-ENVS)" 
"$(VARY-CFG)"
+   @$(PYTHON) $< $(MKINFO-OPTS) $@.tmp
@$(call move-if-changed,$@.tmp,$@)
 
 .PHONY: install install-each-env
diff --git a/build/mkinfo.py b/build/mkinfo.py
index 94891a9..afa355c 100644
--- a/build/mkinfo.py
+++ b/build/mkinfo.py
@@ -1,24 +1,74 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+""" mkinfo.py
 
-import sys, os, json
+Generates a test info json file.
+The script is ran at build stage using the parameters specified
+in the test's Makefile.
+"""
 
-# Usage: mkcfg.py $OUT $NAME $CATEGORY $ENVS $VARIATIONS
-_, out, name, cat, envs, variations = sys.argv
+import json
+import sys
+import shlex
+from   optparse import OptionParser
 
-template = {
-"name": name,
-"category": cat,
-"environments": [],
-"variations": [],
-}
+def main():
+""" Main entrypoint """
+# Avoid wrapping the epilog text
+OptionParser.format_epilog = lambda self, formatter: self.epilog
 
-if envs:
-template["environments"] = envs.split(" ")
-if variations:
-template["variations"] = variations.split(" ")
+parser = OptionParser(
+usage = "%prog [OPTIONS] out_file",
+description = "Xen Test Framework json generation tool",
+)
 
-open(out, "w").write(
-json.dumps(template, indent=4, separators=(',', ': '))
-+ "\n"
-)
+parser.add_option("-n", "--name", action = "store",
+  dest = "name",
+  help = "Test name",
+  )
+parser.add_option("-c", "--class", action = "store",
+  dest = "class_name",
+  help = "Test class name",
+  )
+parser.add_option("-t", "--category", action = &

[Xen-devel] [PATCH] vm_event: Fix XEN_VM_EVENT_RESUME domctl

2019-04-05 Thread Petre Pircalabu
Make XEN_VM_EVENT_RESUME return 0 in case of success, instead of
-EINVAL.
Remove vm_event_resume form vm_event.h header and set the function's
visibility to static as is used only in vm_event.c.
Move the vm_event_check_ring test inside vm_event_resume in order to
simplify the code.

Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c  | 37 -
 xen/include/xen/vm_event.h |  2 --
 2 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 19c983c..746b040 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -366,7 +366,7 @@ int vm_event_get_response(struct domain *d, struct 
vm_event_domain *ved,
  * Note: responses are handled the same way regardless of which ring they
  * arrive on.
  */
-void vm_event_resume(struct domain *d, struct vm_event_domain *ved)
+static int vm_event_resume(struct domain *d, struct vm_event_domain *ved)
 {
 vm_event_response_t rsp;
 
@@ -380,6 +380,9 @@ void vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
  */
 ASSERT(d != current->domain);
 
+if ( unlikely(!vm_event_check_ring(ved)) )
+ return -ENODEV;
+
 /* Pull all responses off the ring. */
 while ( vm_event_get_response(d, ved, &rsp) )
 {
@@ -443,6 +446,8 @@ void vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
 vm_event_vcpu_unpause(v);
 }
 }
+
+return 0;
 }
 
 void vm_event_cancel_slot(struct domain *d, struct vm_event_domain *ved)
@@ -529,30 +534,21 @@ int __vm_event_claim_slot(struct domain *d, struct 
vm_event_domain *ved,
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void mem_paging_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_paging)) )
-vm_event_resume(domain, domain->vm_event_paging);
+(void)vm_event_resume(v->domain, v->domain->vm_event_paging);
 }
 #endif
 
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void monitor_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_monitor)) )
-vm_event_resume(domain, domain->vm_event_monitor);
+(void)vm_event_resume(v->domain, v->domain->vm_event_monitor);
 }
 
 #ifdef CONFIG_HAS_MEM_SHARING
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void mem_sharing_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_share)) )
-vm_event_resume(domain, domain->vm_event_share);
+(void)vm_event_resume(v->domain, v->domain->vm_event_share);
 }
 #endif
 
@@ -676,10 +672,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_paging) )
-vm_event_resume(d, d->vm_event_paging);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_paging);
 break;
 
 default:
@@ -717,10 +710,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_monitor) )
-vm_event_resume(d, d->vm_event_monitor);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_monitor);
 break;
 
 default:
@@ -764,10 +754,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_share) )
-vm_event_resume(d, d->vm_event_share);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_share);
 break;
 
 default:
diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h
index 5302ee5..53af2d5 100644
--- a/xen/include/xen/vm_event.h
+++ b/xen/include/xen/vm_event.h
@@ -67,8 +67,6 @@ void vm_event_put_request(struct domain *d, struct 
vm_event_domain *ved,
 int vm_event_get_response(struct domain *d, struct vm_event_domain *ved,
   vm_event_response_t *rsp);
 
-void vm_event_resume(struct domain *d, struct vm_event_domain *ved);
-
 int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec,
 XEN_GUEST_HANDLE_PARAM(void) u_domctl);
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2] vm_event: Fix XEN_VM_EVENT_RESUME domctl

2019-04-05 Thread Petre Pircalabu
Make XEN_VM_EVENT_RESUME return 0 in case of success, instead of
-EINVAL.
Remove vm_event_resume form vm_event.h header and set the function's
visibility to static as is used only in vm_event.c.
Move the vm_event_check_ring test inside vm_event_resume in order to
simplify the code.

Signed-off-by: Petre Pircalabu 
Acked-by: Razvan Cojocaru 

---
Changes from v1:
  - Removed unnecessary casts
---
 xen/common/vm_event.c  | 37 -
 xen/include/xen/vm_event.h |  2 --
 2 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 19c983c..6e68be4 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -366,7 +366,7 @@ int vm_event_get_response(struct domain *d, struct 
vm_event_domain *ved,
  * Note: responses are handled the same way regardless of which ring they
  * arrive on.
  */
-void vm_event_resume(struct domain *d, struct vm_event_domain *ved)
+static int vm_event_resume(struct domain *d, struct vm_event_domain *ved)
 {
 vm_event_response_t rsp;
 
@@ -380,6 +380,9 @@ void vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
  */
 ASSERT(d != current->domain);
 
+if ( unlikely(!vm_event_check_ring(ved)) )
+ return -ENODEV;
+
 /* Pull all responses off the ring. */
 while ( vm_event_get_response(d, ved, &rsp) )
 {
@@ -443,6 +446,8 @@ void vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
 vm_event_vcpu_unpause(v);
 }
 }
+
+return 0;
 }
 
 void vm_event_cancel_slot(struct domain *d, struct vm_event_domain *ved)
@@ -529,30 +534,21 @@ int __vm_event_claim_slot(struct domain *d, struct 
vm_event_domain *ved,
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void mem_paging_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_paging)) )
-vm_event_resume(domain, domain->vm_event_paging);
+vm_event_resume(v->domain, v->domain->vm_event_paging);
 }
 #endif
 
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void monitor_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_monitor)) )
-vm_event_resume(domain, domain->vm_event_monitor);
+vm_event_resume(v->domain, v->domain->vm_event_monitor);
 }
 
 #ifdef CONFIG_HAS_MEM_SHARING
 /* Registered with Xen-bound event channel for incoming notifications. */
 static void mem_sharing_notification(struct vcpu *v, unsigned int port)
 {
-struct domain *domain = v->domain;
-
-if ( likely(vm_event_check_ring(domain->vm_event_share)) )
-vm_event_resume(domain, domain->vm_event_share);
+vm_event_resume(v->domain, v->domain->vm_event_share);
 }
 #endif
 
@@ -676,10 +672,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_paging) )
-vm_event_resume(d, d->vm_event_paging);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_paging);
 break;
 
 default:
@@ -717,10 +710,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_monitor) )
-vm_event_resume(d, d->vm_event_monitor);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_monitor);
 break;
 
 default:
@@ -764,10 +754,7 @@ int vm_event_domctl(struct domain *d, struct 
xen_domctl_vm_event_op *vec,
 break;
 
 case XEN_VM_EVENT_RESUME:
-if ( vm_event_check_ring(d->vm_event_share) )
-vm_event_resume(d, d->vm_event_share);
-else
-rc = -ENODEV;
+rc = vm_event_resume(d, d->vm_event_share);
 break;
 
 default:
diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h
index 5302ee5..53af2d5 100644
--- a/xen/include/xen/vm_event.h
+++ b/xen/include/xen/vm_event.h
@@ -67,8 +67,6 @@ void vm_event_put_request(struct domain *d, struct 
vm_event_domain *ved,
 int vm_event_get_response(struct domain *d, struct vm_event_domain *ved,
   vm_event_response_t *rsp);
 
-void vm_event_resume(struct domain *d, struct vm_event_domain *ved);
-
 int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec,
 XEN_GUEST_HANDLE_PARAM(void) u_domctl);
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH] tools/ocaml: Fix build error with Arch Linux

2019-10-25 Thread Petre Pircalabu
gcc (GCC) 9.2.0 complains:

xentoollog_stubs.c: In function ‘stub_xtl_ocaml_vmessage’:
xentoollog_stubs.c:93:16: error: initialization discards ‘const’ qualifier from 
pointer target type [-Werror=discarded-qualifiers]
   93 |  value *func = caml_named_value(xtl->vmessage_cb) ;
  |^~~~

Signed-off-by: Petre Pircalabu 
---
 tools/ocaml/libs/xentoollog/xentoollog_stubs.c |  4 ++--
 tools/ocaml/libs/xl/xenlight_stubs.c   | 20 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c 
b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
index aadc3d1..1f73f26 100644
--- a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
+++ b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
@@ -90,7 +90,7 @@ static void stub_xtl_ocaml_vmessage(struct xentoollog_logger 
*logger,
CAMLparam0();
CAMLlocalN(args, 4);
struct caml_xtl *xtl = (struct caml_xtl*)logger;
-   value *func = caml_named_value(xtl->vmessage_cb) ;
+   const value *func = caml_named_value(xtl->vmessage_cb) ;
char *msg;
 
if (func == NULL)
@@ -120,7 +120,7 @@ static void stub_xtl_ocaml_progress(struct 
xentoollog_logger *logger,
CAMLparam0();
CAMLlocalN(args, 5);
struct caml_xtl *xtl = (struct caml_xtl*)logger;
-   value *func = caml_named_value(xtl->progress_cb) ;
+   const value *func = caml_named_value(xtl->progress_cb) ;
 
if (func == NULL)
caml_raise_sys_error(caml_copy_string("Unable to find 
callback"));
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index ff16b87..1181971 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -75,7 +75,7 @@ static void failwith_xl(int error, char *fname)
 {
CAMLparam0();
CAMLlocal1(arg);
-   static value *exc = NULL;
+   static const value *exc = NULL;
 
/* First time around, lookup by name */
if (!exc)
@@ -424,7 +424,7 @@ void async_callback(libxl_ctx *ctx, int rc, void 
*for_callback)
caml_leave_blocking_section();
CAMLparam0();
CAMLlocal2(error, tmp);
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) for_callback;
 
if (func == NULL) {
@@ -1133,7 +1133,7 @@ value stub_libxl_xen_console_read_start(value ctx, value 
clear)
 
 static void raise_eof(void)
 {
-   static value *exc = NULL;
+   static const value *exc = NULL;
 
/* First time around, lookup by name */
if (!exc)
@@ -1274,7 +1274,7 @@ int fd_register(void *user, int fd, void 
**for_app_registration_out,
CAMLparam0();
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app;
 
@@ -1317,7 +1317,7 @@ int fd_modify(void *user, int fd, void 
**for_app_registration_update,
CAMLparam0();
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app = *for_app_registration_update;
 
@@ -1356,7 +1356,7 @@ void fd_deregister(void *user, int fd, void 
*for_app_registration)
caml_leave_blocking_section();
CAMLparam0();
CAMLlocalN(args, 3);
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app = for_app_registration;
 
@@ -1398,7 +1398,7 @@ int timeout_register(void *user, void 
**for_app_registration_out,
CAMLlocal2(sec, usec);
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
struct timeout_handles *handles;
 
@@ -1450,7 +1450,7 @@ int timeout_modify(void *user, void 
**for_app_registration_update,
CAMLlocal1(for_app_update);
CAMLlocalN(args, 2);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
struct timeout_handles *handles = *for_app_registration_update;
 
@@ -1566,7 +1566,7 @@ void event_occurs(void *user, libxl_event *event)
CAMLparam0();
CAMLlocalN(args, 2);
struct user_with_ctx *c_user = (struct user_with_ctx *) user;
-   static value *func = NULL;
+   static const value *func = NULL;
 
if (func == NULL) {
/* First time around, lookup by name */
@@ -1589,7 +1589,7 @@ void disaster(void *user, libxl_event_type type,
CAMLparam0();
CAMLlocalN(args, 4);
struct user_with_ctx *c_user = (struct user_with_ctx *) user;
-   static value *func = NULL;
+   static const value *func = NULL;
 
if (func == NULL) {
   

[Xen-devel] [PATCH v2] tools/ocaml: Fix build error with Arch Linux

2019-10-28 Thread Petre Pircalabu
gcc (GCC) 9.2.0 complains:

xentoollog_stubs.c: In function ‘stub_xtl_ocaml_vmessage’:
xentoollog_stubs.c:93:16: error: initialization discards ‘const’ qualifier from 
pointer target type [-Werror=discarded-qualifiers]
   93 |  value *func = caml_named_value(xtl->vmessage_cb) ;
  |^~~~

This patch constifies the pointer returned by caml_named_value in order
to the accommodate newer versions of OCaml.
In OCaml >= 4.09 the return value pointer of caml_named_value is
declared const.

https://github.com/ocaml/ocaml/commit/4f03a1467d29cf587df5a191830f1525506ee0e3

Signed-off-by: Petre Pircalabu 
Reviewed-by: Anthony PERARD 
Release-acked-by: Juergen Gross 
---
 tools/ocaml/libs/xentoollog/xentoollog_stubs.c |  4 ++--
 tools/ocaml/libs/xl/xenlight_stubs.c   | 20 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c 
b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
index aadc3d1..1f73f26 100644
--- a/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
+++ b/tools/ocaml/libs/xentoollog/xentoollog_stubs.c
@@ -90,7 +90,7 @@ static void stub_xtl_ocaml_vmessage(struct xentoollog_logger 
*logger,
CAMLparam0();
CAMLlocalN(args, 4);
struct caml_xtl *xtl = (struct caml_xtl*)logger;
-   value *func = caml_named_value(xtl->vmessage_cb) ;
+   const value *func = caml_named_value(xtl->vmessage_cb) ;
char *msg;
 
if (func == NULL)
@@ -120,7 +120,7 @@ static void stub_xtl_ocaml_progress(struct 
xentoollog_logger *logger,
CAMLparam0();
CAMLlocalN(args, 5);
struct caml_xtl *xtl = (struct caml_xtl*)logger;
-   value *func = caml_named_value(xtl->progress_cb) ;
+   const value *func = caml_named_value(xtl->progress_cb) ;
 
if (func == NULL)
caml_raise_sys_error(caml_copy_string("Unable to find 
callback"));
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index ff16b87..1181971 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -75,7 +75,7 @@ static void failwith_xl(int error, char *fname)
 {
CAMLparam0();
CAMLlocal1(arg);
-   static value *exc = NULL;
+   static const value *exc = NULL;
 
/* First time around, lookup by name */
if (!exc)
@@ -424,7 +424,7 @@ void async_callback(libxl_ctx *ctx, int rc, void 
*for_callback)
caml_leave_blocking_section();
CAMLparam0();
CAMLlocal2(error, tmp);
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) for_callback;
 
if (func == NULL) {
@@ -1133,7 +1133,7 @@ value stub_libxl_xen_console_read_start(value ctx, value 
clear)
 
 static void raise_eof(void)
 {
-   static value *exc = NULL;
+   static const value *exc = NULL;
 
/* First time around, lookup by name */
if (!exc)
@@ -1274,7 +1274,7 @@ int fd_register(void *user, int fd, void 
**for_app_registration_out,
CAMLparam0();
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app;
 
@@ -1317,7 +1317,7 @@ int fd_modify(void *user, int fd, void 
**for_app_registration_update,
CAMLparam0();
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app = *for_app_registration_update;
 
@@ -1356,7 +1356,7 @@ void fd_deregister(void *user, int fd, void 
*for_app_registration)
caml_leave_blocking_section();
CAMLparam0();
CAMLlocalN(args, 3);
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
value *for_app = for_app_registration;
 
@@ -1398,7 +1398,7 @@ int timeout_register(void *user, void 
**for_app_registration_out,
CAMLlocal2(sec, usec);
CAMLlocalN(args, 4);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
struct timeout_handles *handles;
 
@@ -1450,7 +1450,7 @@ int timeout_modify(void *user, void 
**for_app_registration_update,
CAMLlocal1(for_app_update);
CAMLlocalN(args, 2);
int ret = 0;
-   static value *func = NULL;
+   static const value *func = NULL;
value *p = (value *) user;
struct timeout_handles *handles = *for_app_registration_update;
 
@@ -1566,7 +1566,7 @@ void event_occurs(void *user, libxl_event *event)
CAMLparam0();
CAMLlocalN(args, 2);
struct user_with_ctx *c_user = (struct user_with_ctx *) user;
-   static value *func = NULL;
+   static const value *func = NULL;
 
if (func == NULL) {
/* First

[Xen-devel] [PATCH XTF 0/4] Add monitor tests to XTF

2018-12-14 Thread Petre Pircalabu
Extend the framework to support (simple) monitor related tests.

Petre Pircalabu (4):
  xtf-runner: split into logical components
  xtf: Add executable test class
  xtf: Add monitor test class
  xtf: Add emul-unimpl test

 Makefile   |   6 +-
 build/common.mk|  22 ++-
 build/files.mk |   3 +
 build/gen.mk   |  25 ++-
 build/mkinfo.py|  84 +++--
 docs/all-tests.dox |   5 +
 include/monitor/monitor.h  | 117 
 monitor/Makefile   |  20 ++
 monitor/monitor.c  | 409 +
 tests/emul-unimpl/Makefile |  15 ++
 tests/emul-unimpl/extra.cfg.in |   3 +
 tests/emul-unimpl/main.c   |  59 ++
 tests/emul-unimpl/monitor.c| 310 +++
 xtf-runner | 334 -
 xtf/__init__.py|  12 ++
 xtf/domu_test.py   | 179 ++
 xtf/exceptions.py  |   6 +
 xtf/executable_test.py |  83 +
 xtf/logger.py  |  23 +++
 xtf/monitor_test.py| 132 +
 xtf/suite.py   | 100 ++
 xtf/test.py| 139 ++
 xtf/utils.py   |  17 ++
 xtf/xl_domu.py | 121 
 24 files changed, 1900 insertions(+), 324 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 tests/emul-unimpl/Makefile
 create mode 100644 tests/emul-unimpl/extra.cfg.in
 create mode 100644 tests/emul-unimpl/main.c
 create mode 100644 tests/emul-unimpl/monitor.c
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/executable_test.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/utils.py
 create mode 100644 xtf/xl_domu.py

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH XTF 1/4] xtf-runner: split into logical components

2018-12-14 Thread Petre Pircalabu
Split the xtf-runner script file into multiple modules in order to
support multiple test types.

Features:
  - 2 abstract types (TestInfo and TestInstance) to represent the
  test information (info.json) and, respectively to implement the test
  execution.
TestInfo has to implement the "all_instances" method to create the
list of TestInstance objects.
TestInstance has to implement "set_up", "run", and "clean-up"
methods.
  - TestResult - represents an XTF test result (SUCCESS, SKIP, ERROR,
  FAILURE, CRASH). The values should be kept in sync with the C code
  from report.h
  - Dynamic test class loading. Each info.json shoudl contain a
  "class_name" field which specifies the test info class describing the
  test. This value defaults to "xtf.domu_test.DomuTestInfo"
  - custom test info parameters. info.json can have the "extra"
  field, implemented as a dictionary,  which contains parameters
  specific for a certain test info class.
e.g. TEST-EXTRA-INFO := arg1='--address=0x8000 --id=4' arg2=42
  - logger class (print depending on the quiet field)
  - DomuTestInfo/DomuTest instance. Simple test which loads a XEN DomU
  and checks the output for a specific pattern.
  - toolstack abstraction using a wrapper class (e.g.
  (xtf.xl_domu.XLDomU)

Signed-off-by: Petre Pircalabu 
---
 build/gen.mk  |  13 ++-
 build/mkinfo.py   |  84 +++---
 xtf-runner| 334 +-
 xtf/__init__.py   |  12 ++
 xtf/domu_test.py  | 179 +
 xtf/exceptions.py |   6 +
 xtf/logger.py |  23 
 xtf/suite.py  |  97 
 xtf/test.py   | 139 +++
 xtf/xl_domu.py| 121 
 10 files changed, 687 insertions(+), 321 deletions(-)
 create mode 100644 xtf/__init__.py
 create mode 100644 xtf/domu_test.py
 create mode 100644 xtf/exceptions.py
 create mode 100644 xtf/logger.py
 create mode 100644 xtf/suite.py
 create mode 100644 xtf/test.py
 create mode 100644 xtf/xl_domu.py

diff --git a/build/gen.mk b/build/gen.mk
index 8d7a6bf..c19ca6a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -27,12 +27,23 @@ else
 TEST-CFGS := $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME).cfg)
 endif
 
+CLASS ?= "xtf.domu_test.DomuTestInfo"
+
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
 
+MKINFO-OPTS := -n "$(NAME)"
+MKINFO-OPTS += -c "$(CLASS)"
+MKINFO-OPTS += -t "$(CATEGORY)"
+MKINFO-OPTS += -e "$(TEST-ENVS)"
+MKINFO-OPTS += -v "$(VARY-CFG)"
+ifneq (x$(TEST-EXTRA-INFO), x)
+MKINFO-OPTS += -x "$(TEST-EXTRA-INFO)"
+endif
+
 info.json: $(ROOT)/build/mkinfo.py FORCE
-   @$(PYTHON) $< $@.tmp "$(NAME)" "$(CATEGORY)" "$(TEST-ENVS)" 
"$(VARY-CFG)"
+   @$(PYTHON) $< $(MKINFO-OPTS) $@.tmp
@$(call move-if-changed,$@.tmp,$@)
 
 .PHONY: install install-each-env
diff --git a/build/mkinfo.py b/build/mkinfo.py
index 94891a9..afa355c 100644
--- a/build/mkinfo.py
+++ b/build/mkinfo.py
@@ -1,24 +1,74 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+""" mkinfo.py
 
-import sys, os, json
+Generates a test info json file.
+The script is ran at build stage using the parameters specified
+in the test's Makefile.
+"""
 
-# Usage: mkcfg.py $OUT $NAME $CATEGORY $ENVS $VARIATIONS
-_, out, name, cat, envs, variations = sys.argv
+import json
+import sys
+import shlex
+from   optparse import OptionParser
 
-template = {
-"name": name,
-"category": cat,
-"environments": [],
-"variations": [],
-}
+def main():
+""" Main entrypoint """
+# Avoid wrapping the epilog text
+OptionParser.format_epilog = lambda self, formatter: self.epilog
 
-if envs:
-template["environments"] = envs.split(" ")
-if variations:
-template["variations"] = variations.split(" ")
+parser = OptionParser(
+usage = "%prog [OPTIONS] out_file",
+description = "Xen Test Framework json generation tool",
+)
 
-open(out, "w").write(
-json.dumps(template, indent=4, separators=(',', ': '))
-+ "\n"
-)
+parser.add_option("-n", "--name", action = "store",
+  dest = "name",
+  help = "Test name",
+  )
+parser.add_option("-c", "--class", action = "store",
+  dest = "class_name",
+  help = "Test class name",
+  )
+parser.add_option("-t", "--category", action = &

[Xen-devel] [PATCH XTF 4/4] xtf: Add emul-unimpl test

2018-12-14 Thread Petre Pircalabu
Add a new test to verify if XEN can correctly handle the
X86EMUL_UNIMPLEMENTED event.

The XTF DomU test image just executes a instruction not implemented by
the XEN X86 emulator (fstenv) and checks if the execution was
successfull. This instruction will be the first one in a custom .text
section.

In order to instruct XEN to try to emulate that instruction the monitor
application changes the attributes of that specific page in order to
inhibit execution. This will trigger a MEM_ACCESS request that will be
responded by toggling the EMULATE flag.
The emulation will fail, which will trigger an EMUL_UNIMPLEMENTED
request which will be handled by enabling execution on that specific
page (altp2m) and singlestepping that instruction.

The test will be successfull if the instruction can be executed
correctly.

Signed-off-by: Petre Pircalabu 
---
 docs/all-tests.dox |   2 +-
 tests/emul-unimpl/Makefile |  15 ++
 tests/emul-unimpl/extra.cfg.in |   3 +
 tests/emul-unimpl/main.c   |  59 
 tests/emul-unimpl/monitor.c| 310 +
 5 files changed, 388 insertions(+), 1 deletion(-)
 create mode 100644 tests/emul-unimpl/Makefile
 create mode 100644 tests/emul-unimpl/extra.cfg.in
 create mode 100644 tests/emul-unimpl/main.c
 create mode 100644 tests/emul-unimpl/monitor.c

diff --git a/docs/all-tests.dox b/docs/all-tests.dox
index 3ee552e..b7457be 100644
--- a/docs/all-tests.dox
+++ b/docs/all-tests.dox
@@ -149,5 +149,5 @@ enable BTS.
 
 @section index-monitor Monitor
 
-@subpage test-emul_unimplemented - @Test EMUL_UNIMPLEMENTED event generation
+@subpage test-emul-unimpl - @Test EMUL_UNIMPLEMENTED event generation
 */
diff --git a/tests/emul-unimpl/Makefile b/tests/emul-unimpl/Makefile
new file mode 100644
index 000..5d79e42
--- /dev/null
+++ b/tests/emul-unimpl/Makefile
@@ -0,0 +1,15 @@
+include $(ROOT)/build/common.mk
+
+NAME   := emul-unimpl
+CATEGORY   := monitor
+TEST-ENVS  := hvm64
+CLASS  := xtf.monitor_test.MonitorTestInfo
+TEST-EXTRA-INFO:= monitor_args='--address=0x\$$(nm --defined-only 
@@VM_PATH@@ | grep test_fn | cut -d \  -f 1)'
+
+TEST-EXTRA-CFG := extra.cfg.in
+
+obj-perenv += main.o
+
+obj-monitor += monitor.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/emul-unimpl/extra.cfg.in b/tests/emul-unimpl/extra.cfg.in
new file mode 100644
index 000..e432a0c
--- /dev/null
+++ b/tests/emul-unimpl/extra.cfg.in
@@ -0,0 +1,3 @@
+# Enable altp2m
+altp2m = "mixed"
+altp2mhvm = 1
diff --git a/tests/emul-unimpl/main.c b/tests/emul-unimpl/main.c
new file mode 100644
index 000..63a52cc
--- /dev/null
+++ b/tests/emul-unimpl/main.c
@@ -0,0 +1,59 @@
+/**
+ * @file tests/emul-unimpl/main.c
+ * @ref test-emul-unimpl
+ *
+ * @page test-emul-unimpl emul-unimpl
+ *
+ * @todo Docs for test-emul-unimpl
+ *
+ * @see tests/emul-unimpl/main.c
+ */
+#include 
+
+const char test_title[] = "Test emul-unimpl";
+
+static char fpu_env[128];
+
+static void __attribute__((section(".text.secondary"))) __attribute__ 
((noinline)) test_fn(void)
+{
+__asm__ __volatile__("fstenv %0"
+ : "=m" (fpu_env)
+ :
+ : "memory");
+__asm__ __volatile__("fwait");
+}
+
+void test_main(void)
+{
+int i;
+
+__asm__ __volatile__ ("pushf");
+__asm__ __volatile__ ("cli");
+test_fn();
+__asm__ __volatile__ ("popf");
+
+for ( i = 0; i < 14 ; i++ )
+{
+if ( fpu_env[i] != 0 )
+break;
+}
+
+if ( i == 14 )
+{
+xtf_error(NULL);
+}
+else
+{
+xtf_success(NULL);
+}
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tests/emul-unimpl/monitor.c b/tests/emul-unimpl/monitor.c
new file mode 100644
index 000..4302e51
--- /dev/null
+++ b/tests/emul-unimpl/monitor.c
@@ -0,0 +1,310 @@
+/**
+ * @file tests/emul-unimpl/monitor.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+typedef enum
+{
+INIT,
+MEM_ACCESS,
+SINGLESTEP,
+EMUL_UNIMPL
+} emul_unimpl_state_t;
+
+typedef struct emul_unimpl_monitor
+{
+xtf_monitor_t mon;
+domid_t domain_id;
+uint64_t address;
+uint16_t altp2m_view_id;
+unsigned long gfn;
+emul_unimpl_state_t state;
+} emul_unimpl_monitor_t;
+
+const char monitor_test_help[] = \
+"Usage: test-monitor-emul-unimpl [options] \n"
+"\t -a : the address where an invalid instruction will be 
injected\n"
+;
+
+static int emul_unimpl_setup(int argc, char *argv[]);
+static int emul_unimpl_init();
+static int emul_unimpl_run();
+static int emul_unimpl_cleanup();
+static int emul_unimpl_get_result();
+
+static e

[Xen-devel] [PATCH XTF 3/4] xtf: Add monitor test class

2018-12-14 Thread Petre Pircalabu
This class starts alongside the domain a monitor application which opens
an event channel corresponding to that domain and handles the received
requests.
Use the "monitor_args" key to pass test specific arguments to the
monitor application.
The arguments will be added in the test's Makefile using the
TEST-EXTRA-INFO variable.

Signed-off-by: Petre Pircalabu 
---
 Makefile  |   6 +-
 build/common.mk   |  22 ++-
 build/files.mk|   3 +
 build/gen.mk  |  12 ++
 docs/all-tests.dox|   5 +
 include/monitor/monitor.h | 117 +
 monitor/Makefile  |  20 +++
 monitor/monitor.c | 409 ++
 xtf/__init__.py   |   2 +-
 xtf/monitor_test.py   | 132 +++
 xtf/utils.py  |  17 ++
 11 files changed, 741 insertions(+), 4 deletions(-)
 create mode 100644 include/monitor/monitor.h
 create mode 100644 monitor/Makefile
 create mode 100644 monitor/monitor.c
 create mode 100644 xtf/monitor_test.py
 create mode 100644 xtf/utils.py

diff --git a/Makefile b/Makefile
index 15a865f..db28075 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,9 @@ INSTALL_PROGRAM := $(INSTALL) -p
 OBJCOPY := $(CROSS_COMPILE)objcopy
 PYTHON  := python
 
-export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON
+HOSTCC  := gcc
+
+export CC CPP INSTALL INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM OBJCOPY PYTHON 
HOSTCC
 
 .PHONY: all
 all:
@@ -51,7 +53,7 @@ install:
done
 
 define all_sources
-   find include/ arch/ common/ tests/ -name "*.[hcsS]"
+   find include/ arch/ common/ tests/ monitor/ -name "*.[hcsS]"
 endef
 
 .PHONY: cscope
diff --git a/build/common.mk b/build/common.mk
index b786ddf..1ec0fa4 100644
--- a/build/common.mk
+++ b/build/common.mk
@@ -1,4 +1,4 @@
-ALL_CATEGORIES := special functional xsa utility in-development
+ALL_CATEGORIES := special functional xsa utility in-development monitor
 
 ALL_ENVIRONMENTS   := pv64 pv32pae hvm64 hvm32pae hvm32pse hvm32
 
@@ -35,11 +35,20 @@ COMMON_AFLAGS-x86_64 := -m64
 COMMON_CFLAGS-x86_32 := -m32
 COMMON_CFLAGS-x86_64 := -m64
 
+#HOSTCFLAGS := -Wall -Werror
+HOSTCFLAGS  :=
+HOSTLDFLAGS :=
+HOSTLDLIBS  :=
+HOSTCFLAGS  += -D__XEN_TOOLS__ -g -O3 -I$(ROOT)/include/monitor
+HOSTCFLAGS  += -DXC_WANT_COMPAT_DEVICEMODEL_API 
-DXC_WANT_COMPAT_MAP_FOREIGN_API
+HOSTLDLIBS  += -lxenctrl -lxenstore -lxenevtchn
+
 defcfg-pv:= $(ROOT)/config/default-pv.cfg.in
 defcfg-hvm   := $(ROOT)/config/default-hvm.cfg.in
 
 obj-perarch :=
 obj-perenv  :=
+obj-monitor :=
 include $(ROOT)/build/files.mk
 
 
@@ -90,8 +99,19 @@ DEPS-$(1) = $$(head-$(1)) \
 
 endef
 
+# Setup monitor rules
+define MONITOR_setup
+DEPS-MONITOR = \
+   $$(obj-monitor:%.o=%-monitor.o)
+
+%-monitor.o: %.c
+   $$(HOSTCC) $$(HOSTCFLAGS) -c $$< -o $$@
+endef
+
 $(foreach env,$(ALL_ENVIRONMENTS),$(eval $(call PERENV_setup,$(env
 
+$(eval $(call MONITOR_setup))
+
 define move-if-changed
if ! cmp -s $(1) $(2); then mv -f $(1) $(2); else rm -f $(1); fi
 endef
diff --git a/build/files.mk b/build/files.mk
index dfa27e4..972c797 100644
--- a/build/files.mk
+++ b/build/files.mk
@@ -54,3 +54,6 @@ $(foreach env,$(32BIT_ENVIRONMENTS),$(eval obj-$(env) += 
$(obj-32)))
 # 64bit specific objects
 obj-64  += $(ROOT)/arch/x86/entry_64.o
 $(foreach env,$(64BIT_ENVIRONMENTS),$(eval obj-$(env) += $(obj-64)))
+
+# Monitor common objects
+obj-monitor += $(ROOT)/monitor/monitor.o
diff --git a/build/gen.mk b/build/gen.mk
index c19ca6a..1e6773a 100644
--- a/build/gen.mk
+++ b/build/gen.mk
@@ -32,6 +32,9 @@ CLASS ?= "xtf.domu_test.DomuTestInfo"
 .PHONY: build
 build: $(foreach env,$(TEST-ENVS),test-$(env)-$(NAME)) $(TEST-CFGS)
 build: info.json
+ifeq (x$(CATEGORY),xmonitor)
+build: test-monitor-$(NAME)
+endif
 
 MKINFO-OPTS := -n "$(NAME)"
 MKINFO-OPTS += -c "$(CLASS)"
@@ -100,6 +103,15 @@ install-each-env: install-$(1) install-$(1).cfg
 endef
 $(foreach env,$(TEST-ENVS),$(eval $(call PERENV_build,$(env
 
+define MONITOR_build
+test-monitor-$(NAME): $(DEPS-MONITOR)
+   @echo $(obj-monitor)
+   @echo $(DEPS-MONITOR)
+   $(HOSTCC) $(HOSTLDFLAGS) $(DEPS-MONITOR) $(HOSTLDLIBS) -o $$@
+endef
+
+$(eval $(call MONITOR_build))
+
 .PHONY: clean
 clean:
find $(ROOT) \( -name "*.o" -o -name "*.d" \) -delete
diff --git a/docs/all-tests.dox b/docs/all-tests.dox
index 732d44c..3ee552e 100644
--- a/docs/all-tests.dox
+++ b/docs/all-tests.dox
@@ -145,4 +145,9 @@ enable BTS.
 @subpage test-nested-svm - Nested SVM tests.
 
 @subpage test-nested-vmx - Nested VT-x tests.
+
+
+@section index-monitor Monitor
+
+@subpage test-emul_unimplemented - @Test EMUL_UNIMPLEMENTED event generation
 */
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
new file mode 100644
index 000..d01c259
--- /dev/null
+++ b/include/monitor/monitor.

[Xen-devel] [PATCH XTF 2/4] xtf: Add executable test class

2018-12-14 Thread Petre Pircalabu
The Executable test class runs on host (dom0). The class spawns a
process and searches the program output(stdio) for a specific pattern.

Signed-off-by: Petre Pircalabu 
---
 xtf/__init__.py|  2 +-
 xtf/executable_test.py | 83 ++
 xtf/suite.py   |  5 ++-
 3 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 xtf/executable_test.py

diff --git a/xtf/__init__.py b/xtf/__init__.py
index 889c1d5..07c269a 100644
--- a/xtf/__init__.py
+++ b/xtf/__init__.py
@@ -3,7 +3,7 @@
 
 # All test categories
 default_categories = set(("functional", "xsa"))
-non_default_categories = set(("special", "utility", "in-development"))
+non_default_categories = set(("special", "utility", "in-development", "host"))
 all_categories = default_categories | non_default_categories
 
 # All test environments
diff --git a/xtf/executable_test.py b/xtf/executable_test.py
new file mode 100644
index 000..31aa6e4
--- /dev/null
+++ b/xtf/executable_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Executable test classes
+
+Spawns a process and waits for a specific pattern
+"""
+
+import StringIO
+import pexpect
+
+from xtf.logger import Logger
+from xtf.test import TestInstance, TestInfo, TestResult
+
+class ExecutableTestInstance(TestInstance):
+"""Executable Test Instance"""
+def __init__(self, name, cmd, args, pattern):
+super(ExecutableTestInstance, self).__init__(name)
+
+self._cmd = cmd
+self._args = [x.encode('utf-8') for x in args]
+self._pattern = [x.encode('utf-8') for x in pattern]
+self._proc = None
+self.env = "dom0"
+self.output = StringIO.StringIO()
+
+def __repr__(self):
+return "test-%s-%s" %(self.env, self.name)
+
+def wait_pattern(self, pattern):
+"""Expect the pattern given as parameter."""
+return self._proc.expect(pattern + [pexpect.TIMEOUT, pexpect.EOF])
+
+def set_up(self, opts, result):
+self._proc = pexpect.spawn(self._cmd, self._args, logfile = 
self.output)
+print self._cmd, self._args
+
+if self._proc is None:
+result.set(TestResult.ERROR)
+
+def run(self, result):
+"""Executes the test instance"""
+if self.wait_pattern(self._pattern) > len(self._pattern):
+result.set(TestResult.FAILURE)
+return
+
+result.set(TestResult.SUCCESS)
+
+def clean_up(self, result):
+if self.output:
+Logger().log(self.output.getvalue())
+self.output.close()
+
+class ExecutableTestInfo(TestInfo):
+""" Object representing a tests info.json, in a more convenient form. """
+
+def __init__(self, test_json):
+super(ExecutableTestInfo, self).__init__(test_json)
+self.instance_class = ExecutableTestInstance
+
+cmd = test_json["cmd"]
+if not isinstance(cmd, (str, unicode)):
+raise TypeError("Expected string for 'cmd', got '%s')"
+% (type(cmd), ))
+self.cmd = cmd
+
+args = test_json["args"]
+if not isinstance(args, list):
+raise TypeError("Expected list for 'args', got '%s')"
+% (type(args), ))
+self.args = args
+
+pattern = test_json["pattern"]
+if not isinstance(pattern, list):
+raise TypeError("Expected list for 'pattern', got '%s')"
+% (type(pattern), ))
+self.pattern = pattern
+
+def all_instances(self, env_filter = None, vary_filter = None):
+"""Returns an ExecutableTestInstance object"""
+return [self.instance_class(self.name, self.cmd, self.args,
+self.pattern),]
diff --git a/xtf/suite.py b/xtf/suite.py
index ad7d30f..2e0727c 100644
--- a/xtf/suite.py
+++ b/xtf/suite.py
@@ -75,7 +75,10 @@ def gather_all_test_info():
 try:
 info_file = open(path.join("tests", test, "info.json"))
 except IOError:
-continue
+try:
+info_file = open(path.join("tests", test, "host.json"))
+except IOError:
+continue
 
 # Ignore tests which have bad JSON
 try:
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [RFC PATCH 1/6] tools/libxc: Consistent usage of xc_vm_event_* interface

2018-12-19 Thread Petre Pircalabu
Modified xc_mem_paging_enable to use directly xc_vm_event_enable and
moved the ring_page handling from client to libxc (xenpaging).

Restricted vm_event_control usage only to simplest domctls which do
not expect any return values and change xc_vm_event_enable to call do_domctl
directly.

Removed xc_memshr_ring_enable/disable and xc_memshr_domain_resume.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h | 49 +
 tools/libxc/xc_mem_paging.c   | 23 +---
 tools/libxc/xc_memshr.c   | 34 ---
 tools/libxc/xc_monitor.c  | 31 +
 tools/libxc/xc_private.h  |  2 +-
 tools/libxc/xc_vm_event.c | 64 ---
 tools/xenpaging/xenpaging.c   | 42 +++-
 7 files changed, 62 insertions(+), 183 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 97ae965..de0b990 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1962,7 +1962,7 @@ int xc_altp2m_change_gfn(xc_interface *handle, uint32_t 
domid,
  * Hardware-Assisted Paging (i.e. Intel EPT, AMD NPT). Moreover, AMD NPT
  * support is considered experimental.
  */
-int xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, uint32_t 
*port);
+void *xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, uint32_t 
*port);
 int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id);
 int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id);
 int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id,
@@ -2090,53 +2090,6 @@ int xc_memshr_control(xc_interface *xch,
   uint32_t domid,
   int enable);
 
-/* Create a communication ring in which the hypervisor will place ENOMEM
- * notifications.
- *
- * ENOMEM happens when unsharing pages: a Copy-on-Write duplicate needs to be
- * allocated, and thus the out-of-memory error occurr.
- *
- * For complete examples on how to plumb a notification ring, look into
- * xenpaging or xen-access.
- *
- * On receipt of a notification, the helper should ensure there is memory
- * available to the domain before retrying.
- *
- * If a domain encounters an ENOMEM condition when sharing and this ring
- * has not been set up, the hypervisor will crash the domain.
- *
- * Fails with:
- *  EINVAL if port is NULL
- *  EINVAL if the sharing ring has already been enabled
- *  ENOSYS if no guest gfn has been specified to host the ring via an hvm param
- *  EINVAL if the gfn for the ring has not been populated
- *  ENOENT if the gfn for the ring is paged out, or cannot be unshared
- *  EINVAL if the gfn for the ring cannot be written to
- *  EINVAL if the domain is dying
- *  ENOSPC if an event channel cannot be allocated for the ring
- *  ENOMEM if memory cannot be allocated for internal data structures
- *  EINVAL or EACCESS if the request is denied by the security policy
- */
-
-int xc_memshr_ring_enable(xc_interface *xch, 
-  uint32_t domid,
-  uint32_t *port);
-/* Disable the ring for ENOMEM communication.
- * May fail with EINVAL if the ring was not enabled in the first place.
- */
-int xc_memshr_ring_disable(xc_interface *xch, 
-   uint32_t domid);
-
-/*
- * Calls below return EINVAL if sharing has not been enabled for the domain
- * Calls below return EINVAL if the domain is dying
- */
-/* Once a reponse to an ENOMEM notification is prepared, the tool can
- * notify the hypervisor to re-schedule the faulting vcpu of the domain with an
- * event channel kick and/or this call. */
-int xc_memshr_domain_resume(xc_interface *xch,
-uint32_t domid);
-
 /* Select a page for sharing. 
  *
  * A 64 bit opaque handle will be stored in handle.  The hypervisor ensures
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index a067706..08468fb 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -37,35 +37,26 @@ static int xc_mem_paging_memop(xc_interface *xch, uint32_t 
domain_id,
 return do_memory_op(xch, XENMEM_paging_op, &mpo, sizeof(mpo));
 }
 
-int xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id,
- uint32_t *port)
+void *xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id,
+   uint32_t *port)
 {
-if ( !port )
-{
-errno = EINVAL;
-return -1;
-}
-
-return xc_vm_event_control(xch, domain_id,
-   XEN_VM_EVENT_ENABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING,
-   port);
+return xc_vm_event_enable(xch, domain_id,
+  XEN_DOMCTL_VM_EVENT_OP_PAGING,
+  port);
 }
 
 int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domai

[Xen-devel] [PATCH RFC 0/6] Slotted channels for sync vm_events

2018-12-19 Thread Petre Pircalabu
This patchset is a rework of the "multi-page ring buffer" for vm_events
patch based on Andrew Cooper's comments.
For synchronous vm_events the ring waitqueue logic was unnecessary as the
vcpu sending the request was blocked until a response was received.
To simplify the request/response mechanism, an array of slotted channels
was created, one per vcpu. Each vcpu puts the request in the
corresponding slot and blocks until the response is received.

I'm sending this patch as a RFC because, while I'm still working on way to
measure the overall performance improvement, your feedback would be a great
assistance.

Petre Pircalabu (6):
  tools/libxc: Consistent usage of xc_vm_event_* interface
  tools/libxc: Define VM_EVENT type
  vm_event: Refactor vm_event_domain implementation
  vm_event: Use slotted channels for sync requests.
  xen-access: add support for slotted channel vm_events
  xc_version: add vm_event interface version

 tools/libxc/include/xenctrl.h   |  60 +--
 tools/libxc/xc_mem_paging.c |  23 +-
 tools/libxc/xc_memshr.c |  34 --
 tools/libxc/xc_monitor.c|  67 ++-
 tools/libxc/xc_private.c|   3 +
 tools/libxc/xc_private.h|  22 +-
 tools/libxc/xc_vm_event.c   | 192 ---
 tools/tests/xen-access/xen-access.c | 545 
 tools/xenpaging/xenpaging.c |  42 +-
 xen/arch/arm/mem_access.c   |   2 +-
 xen/arch/x86/mm.c   |   7 +
 xen/arch/x86/mm/mem_access.c|   4 +-
 xen/arch/x86/mm/mem_paging.c|   2 +-
 xen/arch/x86/mm/mem_sharing.c   |   5 +-
 xen/arch/x86/mm/p2m.c   |  10 +-
 xen/common/kernel.c |   3 +
 xen/common/mem_access.c |   2 +-
 xen/common/monitor.c|   4 +-
 xen/common/vm_event.c   | 972 +++-
 xen/drivers/passthrough/pci.c   |   2 +-
 xen/include/public/domctl.h |  64 ++-
 xen/include/public/memory.h |   2 +
 xen/include/public/version.h|   3 +
 xen/include/public/vm_event.h   |  15 +
 xen/include/xen/sched.h |  25 +-
 xen/include/xen/vm_event.h  |  30 +-
 26 files changed, 1511 insertions(+), 629 deletions(-)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [RFC PATCH 5/6] xen-access: add support for slotted channel vm_events

2018-12-19 Thread Petre Pircalabu
Signed-off-by: Petre Pircalabu 
---
 tools/tests/xen-access/xen-access.c | 545 +---
 1 file changed, 441 insertions(+), 104 deletions(-)

diff --git a/tools/tests/xen-access/xen-access.c 
b/tools/tests/xen-access/xen-access.c
index 6aaee16..b09be6c 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -62,13 +62,33 @@
 /* From xen/include/asm-x86/x86-defns.h */
 #define X86_CR4_PGE0x0080 /* enable global pages */
 
-typedef struct vm_event {
-domid_t domain_id;
+#ifndef round_pgup
+#define round_pgup(p)(((p) + (XC_PAGE_SIZE - 1)) & XC_PAGE_MASK)
+#endif /* round_pgup */
+
+struct vm_event_ring
+{
 xenevtchn_handle *xce_handle;
 int port;
 vm_event_back_ring_t back_ring;
 uint32_t evtchn_port;
-void *ring_page;
+void *buffer;
+unsigned int page_count;
+};
+
+struct vm_event_channel
+{
+xenevtchn_handle **xce_handles;
+int *ports;
+uint32_t *evtchn_ports;
+void *buffer;
+};
+
+typedef struct vm_event {
+domid_t domain_id;
+unsigned int num_vcpus;
+struct vm_event_ring *ring;
+struct vm_event_channel *channel;
 } vm_event_t;
 
 typedef struct xenaccess {
@@ -79,6 +99,7 @@ typedef struct xenaccess {
 vm_event_t vm_event;
 } xenaccess_t;
 
+
 static int interrupted;
 bool evtchn_bind = 0, evtchn_open = 0, mem_access_enable = 0;
 
@@ -87,45 +108,224 @@ static void close_handler(int sig)
 interrupted = sig;
 }
 
-int xc_wait_for_event_or_timeout(xc_interface *xch, xenevtchn_handle *xce, 
unsigned long ms)
+static int vcpu_id_by_port(vm_event_t *vm_event, int port)
 {
-struct pollfd fd = { .fd = xenevtchn_fd(xce), .events = POLLIN | POLLERR };
-int port;
-int rc;
+int i;
+
+if ( port == vm_event->ring->port )
+return 0;
+
+if ( vm_event->channel )
+for ( i = 0; i < vm_event->num_vcpus; i++ )
+if ( vm_event->channel->ports[i] == port )
+return i;
+
+return -1;
+}
+
+static int xenaccess_wait_for_events(xenaccess_t *xenaccess,
+ int **_ports,
+ unsigned long ms)
+{
+struct pollfd *fds;
+vm_event_t *vm_event;
+int rc, fd_count = 0, i = 0, found = 0;
+int *ports = NULL;
+
+vm_event = &xenaccess->vm_event;
 
-rc = poll(&fd, 1, ms);
-if ( rc == -1 )
+fd_count = ((vm_event->channel) ? vm_event->num_vcpus : 0) + 1;
+
+fds = calloc(fd_count, sizeof(struct pollfd));
+
+if ( vm_event->channel )
 {
-if (errno == EINTR)
-return 0;
+for (i = 0; i < vm_event->num_vcpus; i++ )
+{
+fds[i].fd = xenevtchn_fd(vm_event->channel->xce_handles[i]);
+fds[i].events = POLLIN | POLLERR;
+fds[i].revents = 0;
+}
+}
 
-ERROR("Poll exited with an error");
-goto err;
+fds[i].fd = xenevtchn_fd(vm_event->ring->xce_handle);
+fds[i].events = POLLIN | POLLERR;
+fds[i].revents = 0;
+
+rc = poll(fds, fd_count, ms);
+if ( rc == -1 || rc == 0 )
+{
+if ( errno == EINTR )
+rc = 0;
+goto cleanup;
 }
 
-if ( rc == 1 )
+ports = malloc(rc * sizeof(int));
+
+for ( i = 0; i < fd_count ; i++ )
 {
-port = xenevtchn_pending(xce);
-if ( port == -1 )
+if ( fds[i].revents & POLLIN )
 {
-ERROR("Failed to read port from event channel");
-goto err;
+bool ring_event = i == (fd_count-1);
+xenevtchn_handle *xce = ( ring_event ) ? 
vm_event->ring->xce_handle :
+ 
vm_event->channel->xce_handles[i];
+int port = xenevtchn_pending(xce);
+
+if ( port == -1 )
+{
+ERROR("Failed to read port from event channel");
+rc = -1;
+goto cleanup;
+}
+
+if ( ring_event )
+{
+if ( RING_HAS_UNCONSUMED_REQUESTS(&vm_event->ring->back_ring) )
+ports[found++] = port;
+
+if ( xenevtchn_unmask(xce, port) )
+{
+ERROR("Failed to unmask event channel port");
+rc = -1;
+goto cleanup;
+}
+}
+else
+{
+int vcpu_id = vcpu_id_by_port(vm_event, port);
+struct vm_event_slot *slot;
+
+if ( vcpu_id < 0 )
+{
+ERROR("Failed to get the vm_event_slot for port %d\n", 
port);
+rc = -1;
+goto cleanup;
+}
+slot = &((struct vm_event_slot 
*)vm_event->channel->buffer)[vcpu_id];

[Xen-devel] [RFC PATCH 4/6] vm_event: Use slotted channels for sync requests.

2018-12-19 Thread Petre Pircalabu
In high throughput introspection scenarios where lots of monitor
vm_events are generated, the ring buffer can fill up before the monitor
application gets a chance to handle all the requests thus blocking
other vcpus which will have to wait for a slot to become available.

This patch adds support for a different mechanism to handle synchronous
vm_event requests / responses. As each synchronous request pauses the
vcpu until the corresponsing response is handled, it can be stored in
a slotted memory buffer (one per vcpu) shared between the hypervisor and
the controlling domain. The asynchronous vm_event requests will be sent
to the controlling domain using a ring buffer, but without blocking the
vcpu as no response is required.

The memory for the asynchronous ring and the synchronous channels will
be allocated from domheap and mapped to the controlling domain using the
foreignmemory_map_resource interface. Unlike the current implementation,
the allocated pages are not part of the target DomU, so they will not be
reclaimed when the vm_event domain is disabled.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |  11 +
 tools/libxc/xc_monitor.c  |  36 +++
 tools/libxc/xc_private.h  |  14 ++
 tools/libxc/xc_vm_event.c |  74 +-
 xen/arch/x86/mm.c |   7 +
 xen/common/vm_event.c | 515 ++
 xen/include/public/domctl.h   |  25 +-
 xen/include/public/memory.h   |   2 +
 xen/include/public/vm_event.h |  15 ++
 xen/include/xen/vm_event.h|   4 +
 10 files changed, 660 insertions(+), 43 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index de0b990..fad8bc4 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2012,6 +2012,17 @@ int xc_get_mem_access(xc_interface *xch, uint32_t 
domain_id,
  * Caller has to unmap this page when done.
  */
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port);
+
+struct xenforeignmemory_resource_handle *xc_monitor_enable_ex(
+xc_interface *xch,
+uint32_t domain_id,
+void **_ring_buffer,
+uint32_t ring_frames,
+uint32_t *ring_port,
+void **_sync_buffer,
+uint32_t *sync_ports,
+uint32_t nr_sync_channels);
+
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id);
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id);
 /*
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 718fe8b..4ceb528 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -49,6 +49,42 @@ void *xc_monitor_enable(xc_interface *xch, uint32_t 
domain_id, uint32_t *port)
 return buffer;
 }
 
+struct xenforeignmemory_resource_handle *xc_monitor_enable_ex(
+xc_interface *xch,
+uint32_t domain_id,
+void **_ring_buffer,
+uint32_t ring_frames,
+uint32_t *ring_port,
+void **_sync_buffer,
+uint32_t *sync_ports,
+uint32_t nr_sync_channels)
+{
+xenforeignmemory_resource_handle *fres;
+int saved_errno;
+
+/* Pause the domain for ring page setup */
+if ( xc_domain_pause(xch, domain_id) )
+{
+PERROR("Unable to pause domain\n");
+return NULL;
+}
+
+fres = xc_vm_event_enable_ex(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR,
+_ring_buffer, ring_frames, ring_port,
+_sync_buffer, sync_ports, nr_sync_channels);
+
+saved_errno = errno;
+if ( xc_domain_unpause(xch, domain_id) )
+{
+if ( fres )
+saved_errno = errno;
+PERROR("Unable to unpause domain");
+}
+
+errno = saved_errno;
+return fres;
+}
+
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 482451c..1f70223 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -420,6 +420,20 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
+/*
+ * Enables vm_event for using the xenforeignmemory_map_resource interface.
+ * The vm_event type can be XEN_VM_EVENT_TYPE_(PAGING/MONITOR/SHARING).
+ *
+ * The function returns:
+ *  - A ring for asynchronous vm_events.
+ *  - A slotted buffer for synchronous vm_events (one slot per vcpu)
+ *  - xenforeignmemory_resource_handle used exclusively for resource cleanup
+ */
+xenforeignmemory_resource_handle *xc_vm_event_enable_ex(xc_interface *xch,
+uint32_t domain_id, int type,
+void **_ring_buffer, uint32_t ring_frames, uint32_t *ring_port,
+void **_sync_buffer, uint32_t *sync_ports, uint32_t nr_sync_channels);
+
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
 
 #endif /* __XC_PRIVATE_H__ */
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc

[Xen-devel] [RFC PATCH 2/6] tools/libxc: Define VM_EVENT type

2018-12-19 Thread Petre Pircalabu
Define the type for each of the supported vm_event rings (paging,
monitor and sharing) and replace the ring param field with this type.

Replace XEN_DOMCTL_VM_EVENT_OP_ occurrences with their corresponding
XEN_VM_EVENT_TYPE_ counterpart.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/xc_mem_paging.c |  6 ++--
 tools/libxc/xc_monitor.c|  6 ++--
 tools/libxc/xc_private.h|  8 +++---
 tools/libxc/xc_vm_event.c   | 68 ++---
 xen/common/vm_event.c   | 12 
 xen/include/public/domctl.h | 45 --
 6 files changed, 73 insertions(+), 72 deletions(-)

diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index 08468fb..37a8224 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -41,7 +41,7 @@ void *xc_mem_paging_enable(xc_interface *xch, uint32_t 
domain_id,
uint32_t *port)
 {
 return xc_vm_event_enable(xch, domain_id,
-  XEN_DOMCTL_VM_EVENT_OP_PAGING,
+  XEN_VM_EVENT_TYPE_PAGING,
   port);
 }
 
@@ -49,14 +49,14 @@ int xc_mem_paging_disable(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING);
+   XEN_VM_EVENT_TYPE_PAGING);
 }
 
 int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING);
+   XEN_VM_EVENT_TYPE_PAGING);
 }
 
 int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id, uint64_t gfn)
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index d190c29..718fe8b 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -35,7 +35,7 @@ void *xc_monitor_enable(xc_interface *xch, uint32_t 
domain_id, uint32_t *port)
 }
 
 buffer = xc_vm_event_enable(xch, domain_id,
-HVM_PARAM_MONITOR_RING_PFN,
+XEN_VM_EVENT_TYPE_MONITOR,
 port);
 saved_errno = errno;
 if ( xc_domain_unpause(xch, domain_id) )
@@ -53,14 +53,14 @@ int xc_monitor_disable(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR);
+   XEN_VM_EVENT_TYPE_MONITOR);
 }
 
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR);
+   XEN_VM_EVENT_TYPE_MONITOR);
 }
 
 int xc_monitor_get_capabilities(xc_interface *xch, uint32_t domain_id,
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 663e78b..482451c 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -412,12 +412,12 @@ int xc_ffs64(uint64_t x);
  * vm_event operations. Internal use only.
  */
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
-unsigned int mode);
+unsigned int type);
 /*
- * Enables vm_event and returns the mapped ring page indicated by param.
- * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN
+ * Enables vm_event and returns the mapped ring page indicated by type.
+ * type can be XEN_VM_EVENT_TYPE_(PAGING/MONITOR/SHARING)
  */
-void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param,
+void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index d9e3a49..4fc2548 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -23,29 +23,54 @@
 #include "xc_private.h"
 
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
-unsigned int mode)
+unsigned int type)
 {
 DECLARE_DOMCTL;
 
 domctl.cmd = XEN_DOMCTL_vm_event_op;
 domctl.domain = domain_id;
 domctl.u.vm_event_op.op = op;
-domctl.u.vm_event_op.mode = mode;
+domctl.u.vm_event_op.type = type;
 
 return do_domctl(xch, &domctl);
 }
 
-void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param,
+static int xc_vm_event_ring_pfn_param(int type, int *param)
+{
+if ( !param )
+return -EINVAL;
+
+switch ( type )
+{
+case XEN_VM_EVENT_TYPE_PAGING:
+*param = HVM_PARAM_PAGING_RING_PFN;

[Xen-devel] [RFC PATCH 6/6] xc_version: add vm_event interface version

2018-12-19 Thread Petre Pircalabu
Signed-off-by: Petre Pircalabu 
---
 tools/libxc/xc_private.c | 3 +++
 xen/common/kernel.c  | 3 +++
 xen/include/public/version.h | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index 90974d5..9b983e0 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -497,6 +497,9 @@ int xc_version(xc_interface *xch, int cmd, void *arg)
 HYPERCALL_BOUNCE_SET_DIR(arg, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 break;
 }
+case XENVER_vm_event_version:
+sz = 0;
+break;
 default:
 ERROR("xc_version: unknown command %d\n", cmd);
 return -EINVAL;
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 5766a0f..667552c 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -516,6 +516,9 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 
 return sz;
 }
+
+case XENVER_vm_event_version:
+return VM_EVENT_INTERFACE_VERSION;
 }
 
 return -ENOSYS;
diff --git a/xen/include/public/version.h b/xen/include/public/version.h
index 7063e8c..b962386 100644
--- a/xen/include/public/version.h
+++ b/xen/include/public/version.h
@@ -103,6 +103,9 @@ struct xen_build_id {
 };
 typedef struct xen_build_id xen_build_id_t;
 
+/* arg == NULL; returns the vm_event interface version */
+#define XENVER_vm_event_version 11
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
 
 /*
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [RFC PATCH 3/6] vm_event: Refactor vm_event_domain implementation

2018-12-19 Thread Petre Pircalabu
Decouple the VM Event interface from the ring implementation.
---
 xen/arch/arm/mem_access.c |   2 +-
 xen/arch/x86/mm/mem_access.c  |   4 +-
 xen/arch/x86/mm/mem_paging.c  |   2 +-
 xen/arch/x86/mm/mem_sharing.c |   5 +-
 xen/arch/x86/mm/p2m.c |  10 +-
 xen/common/mem_access.c   |   2 +-
 xen/common/monitor.c  |   4 +-
 xen/common/vm_event.c | 503 --
 xen/drivers/passthrough/pci.c |   2 +-
 xen/include/xen/sched.h   |  25 +--
 xen/include/xen/vm_event.h|  26 +--
 11 files changed, 312 insertions(+), 273 deletions(-)

diff --git a/xen/arch/arm/mem_access.c b/xen/arch/arm/mem_access.c
index db49372..ba0114a 100644
--- a/xen/arch/arm/mem_access.c
+++ b/xen/arch/arm/mem_access.c
@@ -290,7 +290,7 @@ bool p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const 
struct npfec npfec)
 }
 
 /* Otherwise, check if there is a vm_event monitor subscriber */
-if ( !vm_event_check_ring(v->domain->vm_event_monitor) )
+if ( !vm_event_check(v->domain->vm_event_monitor) )
 {
 /* No listener */
 if ( p2m->access_required )
diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c
index 56c06a4..57aeda7 100644
--- a/xen/arch/x86/mm/mem_access.c
+++ b/xen/arch/x86/mm/mem_access.c
@@ -182,7 +182,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 gfn_unlock(p2m, gfn, 0);
 
 /* Otherwise, check if there is a memory event listener, and send the 
message along */
-if ( !vm_event_check_ring(d->vm_event_monitor) || !req_ptr )
+if ( !vm_event_check(d->vm_event_monitor) || !req_ptr )
 {
 /* No listener */
 if ( p2m->access_required )
@@ -210,7 +210,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 return true;
 }
 }
-if ( vm_event_check_ring(d->vm_event_monitor) &&
+if ( vm_event_check(d->vm_event_monitor) &&
  d->arch.monitor.inguest_pagefault_disabled &&
  npfec.kind != npfec_kind_with_gla ) /* don't send a mem_event */
 {
diff --git a/xen/arch/x86/mm/mem_paging.c b/xen/arch/x86/mm/mem_paging.c
index 54a94fa..dc2a59a 100644
--- a/xen/arch/x86/mm/mem_paging.c
+++ b/xen/arch/x86/mm/mem_paging.c
@@ -44,7 +44,7 @@ int 
mem_paging_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_paging_op_t) arg)
 goto out;
 
 rc = -ENODEV;
-if ( unlikely(!vm_event_check_ring(d->vm_event_paging)) )
+if ( unlikely(!vm_event_check(d->vm_event_paging)) )
 goto out;
 
 switch( mpo.op )
diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index 5ac9d8f..91e92a7 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -557,8 +557,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 .u.mem_sharing.p2mt = p2m_ram_shared
 };
 
-if ( (rc = __vm_event_claim_slot(d, 
-d->vm_event_share, allow_sleep)) < 0 )
+if ( (rc = __vm_event_claim_slot(d->vm_event_share, allow_sleep)) < 0 )
 return rc;
 
 if ( v->domain == d )
@@ -567,7 +566,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 vm_event_vcpu_pause(v);
 }
 
-vm_event_put_request(d, d->vm_event_share, &req);
+vm_event_put_request(d->vm_event_share, &req);
 
 return 0;
 }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index fea4497..3876dda 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1462,7 +1462,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
  * correctness of the guest execution at this point.  If this is the only
  * page that happens to be paged-out, we'll be okay..  but it's likely the
  * guest will crash shortly anyways. */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
+int rc = vm_event_claim_slot(d->vm_event_paging);
 if ( rc < 0 )
 return;
 
@@ -1476,7 +1476,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
 /* Evict will fail now, tag this request for pager */
 req.u.mem_paging.flags |= MEM_PAGING_EVICT_FAIL;
 
-vm_event_put_request(d, d->vm_event_paging, &req);
+vm_event_put_request(d->vm_event_paging, &req);
 }
 
 /**
@@ -1514,7 +1514,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
 /* We're paging. There should be a ring */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
+int rc = vm_event_claim_slot(d->vm_event_paging);
 if ( rc == -ENOSYS )
 {
 gdprintk(XENLOG_ERR, "Domain %hu paging gfn %lx yet no ring "
@@ -1555,7 +1555,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 {
 /* gfn is already on its way back and vcpu is not paused */
 out_cancel:
-vm_event_cancel_slot(d, d->vm_event_paging);
+vm_event_cancel_slot(d->vm_event_paging);
 return;
 }
 
@@ -1563

[Xen-devel] [PATCH v11] x86/altp2m: support for setting restrictions for an array of pages

2018-03-30 Thread Petre Pircalabu
From: Razvan Cojocaru 

For the default EPT view we have xc_set_mem_access_multi(), which
is able to set an array of pages to an array of access rights with
a single hypercall. However, this functionality was lacking for the
altp2m subsystem, which could only set page restrictions for one
page at a time. This patch addresses the gap.

HVMOP_altp2m_set_mem_access_multi has been added as a HVMOP (as opposed to a
DOMCTL) for consistency with its HVMOP_altp2m_set_mem_access counterpart (and
hence with the original altp2m design, where domains are allowed - with the
proper altp2m access rights - to alter these settings), in the absence of an
official position on the issue from the original altp2m designers.

Signed-off-by: Razvan Cojocaru 
Signed-off-by: Petre Pircalabu 
Acked-by: Wei Liu 

---

Changed since v2:
* Added support for compat arguments translation

Changed since v3:
* Replaced  __copy_to_guest with __copy_field_to_guest
* Removed the un-needed parentheses.
* Fixed xlat.lst ordering
* Added comment to patch description explaining why the
functionality was added as an HVMOP.
* Guard using XEN_GENERATING_COMPAT_HEADERS the hvmmem_type_t definition.
This will prevent suplicate definitions to be generated for the
compat equivalent.
* Added comment describing the manual translation of
xen_hvm_altp2m_op_t generic fields from compat_hvm_altp2m_op_t.

Changed since v4:
* Changed the mask parameter to 0x3F.
* Split long lines.
* Added "improperly named HVMMEM_(*)" to the comment explaining the
XEN_GENERATING_COMPAT_HEADERS guard.
* Removed typedef and XEN_GUEST_HANDLE for 
xen_hvm_altp2m_set_mem_access_multi.
* Copied the "opaque" field to guest in compat_altp2m_op.
* Added build time test to check if the size of
xen_hvm_altp2m_set_mem_access_multi at least equal to the size of
compat_hvm_altp2m_set_mem_access_multi.

Changed since v5:
* Changed the domid parameter type to uint32_t to match 5b42c82f.
* Added comment to explain why the 0x3F value was chosen.
* Fixed switch indentation in compat_altp2m_op.
* Changed the condition used to check if the opaque field has to
be copied to the guest.
* Added CHECK_hvm_altp2m_op and CHECK_hvm_altp2m_set_mem_access_multi.

Changed since v6:
* Removed trailing semicolon from the definitions of CHECK_hvm_altp2m_op
and CHECK_hvm_altp2m_set_mem_access_multi.
* Removed BUILD_BUG_ON check.
* Added comment describing the reason for manually defining the CHECK_
macros.
* Added ASSERT_UNREACHABLE as the default switch label action in
compat_altp2m_op.
* Added ASSERT(rc == __HYPERVISOR_hvm_op) to make sure the return
code was actually sey by hypercall_create_continuation.

Changed since v7:
* Changed the patch title.

Changed since v8:
* Use sizeof *var for portability
* Added "must be set to 0" to opaque's comment
* Reordered alphabetically the compat headers
* Added blanks to switch statements at the end of each "case" block
* Do not return -EINVAL when nr is 0

Changed since v9:
* Return -EINVAL only if "opaque" is greater than "nr" when handling
HVMOP_altp2m_set_mem_access_multi.

Changed since v10:
* Change xc_set_mem_access_multi's pages parameter name to gfns
* Reword mask comment according to George's comments.
* Put xc_altp2m_set_mem_access_multi declaration directly after
xc_altp2m_set_mem_access in the header file.
* Removed tabs from xc_altp2m_set_mem_access_multi.
---
 tools/libxc/include/xenctrl.h   |   3 +
 tools/libxc/xc_altp2m.c |  41 
 xen/arch/x86/hvm/hvm.c  | 143 +++-
 xen/include/Makefile|   3 +-
 xen/include/public/hvm/hvm_op.h |  39 +--
 xen/include/xlat.lst|   1 +
 6 files changed, 223 insertions(+), 7 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 058e832..408fa1c 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1961,6 +1961,9 @@ int xc_altp2m_switch_to_view(xc_interface *handle, 
uint32_t domid,
 int xc_altp2m_set_mem_access(xc_interface *handle, uint32_t domid,
  uint16_t view_id, xen_pfn_t gfn,
  xenmem_access_t access);
+int xc_altp2m_set_mem_access_multi(xc_interface *handle, uint32_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *gfns, uint32_t nr);
 int xc_altp2m_change_gfn(xc_interface *handle, uint32_t domid,
  uint16_t view_id, xen_pfn_t old_gfn,
  xen_pfn_t new_gfn);
diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c
index 07fcd18..ce4a1e4 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -213,

[Xen-devel] [PATCH 1/4] x86_emulator: Add PHONY uninstall target

2018-09-13 Thread Petre Pircalabu
The missing uninstall target breaks the top 'tools' uninstall target.

Signed-off-by: Petre Pircalabu 
---
 tools/tests/x86_emulator/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/tests/x86_emulator/Makefile 
b/tools/tests/x86_emulator/Makefile
index e8a3e90..8696a65 100644
--- a/tools/tests/x86_emulator/Makefile
+++ b/tools/tests/x86_emulator/Makefile
@@ -126,6 +126,9 @@ distclean: clean
 .PHONY: install uninstall
 install uninstall:
 
+.PHONY: uninstall
+uninstall:
+
 x86_emulate:
[ -L $@ ] || ln -sf $(XEN_ROOT)/xen/arch/x86/$@
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH 3/4] x86: Add map_domain_pages_global

2018-09-13 Thread Petre Pircalabu
Create a single mapping for multiple domain pages.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/xc_vm_event.c |  2 +-
 xen/arch/x86/domain_page.c| 22 ++
 xen/include/xen/domain_page.h |  9 +
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index dd34cec..de37ca5 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -74,7 +74,7 @@ static int xc_vm_event_domctl(int type, unsigned int *param)
 {
 case XEN_VM_EVENT_TYPE_PAGING:
 *param = XEN_DOMCTL_VM_EVENT_OP_PAGING;
-   break;
+break;
 
 case XEN_VM_EVENT_TYPE_MONITOR:
 *param = XEN_DOMCTL_VM_EVENT_OP_MONITOR;
diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
index 4a07cfb..0d23e52 100644
--- a/xen/arch/x86/domain_page.c
+++ b/xen/arch/x86/domain_page.c
@@ -317,6 +317,28 @@ void *map_domain_page_global(mfn_t mfn)
 return vmap(&mfn, 1);
 }
 
+void *map_domain_pages_global(const mfn_t *mfn, unsigned int nr)
+{
+ASSERT(!in_irq() &&
+   ((system_state >= SYS_STATE_boot &&
+ system_state < SYS_STATE_active) ||
+local_irq_is_enabled()));
+
+return vmap(mfn, nr);
+}
+
+void *__map_domain_pages_global(const struct page_info *pg, unsigned int nr)
+{
+mfn_t mfn[nr];
+int i;
+struct page_info *cur_pg = (struct page_info *)&pg[0];
+
+for (i = 0; i < nr; i++)
+mfn[i] = page_to_mfn(cur_pg++);
+
+return map_domain_pages_global(mfn, nr);
+}
+
 void unmap_domain_page_global(const void *ptr)
 {
 unsigned long va = (unsigned long)ptr;
diff --git a/xen/include/xen/domain_page.h b/xen/include/xen/domain_page.h
index 32669a3..76422f9 100644
--- a/xen/include/xen/domain_page.h
+++ b/xen/include/xen/domain_page.h
@@ -42,6 +42,7 @@ mfn_t domain_page_map_to_mfn(const void *va);
  * mappings can also be unmapped from any context.
  */
 void *map_domain_page_global(mfn_t mfn);
+void *map_domain_pages_global(const mfn_t *mfn, unsigned int nr);
 void unmap_domain_page_global(const void *va);
 
 #define __map_domain_page(pg)map_domain_page(page_to_mfn(pg))
@@ -51,6 +52,8 @@ static inline void *__map_domain_page_global(const struct 
page_info *pg)
 return map_domain_page_global(page_to_mfn(pg));
 }
 
+void *__map_domain_pages_global(const struct page_info *pg, unsigned int nr);
+
 #else /* !CONFIG_DOMAIN_PAGE */
 
 #define map_domain_page(mfn)__mfn_to_virt(mfn_x(mfn))
@@ -68,6 +71,12 @@ static inline void *__map_domain_page_global(const struct 
page_info *pg)
 return page_to_virt(pg);
 }
 
+static inline void *__map_domain_pages_global(const struct page_info *pg,
+  unsigned int nr)
+{
+return __map_domain_page_global(pg);
+}
+
 static inline void unmap_domain_page_global(const void *va) {};
 
 #endif /* !CONFIG_DOMAIN_PAGE */
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH 4/4] vm_event: Add support for multi-page ring buffer

2018-09-13 Thread Petre Pircalabu
In high throughput introspection scenarios where lots of monitor
vm_events are generated, the ring buffer can fill up before the monitor
application gets a chance to handle all the requests thus blocking
other vcpus which will have to wait for a slot to become available.

This patch adds support for extending the ring buffer by allocating a
number of pages from domheap and mapping them to the monitor
application's domain using the foreignmemory_map_resource interface.
Unlike the current implementation, the ring buffer pages are not part of
the introspected DomU, so they will not be reclaimed when the monitor is
disabled.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h   |   2 +
 tools/libxc/xc_monitor.c|   7 +
 tools/libxc/xc_private.h|   3 +
 tools/libxc/xc_vm_event.c   |  49 +++
 tools/tests/xen-access/xen-access.c |  33 +++--
 xen/arch/x86/domain_page.c  |   3 +-
 xen/arch/x86/mm.c   |  14 ++
 xen/common/vm_event.c   | 258 +++-
 xen/include/public/domctl.h |   1 +
 xen/include/public/memory.h |   1 +
 xen/include/xen/sched.h |   5 +-
 xen/include/xen/vm_event.h  |   4 +
 12 files changed, 305 insertions(+), 75 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index bb75bcc..4f91ee9 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2005,6 +2005,8 @@ int xc_get_mem_access(xc_interface *xch, uint32_t 
domain_id,
  * Caller has to unmap this page when done.
  */
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port);
+void *xc_monitor_enable_ex(xc_interface *xch, uint32_t domain_id,
+   int order, uint32_t *port);
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id);
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id);
 /*
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 15e6a0e..5188835 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -28,6 +28,13 @@ void *xc_monitor_enable(xc_interface *xch, uint32_t 
domain_id, uint32_t *port)
   port);
 }
 
+void *xc_monitor_enable_ex(xc_interface *xch, uint32_t domain_id, int order,
+   uint32_t *port)
+{
+return xc_vm_event_enable_ex(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR,
+ order, port);
+}
+
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index be22986..03d9460 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -436,6 +436,9 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
+void *xc_vm_event_enable_ex(xc_interface *xch, uint32_t domain_id, int type,
+int order, uint32_t *port);
+
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
 
 #endif /* __XC_PRIVATE_H__ */
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index de37ca5..216bbe2 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -21,6 +21,7 @@
  */
 
 #include "xc_private.h"
+#include "xenforeignmemory.h"
 
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
 unsigned int mode, uint32_t *port)
@@ -184,6 +185,54 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t 
domain_id, int type,
 return ring_page;
 }
 
+void *xc_vm_event_enable_ex(xc_interface *xch, uint32_t domain_id, int type,
+int order, uint32_t *port)
+{
+xenforeignmemory_resource_handle *fres = NULL;
+int saved_errno;
+void *ring_buffer = NULL;
+
+if ( !port )
+{
+errno = EINVAL;
+return NULL;
+}
+
+/* Pause the domain for ring page setup */
+if ( xc_domain_pause(xch, domain_id) )
+{
+PERROR("Unable to pause domain\n");
+return NULL;
+}
+
+fres = xenforeignmemory_map_resource(xch->fmem, domain_id,
+ XENMEM_resource_vm_event, type, 0,
+ order, &ring_buffer,
+ PROT_READ | PROT_WRITE, 0);
+if ( !fres )
+{
+PERROR("Unable to map vm_event ring pages resource\n");
+goto out;
+}
+
+if ( xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_GET_PORT, type, 
port) )
+PERROR("Unable to get vm_event channel port\n");
+
+out:
+saved_errno = errno;
+if ( xc_domain_unpause(xch, domain_id) != 0 )
+{
+if (fres)
+

[Xen-devel] [PATCH 0/4] Add support for multi-page vm_event ring buffer

2018-09-13 Thread Petre Pircalabu
This series enables the vm_event ring to use buffers larger than 4K.


Petre Pircalabu (4):
  x86_emulator: Add PHONY uninstall target
  tools/libxc: Define VM_EVENT type
  x86: Add map_domain_pages_global
  vm_event: Add support for multi-page ring buffer

 tools/libxc/include/xenctrl.h   |   2 +
 tools/libxc/xc_monitor.c|   9 +-
 tools/libxc/xc_private.h|   9 +-
 tools/libxc/xc_vm_event.c   | 139 ++-
 tools/tests/x86_emulator/Makefile   |   3 +
 tools/tests/xen-access/xen-access.c |  33 +++--
 xen/arch/x86/domain_page.c  |  21 +++
 xen/arch/x86/mm.c   |  14 ++
 xen/common/vm_event.c   | 258 +++-
 xen/include/public/domctl.h |  22 ++-
 xen/include/public/memory.h |   1 +
 xen/include/xen/domain_page.h   |   9 ++
 xen/include/xen/sched.h |   5 +-
 xen/include/xen/vm_event.h  |   4 +
 14 files changed, 414 insertions(+), 115 deletions(-)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH 2/4] tools/libxc: Define VM_EVENT type

2018-09-13 Thread Petre Pircalabu
Define the type for each of the supported vm_event rings (paging,
monitor and sharing) and replace the ring param field with this type.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/xc_monitor.c|  2 +-
 tools/libxc/xc_private.h|  6 +--
 tools/libxc/xc_vm_event.c   | 90 +
 xen/include/public/domctl.h | 21 +++
 4 files changed, 77 insertions(+), 42 deletions(-)

diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 4ac823e..15e6a0e 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -24,7 +24,7 @@
 
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port)
 {
-return xc_vm_event_enable(xch, domain_id, HVM_PARAM_MONITOR_RING_PFN,
+return xc_vm_event_enable(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR,
   port);
 }
 
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 705eaa9..be22986 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -430,10 +430,10 @@ int xc_ffs64(uint64_t x);
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
 unsigned int mode, uint32_t *port);
 /*
- * Enables vm_event and returns the mapped ring page indicated by param.
- * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN
+ * Enables vm_event and returns the mapped ring page indicated by type.
+ * type can be XEN_VM_EVENT_TYPE_(PAGING/MONITOR/SHARING)
  */
-void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param,
+void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port);
 
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c
index 8674607..dd34cec 100644
--- a/tools/libxc/xc_vm_event.c
+++ b/tools/libxc/xc_vm_event.c
@@ -39,16 +39,71 @@ int xc_vm_event_control(xc_interface *xch, uint32_t 
domain_id, unsigned int op,
 return rc;
 }
 
-void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param,
+static int xc_vm_event_ring_pfn_param(int type, int *param)
+{
+if ( !param )
+return -EINVAL;
+
+switch ( type )
+{
+case XEN_VM_EVENT_TYPE_PAGING:
+*param = HVM_PARAM_PAGING_RING_PFN;
+break;
+
+case XEN_VM_EVENT_TYPE_MONITOR:
+*param = HVM_PARAM_MONITOR_RING_PFN;
+break;
+
+case XEN_VM_EVENT_TYPE_SHARING:
+*param = HVM_PARAM_SHARING_RING_PFN;
+break;
+
+default:
+return -EINVAL;
+}
+
+return 0;
+}
+
+static int xc_vm_event_domctl(int type, unsigned int *param)
+{
+if ( !param )
+return -EINVAL;
+
+switch ( type )
+{
+case XEN_VM_EVENT_TYPE_PAGING:
+*param = XEN_DOMCTL_VM_EVENT_OP_PAGING;
+   break;
+
+case XEN_VM_EVENT_TYPE_MONITOR:
+*param = XEN_DOMCTL_VM_EVENT_OP_MONITOR;
+break;
+
+case XEN_VM_EVENT_TYPE_SHARING:
+*param = XEN_DOMCTL_VM_EVENT_OP_SHARING;
+break;
+
+default:
+return -EINVAL;
+}
+
+return 0;
+}
+
+void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type,
  uint32_t *port)
 {
 void *ring_page = NULL;
 uint64_t pfn;
 xen_pfn_t ring_pfn, mmap_pfn;
-unsigned int op, mode;
+unsigned int mode;
 int rc1, rc2, saved_errno;
+int param;
 
-if ( !port )
+if ( !port ||
+ xc_vm_event_ring_pfn_param(type, ¶m) != 0 ||
+ xc_vm_event_domctl(type, &mode) )
 {
 errno = EINVAL;
 return NULL;
@@ -94,34 +149,7 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t 
domain_id, int param,
 goto out;
 }
 
-switch ( param )
-{
-case HVM_PARAM_PAGING_RING_PFN:
-op = XEN_VM_EVENT_ENABLE;
-mode = XEN_DOMCTL_VM_EVENT_OP_PAGING;
-break;
-
-case HVM_PARAM_MONITOR_RING_PFN:
-op = XEN_VM_EVENT_ENABLE;
-mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR;
-break;
-
-case HVM_PARAM_SHARING_RING_PFN:
-op = XEN_VM_EVENT_ENABLE;
-mode = XEN_DOMCTL_VM_EVENT_OP_SHARING;
-break;
-
-/*
- * This is for the outside chance that the HVM_PARAM is valid but is 
invalid
- * as far as vm_event goes.
- */
-default:
-errno = EINVAL;
-rc1 = -1;
-goto out;
-}
-
-rc1 = xc_vm_event_control(xch, domain_id, op, mode, port);
+rc1 = xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_ENABLE, mode, port);
 if ( rc1 != 0 )
 {
 PERROR("Failed to enable vm_event\n");
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 82b6967..ac4ced2 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -757,10 +757,17 @@ struct xen_domctl_gdbsx_domstatus {
 
 /*
  * There are currently three rings available for VM events:
- * sharing, monitor an

Re: [Xen-devel] [PATCH 4/4] vm_event: Add support for multi-page ring buffer

2018-09-14 Thread Petre Pircalabu
On Jo, 2018-09-13 at 10:42 -0600, Tamas K Lengyel wrote:
> On Thu, Sep 13, 2018 at 9:02 AM Petre Pircalabu
>  wrote:
> > 
> > 
> > In high throughput introspection scenarios where lots of monitor
> > vm_events are generated, the ring buffer can fill up before the
> > monitor
> > application gets a chance to handle all the requests thus blocking
> > other vcpus which will have to wait for a slot to become available.
> > 
> > This patch adds support for extending the ring buffer by allocating
> > a
> > number of pages from domheap and mapping them to the monitor
> > application's domain using the foreignmemory_map_resource
> > interface.
> > Unlike the current implementation, the ring buffer pages are not
> > part of
> > the introspected DomU, so they will not be reclaimed when the
> > monitor is
> > disabled.
> > 
> > Signed-off-by: Petre Pircalabu 
> Thanks for this addition, it has been on the TODO for a long while
> now. Could you also please push the patches as a git branch
> somewhere?
I've pushed it to my github repository (branch :
multi_page_ring_buffer/devel_new)
https://github.com/petrepircalabu/xen/tree/multi_page_ring_buffer/devel
_new
> 
> > 
> > ---
> >  tools/libxc/include/xenctrl.h   |   2 +
> >  tools/libxc/xc_monitor.c|   7 +
> >  tools/libxc/xc_private.h|   3 +
> >  tools/libxc/xc_vm_event.c   |  49 +++
> > 
> > +xenaccess->vm_event.domain_id,
> > +xenaccess->vm_event.ring_page_count,
> > +&xenaccess->vm_event.evtchn_port);
> > +
> > +if (xenaccess->vm_event.ring_buffer == NULL && errno ==
> > EOPNOTSUPP)
> How would this situation ever arise? If there is a chance that you
> can't setup multi-page rings, perhaps adding a hypercall that would
> tell the user how many pages are max available for the ring is the
> better route. This just seems like guessing right now.
> 
The multi page ring buffer is mapped using
xenforeignmemory_map_resource which uses IOCTL_PRIVCMD_MMAP_RESOURCE.
This ioctl was added in kernel 4.18.1, which is a relatively new
kernel. If the monitor domain doesnt't recognize this hypercall it sets
errno to EOPNOTSUPP.
> > 
> > +{
> > +xenaccess->vm_event.ring_page_count = 1;
> > +xenaccess->vm_event.ring_buffer =
> >  xc_monitor_enable(xenaccess->xc_handle,
> >    xenaccess->vm_event.domain_id,
> >    &xenaccess->vm_event.evtchn_port);

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH 2/4] tools/libxc: Define VM_EVENT type

2018-09-14 Thread Petre Pircalabu
On Vi, 2018-09-14 at 03:14 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > On 13.09.18 at 17:01,  wrote:
> > --- a/xen/include/public/domctl.h
> > +++ b/xen/include/public/domctl.h
> > @@ -757,10 +757,17 @@ struct xen_domctl_gdbsx_domstatus {
> >  
> >  /*
> >   * There are currently three rings available for VM events:
> > - * sharing, monitor and paging. This hypercall allows one to
> > - * control these rings (enable/disable), as well as to signal
> > - * to the hypervisor to pull responses (resume) from the given
> > - * ring.
> > + * sharing, monitor and paging
> > + */
> > +
> > +#define XEN_VM_EVENT_TYPE_PAGING 1
> > +#define XEN_VM_EVENT_TYPE_MONITOR 2
> > +#define XEN_VM_EVENT_TYPE_SHARING 3
> > +
> > +/*
> > + * This hypercall allows one to control the vm_event rings
> > (enable/disable),
> > + * as well as to signal to the hypervisor to pull responses
> > (resume) from
> > + * the given ring.
> >   */
> What's the reason to modify the comment, the more with a style
> violation (malformed single line comment) as the result?
> 
I have split the comment in 2 parts. The first ("There are ... sharing,
monitor and paging ") describes the 3 XEN_VM_EVENT_TYPE_* rings, and
the second describes the vm_event hypercalls ( XEN_VM_EVENT_ENABLE 
). Other than the missing period at the end of "paging" (which I will
fix in the next iteration) I cannot identify other coding style
violations.

> > 
> > @@ -780,7 +787,7 @@ struct xen_domctl_gdbsx_domstatus {
> >   * EXDEV  - guest has PoD enabled
> >   * EBUSY  - guest has or had paging enabled, ring buffer still
> > active
> >   */
> > -#define XEN_DOMCTL_VM_EVENT_OP_PAGING1
> > +#define XEN_DOMCTL_VM_EVENT_OP_PAGING XEN_VM_EVENT_TYPE_PAGING
> >  
> >  /*
> >   * Monitor helper.
> > @@ -804,7 +811,7 @@ struct xen_domctl_gdbsx_domstatus {
> >   * EBUSY  - guest has or had access enabled, ring buffer still
> > active
> >   *
> >   */
> > -#define XEN_DOMCTL_VM_EVENT_OP_MONITOR   2
> > +#define XEN_DOMCTL_VM_EVENT_OP_MONITOR XEN_VM_EVENT_TYPE_MONITOR
> >  
> >  /*
> >   * Sharing ENOMEM helper.
> > @@ -819,7 +826,7 @@ struct xen_domctl_gdbsx_domstatus {
> >   * Note that shring can be turned on (as per the domctl below)
> >   * *without* this ring being setup.
> >   */
> > -#define XEN_DOMCTL_VM_EVENT_OP_SHARING   3
> > +#define XEN_DOMCTL_VM_EVENT_OP_SHARING XEN_VM_EVENT_TYPE_SHARING
> And what's the reason to retain these (now redundant)
> XEN_DOMCTL_VM_EVENT_OP_* definitions? Either they're independent
> (in which case they shouldn't resolve to XEN_VM_EVENT_TYPE_*) or
> they're true aliases (tolerating arbitrary future changes to
> XEN_VM_EVENT_TYPE_* without further adjustment here), and then
> unnecessary to retain.
> 
> Jan
> 
> 
I kept them despite the redundancy because the domctl.h header is
public and I didn't wanted to break any existent (external) clients of
this interface. 
However, if you think removing them altogether it's best, I will
replace them with the XEN_VM_EVENT_TYPE_* and increment
XEN_DOMCTL_INTERFACE_VERSION.

//Petre

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH 1/4] x86_emulator: Add PHONY uninstall target

2018-09-14 Thread Petre Pircalabu
On Vi, 2018-09-14 at 03:09 -0600, Jan Beulich wrote:
> > 
> > > 
> > > > 
> > > > On 13.09.18 at 17:01,  wrote:
> > The missing uninstall target breaks the top 'tools' uninstall
> > target.
> Missing?
> 
> > 
> > --- a/tools/tests/x86_emulator/Makefile
> > +++ b/tools/tests/x86_emulator/Makefile
> > @@ -126,6 +126,9 @@ distclean: clean
> >  .PHONY: install uninstall
> >  install uninstall:
> >  
> > +.PHONY: uninstall
> > +uninstall:
> Please look at the patch context above your change. It was added
> a couple of weeks ago (09613d3b5f), and you really should have
> noticed this the latest when re-basing on top of that change.
> 
> Jan
> 
Thank-you very much for pointing it out. I have missed it completely.
I will completely remove this patch in the next patchset iteration.

//Petre

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH 4/4] vm_event: Add support for multi-page ring buffer

2018-09-24 Thread Petre Pircalabu
On Mon, 2018-09-17 at 15:41 +0100, Andrew Cooper wrote:
> On 13/09/18 16:02, Petre Pircalabu wrote:
> > In high throughput introspection scenarios where lots of monitor
> > vm_events are generated, the ring buffer can fill up before the
> > monitor
> > application gets a chance to handle all the requests thus blocking
> > other vcpus which will have to wait for a slot to become available.
> > 
> > This patch adds support for extending the ring buffer by allocating
> > a
> > number of pages from domheap and mapping them to the monitor
> > application's domain using the foreignmemory_map_resource
> > interface.
> > Unlike the current implementation, the ring buffer pages are not
> > part of
> > the introspected DomU, so they will not be reclaimed when the
> > monitor is
> > disabled.
> > 
> > Signed-off-by: Petre Pircalabu 
> 
> What about the slotted format for the synchronous events?  While this
> is
> fine for the async bits, I don't think we want to end up changing the
> mapping API twice.
> 
> Simply increasing the size of the ring puts more pressure on the
I'm currently investigating this approach and I will send an
inplementation proposal with the next version of the patch.
> 
> > diff --git a/xen/arch/x86/domain_page.c
> > b/xen/arch/x86/domain_page.c
> > index 0d23e52..2a9cbf3 100644
> > --- a/xen/arch/x86/domain_page.c
> > +++ b/xen/arch/x86/domain_page.c
> > @@ -331,10 +331,9 @@ void *__map_domain_pages_global(const struct
> > page_info *pg, unsigned int nr)
> >  {
> >  mfn_t mfn[nr];
> >  int i;
> > -struct page_info *cur_pg = (struct page_info *)&pg[0];
> >  
> >  for (i = 0; i < nr; i++)
> > -mfn[i] = page_to_mfn(cur_pg++);
> > +mfn[i] = page_to_mfn(pg++);
> 
> This hunk looks like it should be in the previous patch?  That
> said...
Yep. I've completely missed it. This piece of code will be removed
along  with the map_domain_pages_global patch.
> 
> >  
> >  return map_domain_pages_global(mfn, nr);
> >  }
> > diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
> > index 4793aac..faece3c 100644
> > --- a/xen/common/vm_event.c
> > +++ b/xen/common/vm_event.c
> > @@ -39,16 +39,66 @@
> >  #define vm_event_ring_lock(_ved)   spin_lock(&(_ved)-
> > >ring_lock)
> >  #define vm_event_ring_unlock(_ved) spin_unlock(&(_ved)-
> > >ring_lock)
> >  
> > +#define XEN_VM_EVENT_ALLOC_FROM_DOMHEAP 0x
> > +
> > +static int vm_event_alloc_ring(struct domain *d, struct
> > vm_event_domain *ved)
> > +{
> > +struct page_info *page;
> > +void *va = NULL;
> > +int i, rc = -ENOMEM;
> > +
> > +page = alloc_domheap_pages(d, ved->ring_order,
> > MEMF_no_refcount);
> > +if ( !page )
> > +return -ENOMEM;
> 
> ... what is wrong with vzalloc()?
> 
> You don't want to be making a ring_order allocation, especially as
> the
> order grows.  All you need are some mappings which are virtually
> contiguous, not physically contiguous.
Unfortunately, vzalloc doesn't work here (the acquire_resource
succeeds, but the subsequent mapping fails:
(XEN) mm.c:1024:d0v5 pg_owner d0 l1e_owner d0, but real_pg_owner d-1
(XEN) mm.c:1100:d0v5 Error getting mfn dd24d (pfn )
from L1 entry 8000dd24d227 for l1e_owner d0, pg_owner d0
(XEN) mm.c:1024:d0v5 pg_owner d0 l1e_owner d0, but real_pg_owner d-1
(XEN) mm.c:1100:d0v5 Error getting mfn dd24c (pfn )
from L1 entry 8000dd24c227 for l1e_owner d0, pg_owner d0

However, allocating each page with alloc_domheap_page and then mapping
them using vmap does the trick.
Until the next version is ready (slotted format for synchronous events)
 I have pushed an intermediate version which addresses the issues
signaled by you an Jan to my github fork of the xen repository:
https://github.com/petrepircalabu/xen/tree/multi_page_ring_buffer/devel
_new

> ~Andrew

Many thanks for your support,
Petre

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH 4/4] vm_event: Add support for multi-page ring buffer

2018-09-24 Thread Petre Pircalabu
On Tue, 2018-09-18 at 06:58 -0600, Jan Beulich wrote:
> > > > On 13.09.18 at 17:02,  wrote:
> > 
> > --- a/xen/arch/x86/domain_page.c
> > +++ b/xen/arch/x86/domain_page.c
> > @@ -331,10 +331,9 @@ void *__map_domain_pages_global(const struct
> > page_info *pg, unsigned int nr)
> >  {
> >  mfn_t mfn[nr];
> >  int i;
> > -struct page_info *cur_pg = (struct page_info *)&pg[0];
> >  
> >  for (i = 0; i < nr; i++)
> > -mfn[i] = page_to_mfn(cur_pg++);
> > +mfn[i] = page_to_mfn(pg++);
> >  
> >  return map_domain_pages_global(mfn, nr);
> >  }
> 
> Please could you avoid having such random unrelated changes in your
> patches?
> 
Thank-uy very much for noticing it, I've completely missed it. However
I drop the map_domain_pages functionality altoghether as Andrew pointed
out is not necessary to have a physically contiguous area.

> > @@ -4415,6 +4416,19 @@ int arch_acquire_resource(struct domain *d,
> > unsigned int type,
> >  }
> >  #endif
> >  
> > +case XENMEM_resource_vm_event:
> > +{
> > +rc = vm_event_get_ring_frames(d, id, frame, nr_frames,
> > mfn_list);
> > +if ( rc )
> > +break;
> > +/*
> > + * The frames will have been assigned to the domain that
> > created
> > + * the ioreq server.
> > + */
> > +*flags |= XENMEM_rsrc_acq_caller_owned;
> > +break;
> > +}
> 
> Isn't it wrong to assume that the monitor application will run in the
> same
> domain as the / one ioreq server?

I will remove the ioreq server comment as it's misleading. This call is
not using a ioreq server, but only allocates the memory for the
vm_event's ring buffer.

> > --- a/xen/common/vm_event.c
> > +++ b/xen/common/vm_event.c
> > @@ -39,16 +39,66 @@
> >  #define vm_event_ring_lock(_ved)   spin_lock(&(_ved)-
> > >ring_lock)
> >  #define vm_event_ring_unlock(_ved) spin_unlock(&(_ved)-
> > >ring_lock)
> >  
> > +#define XEN_VM_EVENT_ALLOC_FROM_DOMHEAP 0x
> 
> Note this constant's type vs ...
> 
> >  static int vm_event_enable(
> >  struct domain *d,
> > -struct xen_domctl_vm_event_op *vec,
> >  struct vm_event_domain **ved,
> > +unsigned long param,
> 
> ... the function parameter type here. I don't see why this can't be
> "unsigned int".
Fixed.
> 
> > @@ -88,12 +151,12 @@ static int vm_event_enable(
> >  if ( rc < 0 )
> >  goto err;
> >  
> > -(*ved)->xen_port = vec->port = rc;
> > +(*ved)->xen_port =  rc;
> 
> Yet another unrelated change? It looks to be replaced by code further
> down (in the callers), but it's not clear to me why the change is
> needed
> (here). Perhaps worth splitting up the patch a little?
vm_event_enabled can be called from both vm_event_domctl and
vm_event_get_ring_frames (acquire_resource call path). I have removed
the vec parameter (struct xen_domctl_vm_event_op) to make the function
caller agnostic.

Many thank for your comments,
Petre
> 
> Jan
> 
> 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH] MAINTAINERS: Add myself as reviewer for vm_event

2019-06-20 Thread Petre Pircalabu
Signed-off-by: Petre Pircalabu 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ab32e7f..0151625 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -412,6 +412,7 @@ F:  unmodified_drivers/linux-2.6/
 
 VM EVENT, MEM ACCESS and MONITOR
 M: Razvan Cojocaru 
+R: Petre Pircalabu 
 M: Tamas K Lengyel 
 S: Supported
 F: tools/tests/xen-access
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2] MAINTAINERS: Add myself as reviewer for vm_event

2019-06-20 Thread Petre Pircalabu
Signed-off-by: Petre Pircalabu 
---
Changes in v2:
- Added designated reviewer after maintainer list
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ab32e7f..0658bcc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -413,6 +413,7 @@ F:  unmodified_drivers/linux-2.6/
 VM EVENT, MEM ACCESS and MONITOR
 M: Razvan Cojocaru 
 M: Tamas K Lengyel 
+R: Petre Pircalabu 
 S: Supported
 F: tools/tests/xen-access
 F: xen/arch/*/monitor.c
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 01/10] vm_event: Define VM_EVENT type

2019-07-16 Thread Petre Pircalabu
Define the type for each of the supported vm_event rings (paging,
monitor and sharing) and replace the ring param field with this type.

Replace XEN_DOMCTL_VM_EVENT_OP_ occurrences with their corresponding
XEN_VM_EVENT_TYPE_ counterpart.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |  1 +
 tools/libxc/xc_mem_paging.c   |  6 ++--
 tools/libxc/xc_memshr.c   |  6 ++--
 tools/libxc/xc_monitor.c  |  6 ++--
 tools/libxc/xc_private.h  |  8 ++---
 tools/libxc/xc_vm_event.c | 58 +++---
 xen/common/vm_event.c | 12 
 xen/include/public/domctl.h   | 72 +++
 xen/include/public/vm_event.h | 31 +++
 9 files changed, 81 insertions(+), 119 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 538007a..f3af710 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "xentoollog.h"
 
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index a067706..a88c0cc 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -48,7 +48,7 @@ int xc_mem_paging_enable(xc_interface *xch, uint32_t 
domain_id,
 
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_ENABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING,
+   XEN_VM_EVENT_TYPE_PAGING,
port);
 }
 
@@ -56,7 +56,7 @@ int xc_mem_paging_disable(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING,
+   XEN_VM_EVENT_TYPE_PAGING,
NULL);
 }
 
@@ -64,7 +64,7 @@ int xc_mem_paging_resume(xc_interface *xch, uint32_t 
domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_PAGING,
+   XEN_VM_EVENT_TYPE_PAGING,
NULL);
 }
 
diff --git a/tools/libxc/xc_memshr.c b/tools/libxc/xc_memshr.c
index d5e135e..1c4a706 100644
--- a/tools/libxc/xc_memshr.c
+++ b/tools/libxc/xc_memshr.c
@@ -53,7 +53,7 @@ int xc_memshr_ring_enable(xc_interface *xch,
 
 return xc_vm_event_control(xch, domid,
XEN_VM_EVENT_ENABLE,
-   XEN_DOMCTL_VM_EVENT_OP_SHARING,
+   XEN_VM_EVENT_TYPE_SHARING,
port);
 }
 
@@ -62,7 +62,7 @@ int xc_memshr_ring_disable(xc_interface *xch,
 {
 return xc_vm_event_control(xch, domid,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_SHARING,
+   XEN_VM_EVENT_TYPE_SHARING,
NULL);
 }
 
@@ -205,7 +205,7 @@ int xc_memshr_domain_resume(xc_interface *xch,
 {
 return xc_vm_event_control(xch, domid,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_SHARING,
+   XEN_VM_EVENT_TYPE_SHARING,
NULL);
 }
 
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 4ac823e..f05b53d 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -24,7 +24,7 @@
 
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port)
 {
-return xc_vm_event_enable(xch, domain_id, HVM_PARAM_MONITOR_RING_PFN,
+return xc_vm_event_enable(xch, domain_id, XEN_VM_EVENT_TYPE_MONITOR,
   port);
 }
 
@@ -32,7 +32,7 @@ int xc_monitor_disable(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR,
+   XEN_VM_EVENT_TYPE_MONITOR,
NULL);
 }
 
@@ -40,7 +40,7 @@ int xc_monitor_resume(xc_interface *xch, uint32_t domain_id)
 {
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_RESUME,
-   XEN_DOMCTL_VM_EVENT_OP_MONITOR,
+   XEN_VM_EVENT_TYPE_MONITOR,
NULL);
 }
 
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index adc3b6a..e4f7c3a 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -412,12 +412,12 @@ int xc_ffs64(uint64_t x);
  * vm_event operations. Internal use only.
  */
 int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op,
-unsigned int mode, uint

[Xen-devel] [PATCH v2 08/10] xen-access: Use getopt_long for cmdline parsing

2019-07-16 Thread Petre Pircalabu
This simplifies the command line parsing logic and makes it easier to
add new test parameters.

Signed-off-by: Petre Pircalabu 
---
 tools/tests/xen-access/xen-access.c | 60 +
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/tools/tests/xen-access/xen-access.c 
b/tools/tests/xen-access/xen-access.c
index 6aaee16..8a3eea5 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -397,93 +398,102 @@ int main(int argc, char *argv[])
 uint16_t altp2m_view_id = 0;
 
 char* progname = argv[0];
-argv++;
-argc--;
+char* command;
+int c;
+int option_index;
+struct option long_options[] =
+{
+{ "mem-access-listener", no_argument, 0, 'm' },
+};
 
-if ( argc == 3 && argv[0][0] == '-' )
+while ( 1 )
 {
-if ( !strcmp(argv[0], "-m") )
-required = 1;
-else
+c = getopt_long(argc, argv, "m", long_options, &option_index);
+if ( c == -1 )
+break;
+
+switch ( c )
 {
+case 'm':
+required = 1;
+break;
+
+default:
 usage(progname);
 return -1;
 }
-argv++;
-argc--;
 }
 
-if ( argc != 2 )
+if ( argc - optind != 2 )
 {
 usage(progname);
 return -1;
 }
 
-domain_id = atoi(argv[0]);
-argv++;
-argc--;
+domain_id = atoi(argv[optind++]);
+command = argv[optind];
 
-if ( !strcmp(argv[0], "write") )
+if ( !strcmp(command, "write") )
 {
 default_access = XENMEM_access_rx;
 after_first_access = XENMEM_access_rwx;
 memaccess = 1;
 }
-else if ( !strcmp(argv[0], "exec") )
+else if ( !strcmp(command, "exec") )
 {
 default_access = XENMEM_access_rw;
 after_first_access = XENMEM_access_rwx;
 memaccess = 1;
 }
 #if defined(__i386__) || defined(__x86_64__)
-else if ( !strcmp(argv[0], "breakpoint") )
+else if ( !strcmp(command, "breakpoint") )
 {
 breakpoint = 1;
 }
-else if ( !strcmp(argv[0], "altp2m_write") )
+else if ( !strcmp(command, "altp2m_write") )
 {
 default_access = XENMEM_access_rx;
 altp2m = 1;
 memaccess = 1;
 }
-else if ( !strcmp(argv[0], "altp2m_exec") )
+else if ( !strcmp(command, "altp2m_exec") )
 {
 default_access = XENMEM_access_rw;
 altp2m = 1;
 memaccess = 1;
 }
-else if ( !strcmp(argv[0], "altp2m_write_no_gpt") )
+else if ( !strcmp(command, "altp2m_write_no_gpt") )
 {
 default_access = XENMEM_access_rw;
 altp2m_write_no_gpt = 1;
 memaccess = 1;
 altp2m = 1;
 }
-else if ( !strcmp(argv[0], "debug") )
+else if ( !strcmp(command, "debug") )
 {
 debug = 1;
 }
-else if ( !strcmp(argv[0], "cpuid") )
+else if ( !strcmp(command, "cpuid") )
 {
 cpuid = 1;
 }
-else if ( !strcmp(argv[0], "desc_access") )
+else if ( !strcmp(command, "desc_access") )
 {
 desc_access = 1;
 }
-else if ( !strcmp(argv[0], "write_ctrlreg_cr4") )
+else if ( !strcmp(command, "write_ctrlreg_cr4") )
 {
 write_ctrlreg_cr4 = 1;
 }
 #elif defined(__arm__) || defined(__aarch64__)
-else if ( !strcmp(argv[0], "privcall") )
+else if ( !strcmp(command, "privcall") )
 {
 privcall = 1;
 }
 #endif
 else
 {
-usage(argv[0]);
+usage(command);
 return -1;
 }
 
@@ -494,7 +504,7 @@ int main(int argc, char *argv[])
 return 1;
 }
 
-DPRINTF("starting %s %u\n", argv[0], domain_id);
+DPRINTF("starting %s %u\n", command, domain_id);
 
 /* ensure that if we get a signal, we'll do cleanup, then exit */
 act.sa_handler = close_handler;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 10/10] xen-access: Add support for vm_event_ng interface

2019-07-16 Thread Petre Pircalabu
Split xen-access in order to accommodate both vm_event interfaces
(legacy and NG). By default, the legacy vm_event is selected but
this can be changed by adding the '-n' flag in the command line.

Signed-off-by: Petre Pircalabu 
---
 tools/tests/xen-access/Makefile  |   7 +-
 tools/tests/xen-access/vm-event-ng.c | 183 ++
 tools/tests/xen-access/vm-event.c| 194 +++
 tools/tests/xen-access/xen-access.c  | 348 +++
 tools/tests/xen-access/xen-access.h  |  91 +
 5 files changed, 582 insertions(+), 241 deletions(-)
 create mode 100644 tools/tests/xen-access/vm-event-ng.c
 create mode 100644 tools/tests/xen-access/vm-event.c
 create mode 100644 tools/tests/xen-access/xen-access.h

diff --git a/tools/tests/xen-access/Makefile b/tools/tests/xen-access/Makefile
index 131c9f3..17760d8 100644
--- a/tools/tests/xen-access/Makefile
+++ b/tools/tests/xen-access/Makefile
@@ -7,6 +7,7 @@ CFLAGS += -DXC_WANT_COMPAT_DEVICEMODEL_API
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_libxenguest)
 CFLAGS += $(CFLAGS_libxenevtchn)
+CFLAGS += $(CFLAGS_libxenforeignmemory)
 CFLAGS += $(CFLAGS_xeninclude)
 
 TARGETS-y := xen-access
@@ -25,8 +26,10 @@ clean:
 .PHONY: distclean
 distclean: clean
 
-xen-access: xen-access.o Makefile
-   $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) 
$(LDLIBS_libxenevtchn)
+OBJS = xen-access.o vm-event.o vm-event-ng.o
+
+xen-access: $(OBJS) Makefile
+   $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS_libxenctrl) 
$(LDLIBS_libxenguest) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenforeignmemory)
 
 install uninstall:
 
diff --git a/tools/tests/xen-access/vm-event-ng.c 
b/tools/tests/xen-access/vm-event-ng.c
new file mode 100644
index 000..2c79f61
--- /dev/null
+++ b/tools/tests/xen-access/vm-event-ng.c
@@ -0,0 +1,183 @@
+/*
+ * vm-event-ng.c
+ *
+ * Copyright (c) 2019 Bitdefender S.R.L.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "xen-access.h"
+
+#ifndef PFN_UP
+#define PFN_UP(x) (((x) + XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT)
+#endif /* PFN_UP */
+
+typedef struct vm_event_channels
+{
+vm_event_t vme;
+int num_channels;
+xenforeignmemory_resource_handle *fres;
+struct vm_event_slot *slots;
+int *ports;
+} vm_event_channels_t;
+
+#define to_channels(_vme) container_of((_vme), vm_event_channels_t, vme)
+
+static int vm_event_channels_init(xc_interface *xch, xenevtchn_handle *xce,
+  domid_t domain_id, vm_event_ops_t *ops,
+  vm_event_t **vm_event)
+{
+vm_event_channels_t *impl = NULL;
+int rc, i;
+
+impl = (vm_event_channels_t *)calloc(1, sizeof(vm_event_channels_t));
+if ( impl == NULL )
+return -ENOMEM;
+
+rc = xc_monitor_ng_enable(xch, domain_id, &impl->fres, 
&impl->num_channels, (void**)&impl->slots);
+if ( rc )
+{
+ERROR("Failed to enable monitor");
+return rc;
+}
+
+impl->ports = calloc(impl->num_channels, sizeof(int));
+if ( impl->ports == NULL )
+{
+rc = -ENOMEM;
+goto err;
+}
+
+for ( i = 0; i < impl->num_channels; i++)
+{
+rc = xenevtchn_bind_interdomain(xce, domain_id, impl->slots[i].port);
+if (  rc < 0 )
+{
+ERROR("Failed to bind vm_event_slot port for vcpu %d", i);
+rc = -errno;
+goto err;
+}
+
+impl->ports[i] = rc;
+}
+
+*vm_event = (vm_event_t*) impl;
+return 0;
+
+err:
+while ( --i >= 0 )
+xenevtchn_unbind(xce, impl->ports[i]);
+free(impl->ports);
+xc_monitor_ng_disable(xch, domain_id, &impl->fres);
+free(impl);
+return rc;
+}
+
+static i

[Xen-devel] [PATCH v2 03/10] vm_event: Add 'struct domain' backpointer to vm_event_domain.

2019-07-16 Thread Petre Pircalabu
Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c   | 2 ++
 xen/include/xen/sched.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 515a917..787c61c 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -71,6 +71,8 @@ static int vm_event_enable(
 if ( rc < 0 )
 goto err;
 
+ved->d = d;
+
 rc = prepare_ring_for_helper(d, ring_gfn, &ved->ring_pg_struct,
  &ved->ring_page);
 if ( rc < 0 )
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 97a3ab5..e3093d3 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -279,6 +279,8 @@ struct vcpu
 /* VM event */
 struct vm_event_domain
 {
+/* Domain reference */
+struct domain *d;
 spinlock_t lock;
 /* The ring has 64 entries */
 unsigned char foreign_producers;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 04/10] vm_event: Simplify vm_event interface

2019-07-16 Thread Petre Pircalabu
Remove the domain reference from calls to vm_event interface function
and use the backpointer from vm_event_domain.

Affected functions:
- __vm_event_claim_slot / vm_event_claim_slot / vm_event_claim_slot_nosleep
- vm_event_cancel_slot
- vm_event_put_request

Signed-off-by: Petre Pircalabu 
---
 xen/arch/x86/mm/mem_sharing.c |  5 ++---
 xen/arch/x86/mm/p2m.c | 10 +-
 xen/common/monitor.c  |  4 ++--
 xen/common/vm_event.c | 37 ++---
 xen/include/xen/vm_event.h| 17 +++--
 5 files changed, 34 insertions(+), 39 deletions(-)

diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index f16a3f5..9d80389 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -557,8 +557,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 .u.mem_sharing.p2mt = p2m_ram_shared
 };
 
-if ( (rc = __vm_event_claim_slot(d, 
-d->vm_event_share, allow_sleep)) < 0 )
+if ( (rc = __vm_event_claim_slot(d->vm_event_share, allow_sleep)) < 0 )
 return rc;
 
 if ( v->domain == d )
@@ -567,7 +566,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned 
long gfn,
 vm_event_vcpu_pause(v);
 }
 
-vm_event_put_request(d, d->vm_event_share, &req);
+vm_event_put_request(d->vm_event_share, &req);
 
 return 0;
 }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 4c99548..85de64f 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1652,7 +1652,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
  * correctness of the guest execution at this point.  If this is the only
  * page that happens to be paged-out, we'll be okay..  but it's likely the
  * guest will crash shortly anyways. */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
+int rc = vm_event_claim_slot(d->vm_event_paging);
 if ( rc < 0 )
 return;
 
@@ -1666,7 +1666,7 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned 
long gfn,
 /* Evict will fail now, tag this request for pager */
 req.u.mem_paging.flags |= MEM_PAGING_EVICT_FAIL;
 
-vm_event_put_request(d, d->vm_event_paging, &req);
+vm_event_put_request(d->vm_event_paging, &req);
 }
 
 /**
@@ -1704,7 +1704,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
 /* We're paging. There should be a ring */
-int rc = vm_event_claim_slot(d, d->vm_event_paging);
+int rc = vm_event_claim_slot(d->vm_event_paging);
 
 if ( rc == -EOPNOTSUPP )
 {
@@ -1746,7 +1746,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 {
 /* gfn is already on its way back and vcpu is not paused */
 out_cancel:
-vm_event_cancel_slot(d, d->vm_event_paging);
+vm_event_cancel_slot(d->vm_event_paging);
 return;
 }
 
@@ -1754,7 +1754,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned 
long gfn_l)
 req.u.mem_paging.p2mt = p2mt;
 req.vcpu_id = v->vcpu_id;
 
-vm_event_put_request(d, d->vm_event_paging, &req);
+vm_event_put_request(d->vm_event_paging, &req);
 }
 
 /**
diff --git a/xen/common/monitor.c b/xen/common/monitor.c
index d5c9ff1..b8d33c4 100644
--- a/xen/common/monitor.c
+++ b/xen/common/monitor.c
@@ -93,7 +93,7 @@ int monitor_traps(struct vcpu *v, bool sync, 
vm_event_request_t *req)
 int rc;
 struct domain *d = v->domain;
 
-rc = vm_event_claim_slot(d, d->vm_event_monitor);
+rc = vm_event_claim_slot(d->vm_event_monitor);
 switch ( rc )
 {
 case 0:
@@ -125,7 +125,7 @@ int monitor_traps(struct vcpu *v, bool sync, 
vm_event_request_t *req)
 }
 
 vm_event_fill_regs(req);
-vm_event_put_request(d, d->vm_event_monitor, req);
+vm_event_put_request(d->vm_event_monitor, req);
 
 return rc;
 }
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 787c61c..a235d25 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -119,10 +119,11 @@ static unsigned int vm_event_ring_available(struct 
vm_event_domain *ved)
  * but need to be resumed where the ring is capable of processing at least
  * one event from them.
  */
-static void vm_event_wake_blocked(struct domain *d, struct vm_event_domain 
*ved)
+static void vm_event_wake_blocked(struct vm_event_domain *ved)
 {
 struct vcpu *v;
 unsigned int i, j, k, avail_req = vm_event_ring_available(ved);
+struct domain *d = ved->d;
 
 if ( avail_req == 0 || ved->blocked == 0 )
 return;
@@ -154,7 +155,7 @@ static void vm_event_wake_blocked(struct domain *d, struct 
vm_event_domain *ved)
  * was unable to do so, it is queued on a wait queue.  These are woken as
  * needed, and take precedence over 

[Xen-devel] [PATCH v2 02/10] vm_event: Remove "ring" suffix from vm_event_check_ring

2019-07-16 Thread Petre Pircalabu
Decouple implementation from interface to allow vm_event_check to be
used regardless of the vm_event underlying implementation.

Signed-off-by: Petre Pircalabu 
Acked-by: Andrew Cooper 
Acked-by: Tamas K Lengyel 
---
 xen/arch/arm/mem_access.c |  2 +-
 xen/arch/x86/mm/mem_access.c  |  4 ++--
 xen/arch/x86/mm/mem_paging.c  |  2 +-
 xen/common/mem_access.c   |  2 +-
 xen/common/vm_event.c | 24 
 xen/drivers/passthrough/pci.c |  2 +-
 xen/include/xen/vm_event.h|  4 ++--
 7 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/mem_access.c b/xen/arch/arm/mem_access.c
index 3e36202..d54760b 100644
--- a/xen/arch/arm/mem_access.c
+++ b/xen/arch/arm/mem_access.c
@@ -290,7 +290,7 @@ bool p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const 
struct npfec npfec)
 }
 
 /* Otherwise, check if there is a vm_event monitor subscriber */
-if ( !vm_event_check_ring(v->domain->vm_event_monitor) )
+if ( !vm_event_check(v->domain->vm_event_monitor) )
 {
 /* No listener */
 if ( p2m->access_required )
diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c
index 0144f92..640352e 100644
--- a/xen/arch/x86/mm/mem_access.c
+++ b/xen/arch/x86/mm/mem_access.c
@@ -182,7 +182,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 gfn_unlock(p2m, gfn, 0);
 
 /* Otherwise, check if there is a memory event listener, and send the 
message along */
-if ( !vm_event_check_ring(d->vm_event_monitor) || !req_ptr )
+if ( !vm_event_check(d->vm_event_monitor) || !req_ptr )
 {
 /* No listener */
 if ( p2m->access_required )
@@ -210,7 +210,7 @@ bool p2m_mem_access_check(paddr_t gpa, unsigned long gla,
 return true;
 }
 }
-if ( vm_event_check_ring(d->vm_event_monitor) &&
+if ( vm_event_check(d->vm_event_monitor) &&
  d->arch.monitor.inguest_pagefault_disabled &&
  npfec.kind != npfec_kind_with_gla ) /* don't send a mem_event */
 {
diff --git a/xen/arch/x86/mm/mem_paging.c b/xen/arch/x86/mm/mem_paging.c
index 54a94fa..dc2a59a 100644
--- a/xen/arch/x86/mm/mem_paging.c
+++ b/xen/arch/x86/mm/mem_paging.c
@@ -44,7 +44,7 @@ int 
mem_paging_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_paging_op_t) arg)
 goto out;
 
 rc = -ENODEV;
-if ( unlikely(!vm_event_check_ring(d->vm_event_paging)) )
+if ( unlikely(!vm_event_check(d->vm_event_paging)) )
 goto out;
 
 switch( mpo.op )
diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c
index 010e6f8..51e4e2b 100644
--- a/xen/common/mem_access.c
+++ b/xen/common/mem_access.c
@@ -52,7 +52,7 @@ int mem_access_memop(unsigned long cmd,
 goto out;
 
 rc = -ENODEV;
-if ( unlikely(!vm_event_check_ring(d->vm_event_monitor)) )
+if ( unlikely(!vm_event_check(d->vm_event_monitor)) )
 goto out;
 
 switch ( mao.op )
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 56b506a..515a917 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -179,7 +179,7 @@ static int vm_event_disable(struct domain *d, struct 
vm_event_domain **p_ved)
 {
 struct vm_event_domain *ved = *p_ved;
 
-if ( vm_event_check_ring(ved) )
+if ( vm_event_check(ved) )
 {
 struct vcpu *v;
 
@@ -259,7 +259,7 @@ void vm_event_put_request(struct domain *d,
 RING_IDX req_prod;
 struct vcpu *curr = current;
 
-if( !vm_event_check_ring(ved) )
+if( !vm_event_check(ved) )
 return;
 
 if ( curr->domain != d )
@@ -362,7 +362,7 @@ static int vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
  */
 ASSERT(d != current->domain);
 
-if ( unlikely(!vm_event_check_ring(ved)) )
+if ( unlikely(!vm_event_check(ved)) )
  return -ENODEV;
 
 /* Pull all responses off the ring. */
@@ -433,7 +433,7 @@ static int vm_event_resume(struct domain *d, struct 
vm_event_domain *ved)
 
 void vm_event_cancel_slot(struct domain *d, struct vm_event_domain *ved)
 {
-if( !vm_event_check_ring(ved) )
+if( !vm_event_check(ved) )
 return;
 
 spin_lock(&ved->lock);
@@ -488,7 +488,7 @@ static int vm_event_wait_slot(struct vm_event_domain *ved)
 return rc;
 }
 
-bool vm_event_check_ring(struct vm_event_domain *ved)
+bool vm_event_check(struct vm_event_domain *ved)
 {
 return ved && ved->ring_page;
 }
@@ -508,7 +508,7 @@ bool vm_event_check_ring(struct vm_event_domain *ved)
 int __vm_event_claim_slot(struct domain *d, struct vm_event_domain *ved,
   bool allow_sleep)
 {
-if ( !vm_event_check_ring(ved) )
+if ( !vm_event_check(ved) )
 return -EOPNOTSUPP;
 
 if ( (current->domain == d) && allow_sleep )
@@ -543,7 +543,7 @@ static void mem_sharing_notification(struct vcpu *v, 
unsigned int port)
 void vm_event_cleanup(struct domain *d)
 {

[Xen-devel] [PATCH v2 07/10] vm_event: Add vm_event_ng interface

2019-07-16 Thread Petre Pircalabu
In high throughput introspection scenarios where lots of monitor
vm_events are generated, the ring buffer can fill up before the monitor
application gets a chance to handle all the requests thus blocking
other vcpus which will have to wait for a slot to become available.

This patch adds support for a different mechanism to handle synchronous
vm_event requests / responses. As each synchronous request pauses the
vcpu until the corresponding response is handled, it can be stored in
a slotted memory buffer (one per vcpu) shared between the hypervisor and
the controlling domain.

Signed-off-by: Petre Pircalabu 
---
 tools/libxc/include/xenctrl.h |   9 +
 tools/libxc/xc_mem_paging.c   |   9 +-
 tools/libxc/xc_memshr.c   |   9 +-
 tools/libxc/xc_monitor.c  |  23 +-
 tools/libxc/xc_private.h  |  12 +-
 tools/libxc/xc_vm_event.c | 100 ++-
 xen/arch/x86/mm.c |   7 +
 xen/common/vm_event.c | 595 +++---
 xen/include/public/domctl.h   |  10 +-
 xen/include/public/memory.h   |   2 +
 xen/include/public/vm_event.h |  16 ++
 xen/include/xen/vm_event.h|  11 +-
 12 files changed, 684 insertions(+), 119 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index f3af710..1293b0f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -128,6 +128,7 @@ enum xc_error_code {
 
 typedef enum xc_error_code xc_error_code;
 
+struct xenforeignmemory_resource_handle;
 
 /*
  *  INITIALIZATION FUNCTIONS
@@ -2007,6 +2008,14 @@ int xc_vm_event_get_version(xc_interface *xch);
 void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port);
 int xc_monitor_disable(xc_interface *xch, uint32_t domain_id);
 int xc_monitor_resume(xc_interface *xch, uint32_t domain_id);
+
+/* Monitor NG interface */
+int xc_monitor_ng_enable(xc_interface *xch, uint32_t domain_id,
+ struct xenforeignmemory_resource_handle **fres,
+ int *num_channels, void **p_addr);
+int xc_monitor_ng_disable(xc_interface *xch, uint32_t domain_id,
+  struct xenforeignmemory_resource_handle **fres);
+
 /*
  * Get a bitmap of supported monitor events in the form
  * (1 << XEN_DOMCTL_MONITOR_EVENT_*).
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index a88c0cc..978008a 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -49,7 +49,7 @@ int xc_mem_paging_enable(xc_interface *xch, uint32_t 
domain_id,
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_ENABLE,
XEN_VM_EVENT_TYPE_PAGING,
-   port);
+   0, port);
 }
 
 int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id)
@@ -57,15 +57,12 @@ int xc_mem_paging_disable(xc_interface *xch, uint32_t 
domain_id)
 return xc_vm_event_control(xch, domain_id,
XEN_VM_EVENT_DISABLE,
XEN_VM_EVENT_TYPE_PAGING,
-   NULL);
+   0, NULL);
 }
 
 int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id)
 {
-return xc_vm_event_control(xch, domain_id,
-   XEN_VM_EVENT_RESUME,
-   XEN_VM_EVENT_TYPE_PAGING,
-   NULL);
+return xc_vm_event_resume(xch, domain_id, XEN_VM_EVENT_TYPE_PAGING, 0);
 }
 
 int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id, uint64_t gfn)
diff --git a/tools/libxc/xc_memshr.c b/tools/libxc/xc_memshr.c
index 1c4a706..44d4f23 100644
--- a/tools/libxc/xc_memshr.c
+++ b/tools/libxc/xc_memshr.c
@@ -54,7 +54,7 @@ int xc_memshr_ring_enable(xc_interface *xch,
 return xc_vm_event_control(xch, domid,
XEN_VM_EVENT_ENABLE,
XEN_VM_EVENT_TYPE_SHARING,
-   port);
+   0, port);
 }
 
 int xc_memshr_ring_disable(xc_interface *xch, 
@@ -63,7 +63,7 @@ int xc_memshr_ring_disable(xc_interface *xch,
 return xc_vm_event_control(xch, domid,
XEN_VM_EVENT_DISABLE,
XEN_VM_EVENT_TYPE_SHARING,
-   NULL);
+   0, NULL);
 }
 
 static int xc_memshr_memop(xc_interface *xch, uint32_t domid,
@@ -203,10 +203,7 @@ int xc_memshr_range_share(xc_interface *xch,
 int xc_memshr_domain_resume(xc_interface *xch,
 uint32_t domid)
 {
-return xc_vm_event_control(xch, domid,
-   XEN_VM_EVENT_RESUME,
-   XEN_VM_EVENT_TYPE_SHARING,
-   NULL);
+return xc_vm_event_resume(xch, domid, XEN_VM_EVENT_TYPE_SHARING, 0);
 }
 
 int xc_memshr_debug_gfn(xc_interface *xch,
diff --git a/tools

[Xen-devel] [PATCH v2 09/10] xen-access: Code cleanup

2019-07-16 Thread Petre Pircalabu
Cleanup xen-access code in accordance with the XEN style guide.

Signed-off-by: Petre Pircalabu 
---
 tools/tests/xen-access/xen-access.c | 57 +
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/tools/tests/xen-access/xen-access.c 
b/tools/tests/xen-access/xen-access.c
index 8a3eea5..abf17a2 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -137,7 +137,7 @@ int xenaccess_teardown(xc_interface *xch, xenaccess_t 
*xenaccess)
 return 0;
 
 /* Tear down domain xenaccess in Xen */
-if ( xenaccess->vm_event.ring_page )
+if ( xenaccess->vm_event.ring_page != NULL )
 munmap(xenaccess->vm_event.ring_page, XC_PAGE_SIZE);
 
 if ( mem_access_enable )
@@ -195,7 +195,7 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t 
domain_id)
 int rc;
 
 xch = xc_interface_open(NULL, NULL, 0);
-if ( !xch )
+if ( xch == NULL )
 goto err_iface;
 
 DPRINTF("xenaccess init\n");
@@ -218,16 +218,17 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t 
domain_id)
   &xenaccess->vm_event.evtchn_port);
 if ( xenaccess->vm_event.ring_page == NULL )
 {
-switch ( errno ) {
-case EBUSY:
-ERROR("xenaccess is (or was) active on this domain");
-break;
-case ENODEV:
-ERROR("EPT not supported for this guest");
-break;
-default:
-perror("Error enabling mem_access");
-break;
+switch ( errno )
+{
+case EBUSY:
+ERROR("xenaccess is (or was) active on this domain");
+break;
+case ENODEV:
+ERROR("EPT not supported for this guest");
+break;
+default:
+perror("Error enabling mem_access");
+break;
 }
 goto err;
 }
@@ -283,15 +284,12 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t 
domain_id)
 }
 
  err_iface:
+
 return NULL;
 }
 
-static inline
-int control_singlestep(
-xc_interface *xch,
-domid_t domain_id,
-unsigned long vcpu,
-bool enable)
+static inline int control_singlestep(xc_interface *xch, domid_t domain_id,
+ unsigned long vcpu, bool enable)
 {
 uint32_t op = enable ?
 XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON : 
XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF;
@@ -361,11 +359,11 @@ void usage(char* progname)
 {
 fprintf(stderr, "Usage: %s [-m]  write|exec", progname);
 #if defined(__i386__) || defined(__x86_64__)
-fprintf(stderr, 
"|breakpoint|altp2m_write|altp2m_exec|debug|cpuid|desc_access|write_ctrlreg_cr4|altp2m_write_no_gpt");
+fprintf(stderr, 
"|breakpoint|altp2m_write|altp2m_exec|debug|cpuid|desc_access|write_ctrlreg_cr4|altp2m_write_no_gpt");
 #elif defined(__arm__) || defined(__aarch64__)
-fprintf(stderr, "|privcall");
+fprintf(stderr, "|privcall");
 #endif
-fprintf(stderr,
+fprintf(stderr,
 "\n"
 "Logs first page writes, execs, or breakpoint traps that occur on 
the domain.\n"
 "\n"
@@ -562,7 +560,7 @@ int main(int argc, char *argv[])
 DPRINTF("altp2m view created with id %u\n", altp2m_view_id);
 DPRINTF("Setting altp2m mem_access permissions.. ");
 
-for(; gfn < xenaccess->max_gpfn; ++gfn)
+for( ; gfn < xenaccess->max_gpfn; ++gfn )
 {
 rc = xc_altp2m_set_mem_access( xch, domain_id, altp2m_view_id, gfn,
default_access);
@@ -671,7 +669,7 @@ int main(int argc, char *argv[])
 }
 
 /* Wait for access */
-for (;;)
+for ( ; ; )
 {
 if ( interrupted )
 {
@@ -736,7 +734,8 @@ int main(int argc, char *argv[])
 rsp.flags = (req.flags & VM_EVENT_FLAG_VCPU_PAUSED);
 rsp.reason = req.reason;
 
-switch (req.reason) {
+switch ( req.reason )
+{
 case VM_EVENT_REASON_MEM_ACCESS:
 if ( !shutting_down )
 {
@@ -791,6 +790,7 @@ int main(int argc, char *argv[])
 
 rsp.u.mem_access = req.u.mem_access;
 break;
+
 case VM_EVENT_REASON_SOFTWARE_BREAKPOINT:
 printf("Breakpoint: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu 
%d)\n",
req.data.regs.x86.rip,
@@ -809,6 +809,7 @@ int main(int argc, char *argv[])
 continue;
 }
 break;
+
 case VM_EVENT_REASON_PRIVILEGED_CALL:
 printf("Privileged call: pc=%"P

[Xen-devel] [PATCH v2 06/10] vm_event: Decouple implementation details from interface.

2019-07-16 Thread Petre Pircalabu
To accommodate a second implementation of the vm_event subsystem, the
current one (ring) should be decoupled from the xen/vm_event.h interface.

Signed-off-by: Petre Pircalabu 
---
 xen/common/vm_event.c  | 368 ++---
 xen/include/xen/vm_event.h |  60 +++-
 2 files changed, 236 insertions(+), 192 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 21895c2..e6a7a29 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -35,12 +35,13 @@
 #define xen_rmb()  smp_rmb()
 #define xen_wmb()  smp_wmb()
 
-/* VM event */
-struct vm_event_domain
+#define to_ring(_ved) container_of((_ved), struct vm_event_ring_domain, ved)
+
+/* VM event ring implementation */
+struct vm_event_ring_domain
 {
-/* Domain reference */
-struct domain *d;
-spinlock_t lock;
+/* VM event domain */
+struct vm_event_domain ved;
 /* The ring has 64 entries */
 unsigned char foreign_producers;
 unsigned char target_producers;
@@ -61,7 +62,9 @@ struct vm_event_domain
 unsigned int last_vcpu_wake_up;
 };
 
-static int vm_event_enable(
+static const struct vm_event_ops vm_event_ring_ops;
+
+static int vm_event_ring_enable(
 struct domain *d,
 struct xen_domctl_vm_event_op *vec,
 struct vm_event_domain **p_ved,
@@ -71,7 +74,7 @@ static int vm_event_enable(
 {
 int rc;
 unsigned long ring_gfn = d->arch.hvm.params[param];
-struct vm_event_domain *ved;
+struct vm_event_ring_domain *impl;
 
 /*
  * Only one connected agent at a time.  If the helper crashed, the ring is
@@ -84,28 +87,28 @@ static int vm_event_enable(
 if ( ring_gfn == 0 )
 return -EOPNOTSUPP;
 
-ved = xzalloc(struct vm_event_domain);
-if ( !ved )
+impl = xzalloc(struct vm_event_ring_domain);
+if ( !impl )
 return -ENOMEM;
 
 /* Trivial setup. */
-spin_lock_init(&ved->lock);
-init_waitqueue_head(&ved->wq);
-ved->pause_flag = pause_flag;
+spin_lock_init(&impl->ved.lock);
+init_waitqueue_head(&impl->wq);
+impl->ved.d = d;
+impl->ved.ops = &vm_event_ring_ops;
+impl->pause_flag = pause_flag;
 
 rc = vm_event_init_domain(d);
 if ( rc < 0 )
 goto err;
 
-ved->d = d;
-
-rc = prepare_ring_for_helper(d, ring_gfn, &ved->ring_pg_struct,
- &ved->ring_page);
+rc = prepare_ring_for_helper(d, ring_gfn, &impl->ring_pg_struct,
+ &impl->ring_page);
 if ( rc < 0 )
 goto err;
 
-FRONT_RING_INIT(&ved->front_ring,
-(vm_event_sring_t *)ved->ring_page,
+FRONT_RING_INIT(&impl->front_ring,
+(vm_event_sring_t *)impl->ring_page,
 PAGE_SIZE);
 
 rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
@@ -113,26 +116,26 @@ static int vm_event_enable(
 if ( rc < 0 )
 goto err;
 
-ved->xen_port = vec->u.enable.port = rc;
+impl->xen_port = vec->u.enable.port = rc;
 
 /* Success.  Fill in the domain's appropriate ved. */
-*p_ved = ved;
+*p_ved = &impl->ved;
 
 return 0;
 
  err:
-destroy_ring_for_helper(&ved->ring_page, ved->ring_pg_struct);
-xfree(ved);
+destroy_ring_for_helper(&impl->ring_page, impl->ring_pg_struct);
+xfree(impl);
 
 return rc;
 }
 
-static unsigned int vm_event_ring_available(struct vm_event_domain *ved)
+static unsigned int vm_event_ring_available(struct vm_event_ring_domain *impl)
 {
-int avail_req = RING_FREE_REQUESTS(&ved->front_ring);
+int avail_req = RING_FREE_REQUESTS(&impl->front_ring);
 
-avail_req -= ved->target_producers;
-avail_req -= ved->foreign_producers;
+avail_req -= impl->target_producers;
+avail_req -= impl->foreign_producers;
 
 BUG_ON(avail_req < 0);
 
@@ -140,38 +143,38 @@ static unsigned int vm_event_ring_available(struct 
vm_event_domain *ved)
 }
 
 /*
- * vm_event_wake_blocked() will wakeup vcpus waiting for room in the
+ * vm_event_ring_wake_blocked() will wakeup vcpus waiting for room in the
  * ring. These vCPUs were paused on their way out after placing an event,
  * but need to be resumed where the ring is capable of processing at least
  * one event from them.
  */
-static void vm_event_wake_blocked(struct vm_event_domain *ved)
+static void vm_event_ring_wake_blocked(struct vm_event_ring_domain *impl)
 {
 struct vcpu *v;
-unsigned int i, j, k, avail_req = vm_event_ring_available(ved);
-struct domain *d = ved->d;
+unsigned int i, j, k, avail_req = vm_event_ring_available(impl);
+struct domain *d = impl->ved.d;
 
-if ( avail_req == 0 || ved->blocked == 0 )
+if ( avail_req == 0 || impl->blocked == 0 )
 return;
 
 /* We remember which 

[Xen-devel] [PATCH v2 05/10] vm_event: Move struct vm_event_domain to vm_event.c

2019-07-16 Thread Petre Pircalabu
The vm_event_domain members are not accessed outside vm_event.c so it's
better to hide de implementation details.

Signed-off-by: Petre Pircalabu 
Acked-by: Andrew Cooper 
Acked-by: Tamas K Lengyel 
---
 xen/common/vm_event.c   | 26 ++
 xen/include/xen/sched.h | 26 +-
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index a235d25..21895c2 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -35,6 +35,32 @@
 #define xen_rmb()  smp_rmb()
 #define xen_wmb()  smp_wmb()
 
+/* VM event */
+struct vm_event_domain
+{
+/* Domain reference */
+struct domain *d;
+spinlock_t lock;
+/* The ring has 64 entries */
+unsigned char foreign_producers;
+unsigned char target_producers;
+/* shared ring page */
+void *ring_page;
+struct page_info *ring_pg_struct;
+/* front-end ring */
+vm_event_front_ring_t front_ring;
+/* event channel port (vcpu0 only) */
+int xen_port;
+/* vm_event bit for vcpu->pause_flags */
+int pause_flag;
+/* list of vcpus waiting for room in the ring */
+struct waitqueue_head wq;
+/* the number of vCPUs blocked */
+unsigned int blocked;
+/* The last vcpu woken up */
+unsigned int last_vcpu_wake_up;
+};
+
 static int vm_event_enable(
 struct domain *d,
 struct xen_domctl_vm_event_op *vec,
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index e3093d3..19980d2 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -276,31 +276,7 @@ struct vcpu
 #define domain_lock(d) spin_lock_recursive(&(d)->domain_lock)
 #define domain_unlock(d) spin_unlock_recursive(&(d)->domain_lock)
 
-/* VM event */
-struct vm_event_domain
-{
-/* Domain reference */
-struct domain *d;
-spinlock_t lock;
-/* The ring has 64 entries */
-unsigned char foreign_producers;
-unsigned char target_producers;
-/* shared ring page */
-void *ring_page;
-struct page_info *ring_pg_struct;
-/* front-end ring */
-vm_event_front_ring_t front_ring;
-/* event channel port (vcpu0 only) */
-int xen_port;
-/* vm_event bit for vcpu->pause_flags */
-int pause_flag;
-/* list of vcpus waiting for room in the ring */
-struct waitqueue_head wq;
-/* the number of vCPUs blocked */
-unsigned int blocked;
-/* The last vcpu woken up */
-unsigned int last_vcpu_wake_up;
-};
+struct vm_event_domain;
 
 struct evtchn_port_ops;
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 00/10] Per vcpu vm_event channels

2019-07-16 Thread Petre Pircalabu
This patchset adds a new mechanism of sending synchronous vm_event
requests and handling vm_event responses without using a ring.
As each synchronous request pauses the vcpu until the corresponding
response is handled, it can be stored in a slotted memory buffer
(one per vcpu) shared between the hypervisor and the controlling domain.

The main advantages of this approach are:
* the ability to dynamicaly allocate the necessary memory used to hold
the requests/responses (the size of vm_event_request_t/vm_event_response_t
can grow unrestricted by the ring's one page limitation)
* the ring's waitqueue logic is unnecessary in this case because the
vcpu sending the request is blocked until a response is received.

---
Changes from v1:

* Dropped the "tools/libxc: Consistent usage of xc_vm_event_* interface"
because it was not a hard requirement for this patchset.
* Removed sched.h from vm_event.h and replaced it fw declarations of
"struct domain" and "struct vm"event_domain"
* Reworked the vm_event_ng memory allocation mechanism to use
vzalloc/share_xen_page_with_guest. 
* Replaced the new domctl with a flag in the existing one. When the client
(libxc) wants to use the new interface the XEN_VM_EVENT_FLAGS_NG_OP bit
should be set. Also, the file xen/common/vm_event_ng.c was removed because
the domctl is shared between interfaces, and having 2 separated files would
unnecessary expose non-interface functions.
* The xen-access related patch was split in 3 new ones:
  * getopt_long for cmdline parsing
  * code-cleanup according to the XEN style guide
  * the vm_event_ng interface support

---
Petre Pircalabu (10):
  vm_event: Define VM_EVENT type
  vm_event: Remove "ring" suffix from vm_event_check_ring
  vm_event: Add 'struct domain' backpointer to vm_event_domain.
  vm_event: Simplify vm_event interface
  vm_event: Move struct vm_event_domain to vm_event.c
  vm_event: Decouple implementation details from interface.
  vm_event: Add vm_event_ng interface
  xen-access: Use getopt_long for cmdline parsing
  xen-access: Code cleanup
  xen-access: Add support for vm_event_ng interface

 tools/libxc/include/xenctrl.h|  10 +
 tools/libxc/xc_mem_paging.c  |  13 +-
 tools/libxc/xc_memshr.c  |  13 +-
 tools/libxc/xc_monitor.c |  27 +-
 tools/libxc/xc_private.h |  18 +-
 tools/libxc/xc_vm_event.c| 154 --
 tools/tests/xen-access/Makefile  |   7 +-
 tools/tests/xen-access/vm-event-ng.c | 183 +++
 tools/tests/xen-access/vm-event.c| 194 
 tools/tests/xen-access/xen-access.c  | 435 +++--
 tools/tests/xen-access/xen-access.h  |  91 
 xen/arch/arm/mem_access.c|   2 +-
 xen/arch/x86/mm.c|   7 +
 xen/arch/x86/mm/mem_access.c |   4 +-
 xen/arch/x86/mm/mem_paging.c |   2 +-
 xen/arch/x86/mm/mem_sharing.c|   5 +-
 xen/arch/x86/mm/p2m.c|  10 +-
 xen/common/mem_access.c  |   2 +-
 xen/common/monitor.c |   4 +-
 xen/common/vm_event.c| 912 +--
 xen/drivers/passthrough/pci.c|   2 +-
 xen/include/public/domctl.h  |  82 +---
 xen/include/public/memory.h  |   2 +
 xen/include/public/vm_event.h|  47 ++
 xen/include/xen/sched.h  |  24 +-
 xen/include/xen/vm_event.h   |  80 ++-
 26 files changed, 1631 insertions(+), 699 deletions(-)
 create mode 100644 tools/tests/xen-access/vm-event-ng.c
 create mode 100644 tools/tests/xen-access/vm-event.c
 create mode 100644 tools/tests/xen-access/xen-access.h

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel