diff mbox

[v2,REPOST,03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources

Message ID 20170822145107.6877-4-paul.durrant@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paul Durrant Aug. 22, 2017, 2:50 p.m. UTC
Certain memory resources associated with a guest are not necessarily
present in the guest P2M and so are not necessarily available to be
foreign-mapped by a tools domain unless they are inserted, which risks
shattering a super-page mapping.

This patch adds a new memory op to allow such resourced to be priv-mapped
directly, by either a PV or HVM tools domain.

NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,
      I have no means to test it on an ARM platform and so cannot verify
      that it functions correctly. Hence it is currently only implemented
      for x86.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>
---
 xen/arch/x86/mm.c           | 111 ++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/p2m.c       |   3 +-
 xen/include/asm-x86/p2m.h   |   3 ++
 xen/include/public/memory.h |  38 ++++++++++++++-
 4 files changed, 152 insertions(+), 3 deletions(-)

Comments

Wei Liu Aug. 28, 2017, 3:01 p.m. UTC | #1
On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> +
> +/*
> + * Get the pages for a particular guest resource, so that they can be
> + * mapped directly by a tools domain.
> + */
> +#define XENMEM_acquire_resource 28
> +struct xen_mem_acquire_resource {
> +    /* IN - the domain whose resource is to be mapped */
> +    domid_t domid;
> +    /* IN - the type of resource (defined below) */
> +    uint16_t type;
> +
> +#define XENMEM_resource_grant_table 0
> +
> +    /*
> +     * IN - a type-specific resource identifier, which must be zero
> +     *      unless stated otherwise.
> +     */
> +    uint32_t id;
> +    /* IN - number of (4K) frames of the resource to be mapped */
> +    uint32_t nr_frames;
> +    /* IN - the index of the initial frame to be mapped */
> +    uint64_aligned_t frame;
> +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> +     *          will be populated with the MFNs of the resource.
> +     *          If the tools domain is HVM then it is expected that, on
> +     *          entry, gmfn_list will be populated with a list of GFNs
> +     *          that will be mapped to the MFNs of the resource.
> +     */
> +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;

Why is it not possible to make PV does the same thing as HVM?
Paul Durrant Aug. 29, 2017, 8:32 a.m. UTC | #2
> -----Original Message-----
> From: Wei Liu [mailto:wei.liu2@citrix.com]
> Sent: 28 August 2017 16:01
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; George Dunlap
> <George.Dunlap@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>; Wei Liu
> <wei.liu2@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> > +
> > +/*
> > + * Get the pages for a particular guest resource, so that they can be
> > + * mapped directly by a tools domain.
> > + */
> > +#define XENMEM_acquire_resource 28
> > +struct xen_mem_acquire_resource {
> > +    /* IN - the domain whose resource is to be mapped */
> > +    domid_t domid;
> > +    /* IN - the type of resource (defined below) */
> > +    uint16_t type;
> > +
> > +#define XENMEM_resource_grant_table 0
> > +
> > +    /*
> > +     * IN - a type-specific resource identifier, which must be zero
> > +     *      unless stated otherwise.
> > +     */
> > +    uint32_t id;
> > +    /* IN - number of (4K) frames of the resource to be mapped */
> > +    uint32_t nr_frames;
> > +    /* IN - the index of the initial frame to be mapped */
> > +    uint64_aligned_t frame;
> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> > +     *          will be populated with the MFNs of the resource.
> > +     *          If the tools domain is HVM then it is expected that, on
> > +     *          entry, gmfn_list will be populated with a list of GFNs
> > +     *          that will be mapped to the MFNs of the resource.
> > +     */
> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> 
> Why is it not possible to make PV does the same thing as HVM?

Because PV guests don't use a P2M as such. An HVM guest can pass GFNs in and say 'I want the resource mapped here'. A PV guest can't do that since it's using MFNs directly... it has to deal with the resource wherever it may be.

  Paul
Jan Beulich Aug. 29, 2017, 8:59 a.m. UTC | #3
>>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> Sent: 28 August 2017 16:01
>> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> > +
>> > +/*
>> > + * Get the pages for a particular guest resource, so that they can be
>> > + * mapped directly by a tools domain.
>> > + */
>> > +#define XENMEM_acquire_resource 28
>> > +struct xen_mem_acquire_resource {
>> > +    /* IN - the domain whose resource is to be mapped */
>> > +    domid_t domid;
>> > +    /* IN - the type of resource (defined below) */
>> > +    uint16_t type;
>> > +
>> > +#define XENMEM_resource_grant_table 0
>> > +
>> > +    /*
>> > +     * IN - a type-specific resource identifier, which must be zero
>> > +     *      unless stated otherwise.
>> > +     */
>> > +    uint32_t id;
>> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> > +    uint32_t nr_frames;
>> > +    /* IN - the index of the initial frame to be mapped */
>> > +    uint64_aligned_t frame;
>> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> > +     *          will be populated with the MFNs of the resource.
>> > +     *          If the tools domain is HVM then it is expected that, on
>> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> > +     *          that will be mapped to the MFNs of the resource.
>> > +     */
>> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> 
>> Why is it not possible to make PV does the same thing as HVM?
> 
> Because PV guests don't use a P2M as such.

They certainly do, just Xen can't rely on (and hence use) it.

> An HVM guest can pass GFNs in and 
> say 'I want the resource mapped here'. A PV guest can't do that since it's 
> using MFNs directly... it has to deal with the resource wherever it may be.

Xen does, however, maintain the M2P, so it would not be impossible
to return GFNs here for PV guests, requiring the caller to translate
them back to MFNs if so desired.

Jan
Paul Durrant Aug. 29, 2017, 9:13 a.m. UTC | #4
> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 29 August 2017 10:00
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
> >> Sent: 28 August 2017 16:01
> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> >> > +
> >> > +/*
> >> > + * Get the pages for a particular guest resource, so that they can be
> >> > + * mapped directly by a tools domain.
> >> > + */
> >> > +#define XENMEM_acquire_resource 28
> >> > +struct xen_mem_acquire_resource {
> >> > +    /* IN - the domain whose resource is to be mapped */
> >> > +    domid_t domid;
> >> > +    /* IN - the type of resource (defined below) */
> >> > +    uint16_t type;
> >> > +
> >> > +#define XENMEM_resource_grant_table 0
> >> > +
> >> > +    /*
> >> > +     * IN - a type-specific resource identifier, which must be zero
> >> > +     *      unless stated otherwise.
> >> > +     */
> >> > +    uint32_t id;
> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
> >> > +    uint32_t nr_frames;
> >> > +    /* IN - the index of the initial frame to be mapped */
> >> > +    uint64_aligned_t frame;
> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> >> > +     *          will be populated with the MFNs of the resource.
> >> > +     *          If the tools domain is HVM then it is expected that, on
> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
> >> > +     *          that will be mapped to the MFNs of the resource.
> >> > +     */
> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> >>
> >> Why is it not possible to make PV does the same thing as HVM?
> >
> > Because PV guests don't use a P2M as such.
> 
> They certainly do, just Xen can't rely on (and hence use) it.

Oh I know they have one but, as you say, Xen can't use it do put resources at a particular guest location.

> 
> > An HVM guest can pass GFNs in and
> > say 'I want the resource mapped here'. A PV guest can't do that since it's
> > using MFNs directly... it has to deal with the resource wherever it may be.
> 
> Xen does, however, maintain the M2P, so it would not be impossible
> to return GFNs here for PV guests, requiring the caller to translate
> them back to MFNs if so desired.
> 

That's possible, but still different to and HVM caller, which will pass GFNs in rather than using any values returned. So I don't really see any advantage in that.

  Paul

> Jan
Jan Beulich Aug. 29, 2017, 9:27 a.m. UTC | #5
>>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
>>  -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: 29 August 2017 10:00
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> devel@lists.xenproject.org 
>> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> HYPERVISOR_memory_op to acquire guest resources
>> 
>> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> >> Sent: 28 August 2017 16:01
>> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> >> > +
>> >> > +/*
>> >> > + * Get the pages for a particular guest resource, so that they can be
>> >> > + * mapped directly by a tools domain.
>> >> > + */
>> >> > +#define XENMEM_acquire_resource 28
>> >> > +struct xen_mem_acquire_resource {
>> >> > +    /* IN - the domain whose resource is to be mapped */
>> >> > +    domid_t domid;
>> >> > +    /* IN - the type of resource (defined below) */
>> >> > +    uint16_t type;
>> >> > +
>> >> > +#define XENMEM_resource_grant_table 0
>> >> > +
>> >> > +    /*
>> >> > +     * IN - a type-specific resource identifier, which must be zero
>> >> > +     *      unless stated otherwise.
>> >> > +     */
>> >> > +    uint32_t id;
>> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> >> > +    uint32_t nr_frames;
>> >> > +    /* IN - the index of the initial frame to be mapped */
>> >> > +    uint64_aligned_t frame;
>> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> >> > +     *          will be populated with the MFNs of the resource.
>> >> > +     *          If the tools domain is HVM then it is expected that, on
>> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> >> > +     *          that will be mapped to the MFNs of the resource.
>> >> > +     */
>> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> >>
>> >> Why is it not possible to make PV does the same thing as HVM?
>> >
>> > Because PV guests don't use a P2M as such.
>> 
>> They certainly do, just Xen can't rely on (and hence use) it.
> 
> Oh I know they have one but, as you say, Xen can't use it do put resources 
> at a particular guest location.
> 
>> 
>> > An HVM guest can pass GFNs in and
>> > say 'I want the resource mapped here'. A PV guest can't do that since it's
>> > using MFNs directly... it has to deal with the resource wherever it may be.
>> 
>> Xen does, however, maintain the M2P, so it would not be impossible
>> to return GFNs here for PV guests, requiring the caller to translate
>> them back to MFNs if so desired.
> 
> That's possible, but still different to and HVM caller, which will pass GFNs 
> in rather than using any values returned. So I don't really see any advantage 
> in that.

What's wrong with PV passing in PFNs, and Xen installing the
resulting translations into the M2P right away (leaving it to the
caller to just fix up its P2M)? That would sufficiently
parallel XENMEM_exchange, for example.

Jan
Paul Durrant Aug. 29, 2017, 9:31 a.m. UTC | #6
> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 29 August 2017 10:28
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> >>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
> >>  -----Original Message-----
> >> From: Jan Beulich [mailto:JBeulich@suse.com]
> >> Sent: 29 August 2017 10:00
> >> To: Paul Durrant <Paul.Durrant@citrix.com>
> >> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> >> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> >> devel@lists.xenproject.org
> >> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> >> HYPERVISOR_memory_op to acquire guest resources
> >>
> >> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
> >> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
> >> >> Sent: 28 August 2017 16:01
> >> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> >> >> > +
> >> >> > +/*
> >> >> > + * Get the pages for a particular guest resource, so that they can be
> >> >> > + * mapped directly by a tools domain.
> >> >> > + */
> >> >> > +#define XENMEM_acquire_resource 28
> >> >> > +struct xen_mem_acquire_resource {
> >> >> > +    /* IN - the domain whose resource is to be mapped */
> >> >> > +    domid_t domid;
> >> >> > +    /* IN - the type of resource (defined below) */
> >> >> > +    uint16_t type;
> >> >> > +
> >> >> > +#define XENMEM_resource_grant_table 0
> >> >> > +
> >> >> > +    /*
> >> >> > +     * IN - a type-specific resource identifier, which must be zero
> >> >> > +     *      unless stated otherwise.
> >> >> > +     */
> >> >> > +    uint32_t id;
> >> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
> >> >> > +    uint32_t nr_frames;
> >> >> > +    /* IN - the index of the initial frame to be mapped */
> >> >> > +    uint64_aligned_t frame;
> >> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> >> >> > +     *          will be populated with the MFNs of the resource.
> >> >> > +     *          If the tools domain is HVM then it is expected that, on
> >> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
> >> >> > +     *          that will be mapped to the MFNs of the resource.
> >> >> > +     */
> >> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> >> >>
> >> >> Why is it not possible to make PV does the same thing as HVM?
> >> >
> >> > Because PV guests don't use a P2M as such.
> >>
> >> They certainly do, just Xen can't rely on (and hence use) it.
> >
> > Oh I know they have one but, as you say, Xen can't use it do put resources
> > at a particular guest location.
> >
> >>
> >> > An HVM guest can pass GFNs in and
> >> > say 'I want the resource mapped here'. A PV guest can't do that since it's
> >> > using MFNs directly... it has to deal with the resource wherever it may
> be.
> >>
> >> Xen does, however, maintain the M2P, so it would not be impossible
> >> to return GFNs here for PV guests, requiring the caller to translate
> >> them back to MFNs if so desired.
> >
> > That's possible, but still different to and HVM caller, which will pass GFNs
> > in rather than using any values returned. So I don't really see any
> advantage
> > in that.
> 
> What's wrong with PV passing in PFNs, and Xen installing the
> resulting translations into the M2P right away (leaving it to the
> caller to just fix up its P2M)? That would sufficiently
> parallel XENMEM_exchange, for example.

How would that work when the mfns are assigned to a different domain? E.g. when I acquire domU's grant table for mapping in dom0, I don't want to take ownership of the mfns... they still belong to the domU.

  Paul

> 
> Jan
Jan Beulich Aug. 29, 2017, 9:38 a.m. UTC | #7
>>> On 29.08.17 at 11:31, <Paul.Durrant@citrix.com> wrote:
>>  -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: 29 August 2017 10:28
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> devel@lists.xenproject.org 
>> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> HYPERVISOR_memory_op to acquire guest resources
>> 
>> >>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
>> >>  -----Original Message-----
>> >> From: Jan Beulich [mailto:JBeulich@suse.com]
>> >> Sent: 29 August 2017 10:00
>> >> To: Paul Durrant <Paul.Durrant@citrix.com>
>> >> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> >> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> >> devel@lists.xenproject.org 
>> >> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> >> HYPERVISOR_memory_op to acquire guest resources
>> >>
>> >> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> >> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> >> >> Sent: 28 August 2017 16:01
>> >> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> >> >> > +
>> >> >> > +/*
>> >> >> > + * Get the pages for a particular guest resource, so that they can be
>> >> >> > + * mapped directly by a tools domain.
>> >> >> > + */
>> >> >> > +#define XENMEM_acquire_resource 28
>> >> >> > +struct xen_mem_acquire_resource {
>> >> >> > +    /* IN - the domain whose resource is to be mapped */
>> >> >> > +    domid_t domid;
>> >> >> > +    /* IN - the type of resource (defined below) */
>> >> >> > +    uint16_t type;
>> >> >> > +
>> >> >> > +#define XENMEM_resource_grant_table 0
>> >> >> > +
>> >> >> > +    /*
>> >> >> > +     * IN - a type-specific resource identifier, which must be zero
>> >> >> > +     *      unless stated otherwise.
>> >> >> > +     */
>> >> >> > +    uint32_t id;
>> >> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> >> >> > +    uint32_t nr_frames;
>> >> >> > +    /* IN - the index of the initial frame to be mapped */
>> >> >> > +    uint64_aligned_t frame;
>> >> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> >> >> > +     *          will be populated with the MFNs of the resource.
>> >> >> > +     *          If the tools domain is HVM then it is expected that, on
>> >> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> >> >> > +     *          that will be mapped to the MFNs of the resource.
>> >> >> > +     */
>> >> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> >> >>
>> >> >> Why is it not possible to make PV does the same thing as HVM?
>> >> >
>> >> > Because PV guests don't use a P2M as such.
>> >>
>> >> They certainly do, just Xen can't rely on (and hence use) it.
>> >
>> > Oh I know they have one but, as you say, Xen can't use it do put resources
>> > at a particular guest location.
>> >
>> >>
>> >> > An HVM guest can pass GFNs in and
>> >> > say 'I want the resource mapped here'. A PV guest can't do that since it's
>> >> > using MFNs directly... it has to deal with the resource wherever it may
>> be.
>> >>
>> >> Xen does, however, maintain the M2P, so it would not be impossible
>> >> to return GFNs here for PV guests, requiring the caller to translate
>> >> them back to MFNs if so desired.
>> >
>> > That's possible, but still different to and HVM caller, which will pass GFNs
>> > in rather than using any values returned. So I don't really see any
>> advantage
>> > in that.
>> 
>> What's wrong with PV passing in PFNs, and Xen installing the
>> resulting translations into the M2P right away (leaving it to the
>> caller to just fix up its P2M)? That would sufficiently
>> parallel XENMEM_exchange, for example.
> 
> How would that work when the mfns are assigned to a different domain? E.g. 
> when I acquire domU's grant table for mapping in dom0, I don't want to take 
> ownership of the mfns... they still belong to the domU.

Oh, right, these are foreign pages.

Jan
George Dunlap Aug. 29, 2017, 11:16 a.m. UTC | #8
On Tue, Aug 22, 2017 at 3:50 PM, Paul Durrant <paul.durrant@citrix.com> wrote:
> Certain memory resources associated with a guest are not necessarily
> present in the guest P2M and so are not necessarily available to be
> foreign-mapped by a tools domain unless they are inserted, which risks
> shattering a super-page mapping.
>
> This patch adds a new memory op to allow such resourced to be priv-mapped
> directly, by either a PV or HVM tools domain.
>
> NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,
>       I have no means to test it on an ARM platform and so cannot verify
>       that it functions correctly. Hence it is currently only implemented
>       for x86.
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

p2m bits:
Acked-by: George Dunlap <george.dunlap@citrix.com>

You can retain that ack if the p2m.[ch] parts of the patch remain
substantially the same.
Paul Durrant Aug. 29, 2017, 11:19 a.m. UTC | #9
> -----Original Message-----

> From: dunlapg@gmail.com [mailto:dunlapg@gmail.com] On Behalf Of

> George Dunlap

> Sent: 29 August 2017 12:16

> To: Paul Durrant <Paul.Durrant@citrix.com>

> Cc: xen-devel <xen-devel@lists.xenproject.org>; Andrew Cooper

> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>

> Subject: Re: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add

> HYPERVISOR_memory_op to acquire guest resources

> 

> On Tue, Aug 22, 2017 at 3:50 PM, Paul Durrant <paul.durrant@citrix.com>

> wrote:

> > Certain memory resources associated with a guest are not necessarily

> > present in the guest P2M and so are not necessarily available to be

> > foreign-mapped by a tools domain unless they are inserted, which risks

> > shattering a super-page mapping.

> >

> > This patch adds a new memory op to allow such resourced to be priv-

> mapped

> > directly, by either a PV or HVM tools domain.

> >

> > NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,

> >       I have no means to test it on an ARM platform and so cannot verify

> >       that it functions correctly. Hence it is currently only implemented

> >       for x86.

> >

> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

> 

> p2m bits:

> Acked-by: George Dunlap <george.dunlap@citrix.com>

> 

> You can retain that ack if the p2m.[ch] parts of the patch remain

> substantially the same.


Ok, thanks :-)

  Paul
diff mbox

Patch

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index aaa9ff5197..4e86f0a2ab 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4717,6 +4717,107 @@  int xenmem_add_to_physmap_one(
     return rc;
 }
 
+static int xenmem_acquire_grant_table(struct domain *d,
+                                      unsigned long frame,
+                                      unsigned long nr_frames,
+                                      unsigned long mfn_list[])
+{
+    unsigned int i;
+
+    /*
+     * Iterate through the list backwards so that gnttab_get_frame() is
+     * first called for the highest numbered frame. This means that the
+     * out-of-bounds check will be done on the first iteration and, if
+     * the table needs to grow, it will only grow once.
+     */
+    i = nr_frames;
+    while ( i-- != 0 )
+    {
+        mfn_t mfn = gnttab_get_frame(d, frame + i);
+
+        if ( mfn_eq(mfn, INVALID_MFN) )
+            return -EINVAL;
+
+        mfn_list[i] = mfn_x(mfn);
+    }
+
+    return 0;
+}
+
+static int xenmem_acquire_resource(xen_mem_acquire_resource_t *xmar)
+{
+    struct domain *d, *currd = current->domain;
+    unsigned long *mfn_list;
+    int rc;
+
+    if ( xmar->nr_frames == 0 )
+        return -EINVAL;
+
+    d = rcu_lock_domain_by_any_id(xmar->domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    rc = xsm_domain_memory_map(XSM_TARGET, d);
+    if ( rc )
+        goto out;
+
+    mfn_list = xmalloc_array(unsigned long, xmar->nr_frames);
+
+    rc = -ENOMEM;
+    if ( !mfn_list )
+        goto out;
+
+    switch ( xmar->type )
+    {
+    case XENMEM_resource_grant_table:
+        rc = -EINVAL;
+        if ( xmar->id ) /* must be zero for grant_table */
+            break;
+
+        rc = xenmem_acquire_grant_table(d, xmar->frame, xmar->nr_frames,
+                                        mfn_list);
+        break;
+
+    default:
+        rc = -EOPNOTSUPP;
+        break;
+    }
+
+    if ( rc )
+        goto free_and_out;
+
+    if ( !paging_mode_translate(currd) )
+    {
+        if ( __copy_to_guest_offset(xmar->gmfn_list, 0, mfn_list,
+                                    xmar->nr_frames) )
+            rc = -EFAULT;
+    }
+    else
+    {
+        unsigned int i;
+
+        for ( i = 0; i < xmar->nr_frames; i++ )
+        {
+            xen_pfn_t gfn;
+
+            rc = -EFAULT;
+            if ( __copy_from_guest_offset(&gfn, xmar->gmfn_list, i, 1) )
+                goto free_and_out;
+
+            rc = set_foreign_p2m_entry(currd, gfn, _mfn(mfn_list[i]));
+            if ( rc )
+                goto free_and_out;
+        }
+    }
+
+ free_and_out:
+    xfree(mfn_list);
+
+ out:
+    rcu_unlock_domain(d);
+    return rc;
+}
+
 long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
     int rc;
@@ -4939,6 +5040,16 @@  long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         return rc;
     }
 
+    case XENMEM_acquire_resource:
+    {
+        xen_mem_acquire_resource_t xmar;
+
+        if ( copy_from_guest(&xmar, arg, 1) )
+            return -EFAULT;
+
+        return xenmem_acquire_resource(&xmar);
+    }
+
     default:
         return subarch_memory_op(cmd, arg);
     }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index e8a57d118c..c503a7f1d2 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1118,8 +1118,7 @@  static int set_typed_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
 }
 
 /* Set foreign mfn in the given guest's p2m table. */
-static int set_foreign_p2m_entry(struct domain *d, unsigned long gfn,
-                                 mfn_t mfn)
+int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 {
     return set_typed_p2m_entry(d, gfn, mfn, PAGE_ORDER_4K, p2m_map_foreign,
                                p2m_get_hostp2m(d)->default_access);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 6395e8fd1d..3ccec250d8 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -613,6 +613,9 @@  void p2m_memory_type_changed(struct domain *d);
 int p2m_is_logdirty_range(struct p2m_domain *, unsigned long start,
                           unsigned long end);
 
+/* Set foreign entry in the p2m table (for priv-mapping) */
+int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
+
 /* Set mmio addresses in the p2m table (for pass-through) */
 int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
                        unsigned int order, p2m_access_t access);
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 29386df98b..9bf58e7384 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -650,7 +650,43 @@  struct xen_vnuma_topology_info {
 typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t;
 DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t);
 
-/* Next available subop number is 28 */
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+/*
+ * Get the pages for a particular guest resource, so that they can be
+ * mapped directly by a tools domain.
+ */
+#define XENMEM_acquire_resource 28
+struct xen_mem_acquire_resource {
+    /* IN - the domain whose resource is to be mapped */
+    domid_t domid;
+    /* IN - the type of resource (defined below) */
+    uint16_t type;
+
+#define XENMEM_resource_grant_table 0
+
+    /*
+     * IN - a type-specific resource identifier, which must be zero
+     *      unless stated otherwise.
+     */
+    uint32_t id;
+    /* IN - number of (4K) frames of the resource to be mapped */
+    uint32_t nr_frames;
+    /* IN - the index of the initial frame to be mapped */
+    uint64_aligned_t frame;
+    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
+     *          will be populated with the MFNs of the resource.
+     *          If the tools domain is HVM then it is expected that, on
+     *          entry, gmfn_list will be populated with a list of GFNs
+     *          that will be mapped to the MFNs of the resource.
+     */
+    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
+};
+typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t;
+
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
+/* Next available subop number is 29 */
 
 #endif /* __XEN_PUBLIC_MEMORY_H__ */