Re: [Xen-devel] [PATCH v5] x86/altp2m: Added xc_altp2m_set_mem_access_multi()

2017-10-13 Thread Jan Beulich
>>> On 13.10.17 at 15:00,  wrote:
> On Vi, 2017-10-13 at 03:51 -0600, Jan Beulich wrote:
>> > 
>> > 
>> > +BUILD_BUG_ON(sizeof(struct
>> > xen_hvm_altp2m_set_mem_access_multi) <
>> > + sizeof(struct
>> > compat_hvm_altp2m_set_mem_access_multi));
>> What good does this do?
>> Sorry, I don't understand how these size checks should look (are we
>> testing that the left hand side is at least as wide as the right hand
>> side?). Could you please give an example? Thanks!
> 
>> > + */
>> > +nat.altp2m_op->version  = a.version;
>> > +nat.altp2m_op->cmd  = a.cmd;
>> > +nat.altp2m_op->domain   = a.domain;
>> > +nat.altp2m_op->pad1 = a.pad1;
>> > +nat.altp2m_op->pad2 = a.pad2;
>> There are _still_ no size checks here.
> I'm not sure I understand what kind of size checks should be used here.
> Are you expecting something similar with the CHECK_FIELD_ macro?

Yes, as I've been stating repeatedly. You want to demonstrate
that field sizes match, or that at least no truncation can occur.

>> > 
>> > +if ( nat.altp2m_op->u.set_mem_access_multi.opaque > 0
>> > )
>> Please also check rc here to avoid needlessly copying back. In
>> fact _only_ checking rc ought to be fine.
> Actually, in this case rc is overwritten in do_altp2m_op (-EFAULT if
> the copy didn't work or the result of hypercall_create_continuation
> otherwise).

And it's the result of hypercall_create_continuation() which you
want to check against (provided there's no other way for rc to
obtain a positive value).

Jan


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


Re: [Xen-devel] [PATCH v5] x86/altp2m: Added xc_altp2m_set_mem_access_multi()

2017-10-13 Thread Petre Ovidiu PIRCALABU
On Vi, 2017-10-13 at 03:51 -0600, Jan Beulich wrote:
> > 
> > 
> > +BUILD_BUG_ON(sizeof(struct
> > xen_hvm_altp2m_set_mem_access_multi) <
> > + sizeof(struct
> > compat_hvm_altp2m_set_mem_access_multi));
> What good does this do?
> Sorry, I don't understand how these size checks should look (are we
> testing that the left hand side is at least as wide as the right hand
> side?). Could you please give an example? Thanks!

> > + */
> > +nat.altp2m_op->version  = a.version;
> > +nat.altp2m_op->cmd  = a.cmd;
> > +nat.altp2m_op->domain   = a.domain;
> > +nat.altp2m_op->pad1 = a.pad1;
> > +nat.altp2m_op->pad2 = a.pad2;
> There are _still_ no size checks here.
I'm not sure I understand what kind of size checks should be used here.
Are you expecting something similar with the CHECK_FIELD_ macro?
> > 
> > +if ( nat.altp2m_op->u.set_mem_access_multi.opaque > 0
> > )
> Please also check rc here to avoid needlessly copying back. In
> fact _only_ checking rc ought to be fine.
Actually, in this case rc is overwritten in do_altp2m_op (-EFAULT if
the copy didn't work or the result of hypercall_create_continuation
otherwise).
I have used the check for nat.altp2m_op->u.set_mem_access_multi.opaque
as it usually gets set to a positive value only if the hypercall gets
preempted,

Many thanks for your support,
Petre
> 
> > 
> 
> Jan
> 
> 
> 
> This email was scanned by Bitdefender
___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v5] x86/altp2m: Added xc_altp2m_set_mem_access_multi()

