Re: [Xen-devel] [PATCH v2 06/11] hvmctl: convert HVMOP_modified_memory

2016-07-05 Thread Daniel De Graaf

On 06/24/2016 06:31 AM, Jan Beulich wrote:

Also limiting "nr" at the libxc level to 32 bits (the high 32 bits of
the previous 64-bit parameter got ignore so far).

Signed-off-by: Jan Beulich 
Reviewed-by: Wei Liu 
Reviewed-by: Andrew Cooper 


Acked-by: Daniel De Graaf 

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


[Xen-devel] [PATCH v2 06/11] hvmctl: convert HVMOP_modified_memory

2016-06-24 Thread Jan Beulich
Also limiting "nr" at the libxc level to 32 bits (the high 32 bits of
the previous 64-bit parameter got ignore so far).

Signed-off-by: Jan Beulich 
Reviewed-by: Wei Liu 
Reviewed-by: Andrew Cooper 

--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1620,7 +1620,7 @@ int xc_hvm_track_dirty_vram(
  * Notify that some pages got modified by the Device Model
  */
 int xc_hvm_modified_memory(
-xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr);
+xc_interface *xch, domid_t dom, uint64_t first_gfn, uint32_t nr);
 
 /*
  * Set a range of memory to a specific type.
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -558,29 +558,13 @@ int xc_hvm_track_dirty_vram(
 }
 
 int xc_hvm_modified_memory(
-xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr)
+xc_interface *xch, domid_t dom, uint64_t first_gfn, uint32_t nr)
 {
-DECLARE_HYPERCALL_BUFFER(struct xen_hvm_modified_memory, arg);
-int rc;
+DECLARE_HVMCTL(modified_memory, dom,
+   .first_gfn = first_gfn,
+   .nr= nr);
 
-arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
-if ( arg == NULL )
-{
-PERROR("Could not allocate memory for xc_hvm_modified_memory 
hypercall");
-return -1;
-}
-
-arg->domid = dom;
-arg->first_pfn = first_pfn;
-arg->nr= nr;
-
-rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
-  HVMOP_modified_memory,
-  HYPERCALL_BUFFER_AS_ARG(arg));
-
-xc_hypercall_buffer_free(xch, arg);
-
-return rc;
+return do_hvmctl(xch, );
 }
 
 int xc_hvm_set_mem_type(
--- a/xen/arch/x86/hvm/control.c
+++ b/xen/arch/x86/hvm/control.c
@@ -14,6 +14,7 @@
  * this program; If not, see .
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -90,6 +91,51 @@ static int track_dirty_vram(struct domai
: hap_track_dirty_vram(d, op->first_gfn, op->nr, op->dirty_bitmap);
 }
 
+static int modified_memory(struct domain *d,
+   const struct xen_hvm_modified_memory *op,
+   uint64_t *iter)
+{
+if ( !is_hvm_domain(d) )
+return -EINVAL;
+
+if ( op->rsvd || op->nr < *iter ||
+ ((op->first_gfn + op->nr - 1) < op->first_gfn) ||
+ ((op->first_gfn + op->nr - 1) > domain_get_maximum_gpfn(d)) )
+return -EINVAL;
+
+if ( !paging_mode_log_dirty(d) )
+return 0;
+
+while ( op->nr > *iter )
+{
+unsigned long gfn = op->first_gfn + *iter;
+struct page_info *page = get_page_from_gfn(d, gfn, NULL, P2M_UNSHARE);
+
+if ( page )
+{
+unsigned long mfn = page_to_mfn(page);
+
+paging_mark_dirty(d, mfn);
+/*
+ * These are most probably not page tables any more:
+ * Don't take a long time, and don't die either.
+ */
+sh_remove_shadows(d, _mfn(mfn), 1, 0);
+put_page(page);
+}
+
+/*
+ * Check for continuation every once in a while, and if it's not the
+ * last interation.
+ */
+if ( op->nr > ++*iter && !(*iter & 0xff) &&
+ hypercall_preempt_check() )
+return -ERESTART;
+}
+
+return 0;
+}
+
 long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xen_hvmctl_t) u_hvmctl)
 {
 xen_hvmctl_t op;
@@ -140,6 +186,10 @@ long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xe
 rc = track_dirty_vram(d, _dirty_vram);
 break;
 
+case XEN_HVMCTL_modified_memory:
+rc = modified_memory(d, _memory, );
+break;
+
 default:
 rc = -EOPNOTSUPP;
 break;
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -5233,7 +5233,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
 default:
 mask = ~0UL;
 break;
-case HVMOP_modified_memory:
 case HVMOP_set_mem_type:
 mask = HVMOP_op_mask;
 break;
@@ -5296,65 +5295,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
 rc = guest_handle_is_null(arg) ? hvmop_flush_tlb_all() : -ENOSYS;
 break;
 
-case HVMOP_modified_memory:
-{
-struct xen_hvm_modified_memory a;
-struct domain *d;
-
-if ( copy_from_guest(, arg, 1) )
-return -EFAULT;
-
-rc = rcu_lock_remote_domain_by_id(a.domid, );
-if ( rc != 0 )
-return rc;
-
-rc = -EINVAL;
-if ( !is_hvm_domain(d) )
-goto modmem_fail;
-
-rc = xsm_hvm_control(XSM_DM_PRIV, d, op);
-if ( rc )
-goto modmem_fail;
-
-rc = -EINVAL;
-if ( a.nr < start_iter ||
- ((a.first_pfn + a.nr - 1) < a.first_pfn) ||
- ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) )
-goto modmem_fail;
-
-rc = 0;
-if ( !paging_mode_log_dirty(d) )
-goto modmem_fail;
-