2017-10-13 Thread Jan Beulich
>>> On 11.10.17 at 18:26,  wrote:
> @@ -4568,6 +4571,32 @@ static int do_altp2m_op(
>  a.u.set_mem_access.view);
>  break;
>  
> +case HVMOP_altp2m_set_mem_access_multi:
> +if ( a.u.set_mem_access_multi.pad ||
> + a.u.set_mem_access_multi.opaque >= a.u.set_mem_access_multi.nr )
> +{
> +rc = -EINVAL;
> +break;
> +}
> +
> +rc = p2m_set_mem_access_multi(d, a.u.set_mem_access_multi.pfn_list,
> +  a.u.set_mem_access_multi.access_list,
> +  a.u.set_mem_access_multi.nr,
> +  a.u.set_mem_access_multi.opaque,
> +  0x3F,

Please add /* pretty arbitrary */ or something similar here.

> @@ -4586,6 +4615,80 @@ static int do_altp2m_op(
>  return rc;
>  }
>  
> +DEFINE_XEN_GUEST_HANDLE(compat_hvm_altp2m_op_t);
> +
> +static int compat_altp2m_op(
> +XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> +int rc = 0;
> +struct compat_hvm_altp2m_op a;
> +union
> +{
> +XEN_GUEST_HANDLE_PARAM(void) hnd;
> +struct xen_hvm_altp2m_op *altp2m_op;
> +} nat;
> +
> +if ( !hvm_altp2m_supported() )
> +return -EOPNOTSUPP;
> +
> +if ( copy_from_guest(&a, arg, 1) )
> +return -EFAULT;
> +
> +if ( a.pad1 || a.pad2 ||
> + (a.version != HVMOP_ALTP2M_INTERFACE_VERSION) )
> +return -EINVAL;
> +
> +set_xen_guest_handle(nat.hnd, COMPAT_ARG_XLAT_VIRT_BASE);
> +
> +switch ( a.cmd )
> +{
> +case HVMOP_altp2m_set_mem_access_multi:

Indentation.

> +BUILD_BUG_ON(sizeof(struct xen_hvm_altp2m_set_mem_access_multi) <
> + sizeof(struct 
> compat_hvm_altp2m_set_mem_access_multi));

What good does this do?

> +#define XLAT_hvm_altp2m_set_mem_access_multi_HNDL_pfn_list(_d_, _s_); \
> +guest_from_compat_handle((_d_)->pfn_list, (_s_)->pfn_list)
> +#define XLAT_hvm_altp2m_set_mem_access_multi_HNDL_access_list(_d_, _s_); \
> +guest_from_compat_handle((_d_)->access_list, (_s_)->access_list)
> +
> XLAT_hvm_altp2m_set_mem_access_multi(&nat.altp2m_op->u.set_mem_access_multi,
> +&a.u.set_mem_access_multi);
> +#undef XLAT_hvm_altp2m_set_mem_access_multi_HNDL_pfn_list
> +#undef XLAT_hvm_altp2m_set_mem_access_multi_HNDL_access_list
> +break;
> +default:
> +return do_altp2m_op(arg);
> +}
> +
> +/*
> + * Manually fill the common part of the xen_hvm_altp2m_op structure 
> because
> + * the generated XLAT_hvm_altp2m_op macro doesn't correctly handle the
> + * translation of all fields from compat_hvm_altp2m_op to 
> xen_hvm_altp2m_op.
> + */
> +nat.altp2m_op->version  = a.version;
> +nat.altp2m_op->cmd  = a.cmd;
> +nat.altp2m_op->domain   = a.domain;
> +nat.altp2m_op->pad1 = a.pad1;
> +nat.altp2m_op->pad2 = a.pad2;

There are _still_ no size checks here.

> +rc = do_altp2m_op(nat.hnd);
> +
> +switch ( a.cmd )
> +{
> +case HVMOP_altp2m_set_mem_access_multi:

Indentation.

> +if ( nat.altp2m_op->u.set_mem_access_multi.opaque > 0 )

Please also check rc here to avoid needlessly copying back. In
fact _only_ checking rc ought to be fine.

> +{
> +a.u.set_mem_access_multi.opaque =
> +nat.altp2m_op->u.set_mem_access_multi.opaque;

You also need a size check here.

Jan


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


[Xen-devel] [PATCH v5] x86/altp2m: Added xc_altp2m_set_mem_access_multi()

2017-10-11 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 0x3Fa.
* 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.
---
 tools/libxc/include/xenctrl.h   |   3 ++
 tools/libxc/xc_altp2m.c |  41 
 xen/arch/x86/hvm/hvm.c  | 105 +++-
 xen/include/Makefile|   1 +
 xen/include/public/hvm/hvm_op.h |  36 --
 xen/include/xlat.lst|   1 +
 6 files changed, 181 insertions(+), 6 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 3bcab3c..4e2ce64 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1971,6 +1971,9 @@ int xc_altp2m_switch_to_view(xc_interface *handle, 
domid_t domid,
 int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
  uint16_t view_id, xen_pfn_t gfn,
  xenmem_access_t access);
+int xc_altp2m_set_mem_access_multi(xc_interface *handle, domid_t domid,
+   uint16_t view_id, uint8_t *access,
+   uint64_t *pages, uint32_t nr);
 int xc_altp2m_change_gfn(xc_interface *handle, domid_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 0639632..f202ca1 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -188,6 +188,47 @@ int xc_altp2m_set_mem_access(xc_interface *handle, domid_t 
domid,
 return rc;
 }
 
+int xc_altp2m_set_mem_access_multi(xc_interface *xch, domid_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, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+DECLARE_HYPERCALL_BOUNCE(pages, nr * sizeof(uint64_t),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
+if ( arg == NULL )
+return -1;
+
+arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
+arg->cmd = HVMOP_altp2m_set_mem_access_multi;
+arg->domain = domid;
+arg->u.set_mem_access_multi.view = view_id;
+arg->u.set_mem_access_multi.nr = nr;
+
+if ( xc_hypercall_bounce_pre(xch, pages) ||
+ xc_hypercall_bounce_pre(xch, access) )
+{
+PERROR("Could not bounce memory for 
HVMOP_altp2m_set_mem_access_multi");
+return -1;
+}
+
+set_xen_guest_handle(arg->u.set_mem_access_multi.pfn_list, pages);
+set_xen_guest_handle(arg->u.set_mem_access_multi.access_list, access);
+
+rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+ HYPERCALL_BUFFER_AS_ARG(arg));
+
+xc_hypercall_buffer_free(xch, arg);
+xc_hypercall_bounce_post(xch, access);
+xc_hypercall_bounce_post(xch, pages);
+
+return rc;
+}
+
 int xc_altp2m_change_gfn(xc_interface *handle, domid_t domid,
  uint16_t view_id, xen_pfn_t old_gfn,
  xen_pfn_t new_gfn)
diff -