All of lore.kernel.org
 help / color / mirror / Atom feed
* [hybrid]: code review for function mapping pfn to foreign mfn
@ 2012-04-14  1:29 Mukesh Rathor
  2012-04-16 13:53 ` Ian Campbell
  2012-04-19 14:15 ` Tim Deegan
  0 siblings, 2 replies; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-14  1:29 UTC (permalink / raw)
  To: Xen-devel, Ian Campbell, stefano.stabellini, Keir Fraser

Hi,

I wrote up some code to map/unmap pfn to mfn for hybrid. I wonder if anyone
can please look at it and give any comments. I tested it and seems to work
ok.

Basically, the library, xl running in hybrid dom0, needs to map domU pages
during guest creation. I tried using existing add to physmap, mmu_update,
but nothing was feasible. So wrote this. Its called from
privcmd_ioctl_mmap_batch().

thanks,
Mukesh


/* add frames from foreign domain to current domain physmap. Similar to 
 * XENMEM_add_to_physmap but the mfn frame is foreign, is being mapped into 
 * current privileged domain, and is not removed from foreign domain. 
 * Usage: libxl when creating guest in hybrid dom0 doing privcmd_ioctl_mmap
 * Return: 0 success
 */
static long _add_foreign_to_pmap_batch(XEN_GUEST_HANDLE(void) arg)
{
    struct xen_add_to_foreign_pmap_batch pmapb;
    unsigned long rc=0, i, prev_mfn, mfn = 0;
    struct domain *fdom, *currd = current->domain;
    p2m_type_t p2mt;

    if ( copy_from_guest(&pmapb, arg, 1) )
        return -EFAULT;

    fdom = get_pg_owner(pmapb.foreign_domid);

    if ( fdom== NULL ) {
        put_pg_owner(fdom);
        return -EPERM;
    }

    for (i=0; (rc == 0) && (i < pmapb.count); i++) {
        unsigned long fgmfn = pmapb.gmfn+i, gpfn = pmapb.gpfn+i;
        mfn = mfn_x(gfn_to_mfn_query(p2m_get_hostp2m(fdom), fgmfn, &p2mt));
	if ( !p2m_is_valid(p2mt) )
            rc = -EINVAL;

        if ( !rc && !get_page_from_pagenr(mfn, fdom) )
            rc = -EPERM;

        if (!rc) 
            put_page(mfn_to_page(mfn));
        else 
            break;

        /* Remove previously mapped page if it was present. */
        prev_mfn = gmfn_to_mfn(currd, gpfn);
        if ( mfn_valid(prev_mfn) )
        {
            if ( is_xen_heap_mfn(prev_mfn) )
                /* Xen heap frames are simply unhooked from this phys slot */
                guest_physmap_remove_page(currd, gpfn, prev_mfn, 0);
            else
                /* Normal domain memory is freed, to avoid leaking memory. */
                guest_remove_page(currd, gpfn);
        }
        /* Map at new location. */
	/* Can't use guest_physmap_add_page() because it will update the m2p
	 * table so mfn ---> gpfn in dom0 and not gpfn of domU.
	 */
        /* rc = guest_physmap_add_page(currd, gpfn, mfn, 0); */

	rc = set_mmio_p2m_entry(p2m_get_hostp2m(currd), gpfn, mfn);
        if (rc==0) {
            printk("guest_physmap_add_page failed.gpfn:%lx mfn:%lx fgmfn:%lx\n",
                   gpfn, mfn, fgmfn);
            rc == -EINVAL;
        } else 
            rc = 0;
    }

    pmapb.count = i;
    copy_to_guest(arg, &pmapb, 1);
    put_pg_owner(fdom);
    return rc;
}

static long noinline _rem_foreign_pmap_batch(XEN_GUEST_HANDLE(void) arg)
{
    xen_pfn_t gmfn;
    struct xen_rem_foreign_pmap_batch pmapb;
    p2m_type_t p2mt;
    int i, rc=0;
    struct domain *currd = current->domain;

    if ( copy_from_guest(&pmapb, arg, 1) )
        return -EFAULT;

    for ( gmfn=pmapb.s_gpfn, i=0;  i < pmapb.count;  i++, gmfn++ ) {

        mfn_t mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(currd), gmfn, &p2mt));
        if ( unlikely(!mfn_valid(mfn)) )
        {
            gdprintk(XENLOG_INFO, "%s: Domain:%u gmfn:%lx invalid\n",
                     __FUNCTION__, currd->domain_id, gmfn);
            rc = -EINVAL;
            break;
        }
        /* guest_physmap_remove_page(currd, gmfn, mfn, 0); */
	clear_mmio_p2m_entry(p2m_get_hostp2m(currd), gmfn);
    }
    pmapb.count = i;
    copy_to_guest(arg, &pmapb, 1);
    return rc;
}

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-14  1:29 [hybrid]: code review for function mapping pfn to foreign mfn Mukesh Rathor
@ 2012-04-16 13:53 ` Ian Campbell
  2012-04-16 14:02   ` Tim Deegan
  2012-04-17  1:53   ` Mukesh Rathor
  2012-04-19 14:15 ` Tim Deegan
  1 sibling, 2 replies; 17+ messages in thread
From: Ian Campbell @ 2012-04-16 13:53 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Xen-devel, Tim Deegan, Keir Fraser, Stefano Stabellini

On Sat, 2012-04-14 at 02:29 +0100, Mukesh Rathor wrote:
> Hi,
> 
> I wrote up some code to map/unmap pfn to mfn for hybrid. I wonder if anyone
> can please look at it and give any comments. I tested it and seems to work
> ok.

I'm not all that familiar with x86 p2m stuff but I'll try. (I've also
added Tim, who is familiar with this stuff)

> Basically, the library, xl running in hybrid dom0, needs to map domU pages
> during guest creation. I tried using existing add to physmap, mmu_update,
> but nothing was feasible. So wrote this. Its called from
> privcmd_ioctl_mmap_batch().
> 
> thanks,
> Mukesh
> 
> 
> /* add frames from foreign domain to current domain physmap. Similar to 
>  * XENMEM_add_to_physmap

Why a whole new hypercall rather than a new XENMAPSPACE for the exiting
XENMEM_add_to_physmap.

>  but the mfn frame is foreign, is being mapped into 
>  * current privileged domain, and is not removed from foreign domain. 
>  * Usage: libxl when creating guest in hybrid dom0 doing privcmd_ioctl_mmap
>  * Return: 0 success
>  */
> static long _add_foreign_to_pmap_batch(XEN_GUEST_HANDLE(void) arg)
> {
>     struct xen_add_to_foreign_pmap_batch pmapb;

Ideally we'd have the definition of this (or the equivalent mod to the
XENMEM_add_to_physmap associated struct) for context, but I can probably
guess what the content looks like.

>     unsigned long rc=0, i, prev_mfn, mfn = 0;
>     struct domain *fdom, *currd = current->domain;
>     p2m_type_t p2mt;
> 
>     if ( copy_from_guest(&pmapb, arg, 1) )
>         return -EFAULT;
> 
>     fdom = get_pg_owner(pmapb.foreign_domid);
> 
>     if ( fdom== NULL ) {
>         put_pg_owner(fdom);
>         return -EPERM;
>     }
> 
>     for (i=0; (rc == 0) && (i < pmapb.count); i++) {
>         unsigned long fgmfn = pmapb.gmfn+i, gpfn = pmapb.gpfn+i;
>         mfn = mfn_x(gfn_to_mfn_query(p2m_get_hostp2m(fdom), fgmfn, &p2mt));

I don't see gfn_to_mfn_query anywhere, I presume it's just a pretty
straight forward p2m lookup? Surprised there is no existing API but OK.

> 	if ( !p2m_is_valid(p2mt) )
>             rc = -EINVAL;
> 
>         if ( !rc && !get_page_from_pagenr(mfn, fdom) )
>             rc = -EPERM;
> 
>         if (!rc) 
>             put_page(mfn_to_page(mfn));
>         else 
>             break;
> 
>         /* Remove previously mapped page if it was present. */
>         prev_mfn = gmfn_to_mfn(currd, gpfn);
>         if ( mfn_valid(prev_mfn) )
>         {
>             if ( is_xen_heap_mfn(prev_mfn) )
>                 /* Xen heap frames are simply unhooked from this phys slot */
>                 guest_physmap_remove_page(currd, gpfn, prev_mfn, 0);
>             else
>                 /* Normal domain memory is freed, to avoid leaking memory. */
>                 guest_remove_page(currd, gpfn);

Do you mean "unrefd" here rather than freed? Presumably the remote
domain (which owns the page) is still using it?

>         }
>         /* Map at new location. */
> 	/* Can't use guest_physmap_add_page() because it will update the m2p
> 	 * table so mfn ---> gpfn in dom0 and not gpfn of domU.
> 	 */
>         /* rc = guest_physmap_add_page(currd, gpfn, mfn, 0); */
> 
> 	rc = set_mmio_p2m_entry(p2m_get_hostp2m(currd), gpfn, mfn);

This ends up setting the page type to p2m_mmio_direct, which doesn't
seem likely to be correct. Perhaps you should be calling
set_p2m_entry()? Or adding a set_ram_p2m_entry which does similar checks
etc to set_mmio_p2m_entry (or maybe you could abstract out some generic
bits there)?

>         if (rc==0) {
>             printk("guest_physmap_add_page failed.gpfn:%lx mfn:%lx fgmfn:%lx\n",
>                    gpfn, mfn, fgmfn);
>             rc == -EINVAL;
>         } else 
>             rc = 0;
>     }
> 
>     pmapb.count = i;
>     copy_to_guest(arg, &pmapb, 1);
>     put_pg_owner(fdom);
>     return rc;
> }
> 
> static long noinline _rem_foreign_pmap_batch(XEN_GUEST_HANDLE(void) arg)

Can't XENMEM_remove_from_physmap be used here?

> {
>     xen_pfn_t gmfn;
>     struct xen_rem_foreign_pmap_batch pmapb;
>     p2m_type_t p2mt;
>     int i, rc=0;
>     struct domain *currd = current->domain;
> 
>     if ( copy_from_guest(&pmapb, arg, 1) )
>         return -EFAULT;
> 
>     for ( gmfn=pmapb.s_gpfn, i=0;  i < pmapb.count;  i++, gmfn++ ) {
> 
>         mfn_t mfn = mfn_x(gfn_to_mfn(p2m_get_hostp2m(currd), gmfn, &p2mt));
>         if ( unlikely(!mfn_valid(mfn)) )
>         {
>             gdprintk(XENLOG_INFO, "%s: Domain:%u gmfn:%lx invalid\n",
>                      __FUNCTION__, currd->domain_id, gmfn);
>             rc = -EINVAL;
>             break;
>         }
>         /* guest_physmap_remove_page(currd, gmfn, mfn, 0); */
> 	clear_mmio_p2m_entry(p2m_get_hostp2m(currd), gmfn);
>     }
>     pmapb.count = i;
>     copy_to_guest(arg, &pmapb, 1);
>     return rc;
> }
> 

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-16 13:53 ` Ian Campbell
@ 2012-04-16 14:02   ` Tim Deegan
  2012-04-17  1:53   ` Mukesh Rathor
  1 sibling, 0 replies; 17+ messages in thread
From: Tim Deegan @ 2012-04-16 14:02 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen-devel, Keir Fraser, Stefano Stabellini

At 14:53 +0100 on 16 Apr (1334588002), Ian Campbell wrote:
> On Sat, 2012-04-14 at 02:29 +0100, Mukesh Rathor wrote:
> > Hi,
> > 
> > I wrote up some code to map/unmap pfn to mfn for hybrid. I wonder if anyone
> > can please look at it and give any comments. I tested it and seems to work
> > ok.
> 
> I'm not all that familiar with x86 p2m stuff but I'll try. (I've also
> added Tim, who is familiar with this stuff)

This is on my todo list for later this week. 

> >     for (i=0; (rc == 0) && (i < pmapb.count); i++) {
> >         unsigned long fgmfn = pmapb.gmfn+i, gpfn = pmapb.gpfn+i;
> >         mfn = mfn_x(gfn_to_mfn_query(p2m_get_hostp2m(fdom), fgmfn, &p2mt));
> 
> I don't see gfn_to_mfn_query anywhere, I presume it's just a pretty
> straight forward p2m lookup? Surprised there is no existing API but OK.

Yes, it's a lookup with no PoD/paging/sharing side-effects.
gfn_to_mfn_*() have been replaced by get_gfn()/put_gfn(), so at the
very least this will have to be rebased across that change.

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-16 13:53 ` Ian Campbell
  2012-04-16 14:02   ` Tim Deegan
@ 2012-04-17  1:53   ` Mukesh Rathor
  2012-04-17  9:05     ` Ian Campbell
  1 sibling, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-17  1:53 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen-devel, Tim Deegan, Keir Fraser, Stefano Stabellini

On Mon, 16 Apr 2012 14:53:22 +0100
Ian Campbell <Ian.Campbell@citrix.com> wrote:

> > Similar to 
> >  * XENMEM_add_to_physmap
> 
> Why a whole new hypercall rather than a new XENMAPSPACE for the
> exiting XENMEM_add_to_physmap.

> Ideally we'd have the definition of this (or the equivalent mod to the
> XENMEM_add_to_physmap associated struct) for context, but I can
> probably guess what the content looks like.

Not a new hcall, just a new subcall. Forgot to include the struct:

#define XENMEM_add_foreign_to_pmap_batch      19
struct xen_add_to_foreign_pmap_batch {
    domid_t foreign_domid;         /* IN: gmfn belongs to this domain */
    int count;                     /* IN/OUT: number of contigous
frames */ unsigned long     gpfn;        /* IN: pfn in the current
domain */ unsigned long     gmfn;        /* IN: from foreign domain */
    int fpmap_flags;               /* future use */
};
typedef struct xen_add_to_foreign_pmap_batch
xen_add_to_foreign_pmap_batch_t;
DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_foreign_pmap_batch_t);


> > 	rc = set_mmio_p2m_entry(p2m_get_hostp2m(currd), gpfn, mfn);
> 
> This ends up setting the page type to p2m_mmio_direct, which doesn't
> seem likely to be correct. Perhaps you should be calling
> set_p2m_entry()? Or adding a set_ram_p2m_entry which does similar
> checks etc to set_mmio_p2m_entry (or maybe you could abstract out
> some generic bits there)?

well, set_mmio_p2m_entry() calls set_p2m_entry() with a couple checks.
I can add those to my function and just call set_p2m_entry too. It says
mmio, but doesn't seem to do anything mmio specific. 

thanks,
Mukesh

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-17  1:53   ` Mukesh Rathor
@ 2012-04-17  9:05     ` Ian Campbell
  2012-04-18 23:29       ` Mukesh Rathor
  0 siblings, 1 reply; 17+ messages in thread
From: Ian Campbell @ 2012-04-17  9:05 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Xen-devel, Tim (Xen.org), Keir Fraser, Stefano Stabellini

On Tue, 2012-04-17 at 02:53 +0100, Mukesh Rathor wrote:
> On Mon, 16 Apr 2012 14:53:22 +0100
> Ian Campbell <Ian.Campbell@citrix.com> wrote:
> 
> > > Similar to 
> > >  * XENMEM_add_to_physmap
> > 
> > Why a whole new hypercall rather than a new XENMAPSPACE for the
> > exiting XENMEM_add_to_physmap.
> 
> > Ideally we'd have the definition of this (or the equivalent mod to the
> > XENMEM_add_to_physmap associated struct) for context, but I can
> > probably guess what the content looks like.
> 
> Not a new hcall, just a new subcall.

Sorry, I meant why a whole new subcall instead of a new XENMAPSPACE ;-)

e.g. On ARM I did:

diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 86d02c8..b2adfbe 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -212,11 +212,13 @@ struct xen_add_to_physmap {
     uint16_t    size;
 
     /* Source mapping space. */
-#define XENMAPSPACE_shared_info 0 /* shared info page */
-#define XENMAPSPACE_grant_table 1 /* grant table page */
-#define XENMAPSPACE_gmfn        2 /* GMFN */
-#define XENMAPSPACE_gmfn_range  3 /* GMFN range */
-    unsigned int space;
+#define XENMAPSPACE_shared_info  0 /* shared info page */
+#define XENMAPSPACE_grant_table  1 /* grant table page */
+#define XENMAPSPACE_gmfn         2 /* GMFN */
+#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
+#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
+    uint16_t space;
+    domid_t foreign_domid; /* IFF gmfn_foreign */
 
 #define XENMAPIDX_grant_table_status 0x80000000
 

Effectively stealing the (currently always zero) top 16 bits of the
space member for the foreign domid.


>  Forgot to include the struct:
> 
> #define XENMEM_add_foreign_to_pmap_batch      19
> struct xen_add_to_foreign_pmap_batch {
>     domid_t foreign_domid;         /* IN: gmfn belongs to this domain */
>     int count;                     /* IN/OUT: number of contigous
> frames */ unsigned long     gpfn;        /* IN: pfn in the current
> domain */ unsigned long     gmfn;        /* IN: from foreign domain */
>     int fpmap_flags;               /* future use */
> };
> typedef struct xen_add_to_foreign_pmap_batch
> xen_add_to_foreign_pmap_batch_t;
> DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_foreign_pmap_batch_t);
> 
> 
> > > 	rc = set_mmio_p2m_entry(p2m_get_hostp2m(currd), gpfn, mfn);
> > 
> > This ends up setting the page type to p2m_mmio_direct, which doesn't
> > seem likely to be correct. Perhaps you should be calling
> > set_p2m_entry()? Or adding a set_ram_p2m_entry which does similar
> > checks etc to set_mmio_p2m_entry (or maybe you could abstract out
> > some generic bits there)?
> 
> well, set_mmio_p2m_entry() calls set_p2m_entry() with a couple checks.
> I can add those to my function and just call set_p2m_entry too. It says
> mmio, but doesn't seem to do anything mmio specific. 

If that's the case perhaps you could rename it and add the type as a
parameter?

If not then I wouldn't add those checks to your function -- create a new
wrapper (set_ram_p2m_entry or whatever) with the checks.

Ian.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-17  9:05     ` Ian Campbell
@ 2012-04-18 23:29       ` Mukesh Rathor
  2012-04-19  7:22         ` Ian Campbell
  0 siblings, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-18 23:29 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen-devel, Tim (Xen.org), Keir Fraser, Stefano Stabellini

On Tue, 17 Apr 2012 10:05:28 +0100
Ian Campbell <Ian.Campbell@citrix.com> wrote:

> On Tue, 2012-04-17 at 02:53 +0100, Mukesh Rathor wrote:
> > On Mon, 16 Apr 2012 14:53:22 +0100
> > Ian Campbell <Ian.Campbell@citrix.com> wrote:
> 
> Sorry, I meant why a whole new subcall instead of a new
> XENMAPSPACE ;-)
> 
> e.g. On ARM I did:
> 
> diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
> index 86d02c8..b2adfbe 100644
> --- a/xen/include/public/memory.h
> +++ b/xen/include/public/memory.h
> @@ -212,11 +212,13 @@ struct xen_add_to_physmap {
>      uint16_t    size;
>  
>      /* Source mapping space. */
> -#define XENMAPSPACE_shared_info 0 /* shared info page */
> -#define XENMAPSPACE_grant_table 1 /* grant table page */
> -#define XENMAPSPACE_gmfn        2 /* GMFN */
> -#define XENMAPSPACE_gmfn_range  3 /* GMFN range */
> -    unsigned int space;
> +#define XENMAPSPACE_shared_info  0 /* shared info page */
> +#define XENMAPSPACE_grant_table  1 /* grant table page */
> +#define XENMAPSPACE_gmfn         2 /* GMFN */
> +#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
> +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
> +    uint16_t space;
> +    domid_t foreign_domid; /* IFF gmfn_foreign */


Well, for several reasons, I didn't use it, mainly, it doesn't allow
for count. So requests have to come in one frame at a time. Second,
none of the common code can be used by my new request, because:
   - frame is not removed from foreign domain in my case
   - i don't want to update the m2p with new info.

Anyways, I put it there for now. With ballooning change in dom0, I'm
now doing the hcall one frame at a time anyways. We can always enhance
in the future.

        case XENMAPSPACE_gmfn_foreign:
        {
            rc = _add_foreign_to_pmap_batch(&xatp);
            rcu_unlock_domain(d);
            return rc;
        }


>> static long noinline _rem_foreign_pmap_batch(XEN_GUEST_HANDLE(void)
>> arg)  

>Can't XENMEM_remove_from_physmap be used here?

Well, that calls guest_physmap_remove_page() which calls
p2m_remove_page which updates the M2P with INVALID_M2P_ENTRY. Whereas,
i just need to remove from the dom0 p2m and leave M2P as is (mfn to
domU gmfn). I could add a flag to the struct causing it to just call
set_p2m_entry() directly?

thanks,
Mukesh

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-18 23:29       ` Mukesh Rathor
@ 2012-04-19  7:22         ` Ian Campbell
  0 siblings, 0 replies; 17+ messages in thread
From: Ian Campbell @ 2012-04-19  7:22 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Xen-devel, Tim (Xen.org), Keir Fraser, Stefano Stabellini

On Thu, 2012-04-19 at 00:29 +0100, Mukesh Rathor wrote:
> On Tue, 17 Apr 2012 10:05:28 +0100
> Ian Campbell <Ian.Campbell@citrix.com> wrote:
> 
> > On Tue, 2012-04-17 at 02:53 +0100, Mukesh Rathor wrote:
> > > On Mon, 16 Apr 2012 14:53:22 +0100
> > > Ian Campbell <Ian.Campbell@citrix.com> wrote:
> > 
> > Sorry, I meant why a whole new subcall instead of a new
> > XENMAPSPACE ;-)
> > 
> > e.g. On ARM I did:
> > 
> > diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
> > index 86d02c8..b2adfbe 100644
> > --- a/xen/include/public/memory.h
> > +++ b/xen/include/public/memory.h
> > @@ -212,11 +212,13 @@ struct xen_add_to_physmap {
> >      uint16_t    size;
> >  
> >      /* Source mapping space. */
> > -#define XENMAPSPACE_shared_info 0 /* shared info page */
> > -#define XENMAPSPACE_grant_table 1 /* grant table page */
> > -#define XENMAPSPACE_gmfn        2 /* GMFN */
> > -#define XENMAPSPACE_gmfn_range  3 /* GMFN range */
> > -    unsigned int space;
> > +#define XENMAPSPACE_shared_info  0 /* shared info page */
> > +#define XENMAPSPACE_grant_table  1 /* grant table page */
> > +#define XENMAPSPACE_gmfn         2 /* GMFN */
> > +#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
> > +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
> > +    uint16_t space;
> > +    domid_t foreign_domid; /* IFF gmfn_foreign */
> 
> 
> Well, for several reasons, I didn't use it, mainly, it doesn't allow
> for count. So requests have to come in one frame at a time.

I've got it that way on ARM too at the moment but I was planning to make
it behave like gmfn_range and use the size parameter to map multiple at
a time (unless I've misunderstood what the gmfn_range variant does).

>  Second, none of the common code can be used by my new request,

I don't think that's an impediment to the API, XENMAPSPACE_gmfn_foreign
is in pretty much the same position.

>  because:
>    - frame is not removed from foreign domain in my case
>    - i don't want to update the m2p with new info.
> 
> Anyways, I put it there for now. With ballooning change in dom0, I'm
> now doing the hcall one frame at a time anyways. We can always enhance
> in the future.
> 
>         case XENMAPSPACE_gmfn_foreign:
>         {
>             rc = _add_foreign_to_pmap_batch(&xatp);
>             rcu_unlock_domain(d);
>             return rc;
>         }
> 
> 
> >> static long noinline _rem_foreign_pmap_batch(XEN_GUEST_HANDLE(void)
> >> arg)  
> 
> >Can't XENMEM_remove_from_physmap be used here?
> 
> Well, that calls guest_physmap_remove_page() which calls
> p2m_remove_page which updates the M2P with INVALID_M2P_ENTRY. Whereas,
> i just need to remove from the dom0 p2m and leave M2P as is (mfn to
> domU gmfn). I could add a flag to the struct causing it to just call
> set_p2m_entry() directly?

Would it be useful to track the fact that a p2m entry is foreign
somewhere? That would let you do the appropriate type of teardown etc
without relying on the tools to get it right.

Are there s/w bits available in the p2m entry itself on x86 or do we use
them all already?

Ian.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-14  1:29 [hybrid]: code review for function mapping pfn to foreign mfn Mukesh Rathor
  2012-04-16 13:53 ` Ian Campbell
@ 2012-04-19 14:15 ` Tim Deegan
  2012-04-24  1:37   ` Mukesh Rathor
  1 sibling, 1 reply; 17+ messages in thread
From: Tim Deegan @ 2012-04-19 14:15 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Keir Fraser, Xen-devel, Ian Campbell, stefano.stabellini

Hi, 

At 18:29 -0700 on 13 Apr (1334341792), Mukesh Rathor wrote:
> I wrote up some code to map/unmap pfn to mfn for hybrid. I wonder if anyone
> can please look at it and give any comments. I tested it and seems to work
> ok.

I agree with what Ian's already said about this.  In particular: 

 - This should use the existing XENMEM_add_to_physmap interface rather
   than having a new operation.
 - AFAICT you're using set_mmio_p2m_entry and adding a new unmap
   operation just to avoid having the m2p updated.  Since you can't rely
   on the unmap always happening through the new call (and you don't
   enforce it anywhere), it would be better to add a new p2m_type
   just for non-grant foreign mappings.  Then you can gate the m2p
   updates in the existing code on the map being normal RAM, as is
   already done for p2m_is_grant().

Apart from that: 

> struct xen_add_to_foreign_pmap_batch {
>     domid_t foreign_domid;         /* IN: gmfn belongs to this domain */
>     int count;                     /* IN/OUT: number of contigous frames */

Please only add explicitly-sized fields to the public interface.  
(I understand that there's currently no call for a compat VM to make
this call, but even so).

>     unsigned long     gpfn;        /* IN: pfn in the current domain */
>     unsigned long     gmfn;        /* IN: from foreign domain */
>     int fpmap_flags;               /* future use */
> };


> /* add frames from foreign domain to current domain physmap. Similar to 
>  * XENMEM_add_to_physmap but the mfn frame is foreign, is being mapped into 
>  * current privileged domain, and is not removed from foreign domain. 
>  * Usage: libxl when creating guest in hybrid dom0 doing privcmd_ioctl_mmap
>  * Return: 0 success
>  */
> static long _add_foreign_to_pmap_batch(XEN_GUEST_HANDLE(void) arg)
> {
>     struct xen_add_to_foreign_pmap_batch pmapb;
>     unsigned long rc=0, i, prev_mfn, mfn = 0;
>     struct domain *fdom, *currd = current->domain;
>     p2m_type_t p2mt;
> 
>     if ( copy_from_guest(&pmapb, arg, 1) )
>         return -EFAULT;
> 
>     fdom = get_pg_owner(pmapb.foreign_domid);
> 
>     if ( fdom== NULL ) {
>         put_pg_owner(fdom);

Best not, if it's NULL. :)

>         return -EPERM;
>     }
> 
>     for (i=0; (rc == 0) && (i < pmapb.count); i++) {

This loop could do nearly 2^31 iterations; it needs to have a preemption
check to stop it locking up the hypervisor.  (If you switch to using
XENMEM_add_to_physmap, you'll get this for free.)

Also, I understand this is early code, but it will eventually have to
follow the coding style about whitespace.  There are hard tabs in a few
places below as well.  Can you train your text editor not to do that?

>         unsigned long fgmfn = pmapb.gmfn+i, gpfn = pmapb.gpfn+i;
>         mfn = mfn_x(gfn_to_mfn_query(p2m_get_hostp2m(fdom), fgmfn, &p2mt));

This will need to use the new get_gfn()/put_gfn() interfaces.

> 	if ( !p2m_is_valid(p2mt) )
>             rc = -EINVAL;
> 
>         if ( !rc && !get_page_from_pagenr(mfn, fdom) )
>             rc = -EPERM;
> 
>         if (!rc) 
>             put_page(mfn_to_page(mfn));
>         else 
>             break;

That's a particularly confusing way of putting it.  Also, you'll need to
keep a reference to the foreign page until this mapping goes away;
otherwise the foreign domain could die and its memory be reused while
you still have this mapping.  You should take a PGT_writeable_page
typecount, too, if the foreign domain isn't in paging_mode_external
(like how get_page_from_l1e does for PV mappings).

Cheers,

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-19 14:15 ` Tim Deegan
@ 2012-04-24  1:37   ` Mukesh Rathor
  2012-04-24  9:36     ` Tim Deegan
  0 siblings, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-24  1:37 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Keir Fraser, Xen-devel, Ian Campbell, stefano.stabellini

On Thu, 19 Apr 2012 15:15:27 +0100
Tim Deegan <tim@xen.org> wrote:

> At 18:29 -0700 on 13 Apr (1334341792), Mukesh Rathor wrote:
>  - AFAICT you're using set_mmio_p2m_entry and adding a new unmap
>    operation just to avoid having the m2p updated.  Since you can't
> rely on the unmap always happening through the new call (and you don't
>    enforce it anywhere), it would be better to add a new p2m_type
>    just for non-grant foreign mappings.  Then you can gate the m2p
>    updates in the existing code on the map being normal RAM, as is
>    already done for p2m_is_grant().
 
Hi Tim,

The variants of get_page* are confusing me, so wanna double check with 
you.  I should be able to do something like following, right?


/* add frames from foreign domain to current domain physmap. Similar to 
 * XENMEM_add_to_physmap but the frame is foreign being mapped into current,
 * and is not removed from foreign domain.  */
static long noinline _add_foreign_to_pmap_batch(struct xen_add_to_physmap *xpmp)
{
    unsigned long rc, prev_mfn, mfn = 0;
    struct domain *fdom, *currd = current->domain;
    unsigned long fgmfn = xpmp->idx, gpfn = xpmp->gpfn;
    p2m_type_t p2mt;

    if ( (fdom = get_pg_owner(xpmp->foreign_domid)) == NULL ) {
        return -EPERM;
    }

    mfn = mfn_x(gfn_to_mfn_query(p2m_get_hostp2m(fdom), fgmfn, &p2mt));
    if ( !p2m_is_valid(p2mt) ) {
        put_pg_owner(fdom);
        return -EINVAL;
    }
    if ( (rc=get_page_and_type_from_pagenr(mfn, PGT_writable_page,fdom,0,0)) ) {
        put_pg_owner(fdom);
        return rc;
    }

    /* Remove previously mapped page if it was present. */
    prev_mfn = gmfn_to_mfn(currd, gpfn);
    if ( mfn_valid(prev_mfn) )
    {
        if ( is_xen_heap_mfn(prev_mfn) )
            /* Xen heap frames are simply unhooked from this phys slot */
            guest_physmap_remove_page(currd, gpfn, prev_mfn, 0);
        else
            /* Normal domain memory is freed, to avoid leaking memory. */
            guest_remove_page(currd, gpfn);
    }
    
    if (set_foreign_p2m_entry(p2m_get_hostp2m(currd), gpfn, mfn) == 0) {
        printk("guest_physmap_add_page failed. gpfn:%lx mfn:%lx fgmfn:%lx\n", 
             gpfn, mfn, fgmfn);
        rc = -EINVAL;      ??????????????
    }

    put_pg_owner(fdom);
    return rc;
}

/* Returns: True for success. 0 for failure */
int
set_foreign_p2m_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn)
{
    int rc = 0;
    p2m_type_t ot;
    mfn_t omfn;

    if ( !paging_mode_translate(p2m->domain) )
        return 0;

    omfn = gfn_to_mfn_query(p2m, gfn, &ot);
    if (mfn_valid(omfn)) {
        gdprintk(XENLOG_ERR, "Already mapped mfn %lx at gfn:%lx\n", omfn, gfn);
        set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
    }

    P2M_DEBUG("set foreign %lx %lx\n", gfn, mfn_x(mfn));
    p2m_lock(p2m);
    rc = set_p2m_entry(p2m, gfn, mfn, 0, p2m_map_foreign, p2m->default_access);
    audit_p2m(p2m, 1);
    p2m_unlock(p2m);
    if ( rc == 0 )
        gdprintk(XENLOG_ERR,
            "set_foreign_p2m_entry: set_p2m_entry failed! gfn:%lx mfn=%08lx\n",
            gfn, mfn_x(gfn_to_mfn(p2m, gfn, &ot)));
    return rc;
}



thanks,
Mukesh

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-24  1:37   ` Mukesh Rathor
@ 2012-04-24  9:36     ` Tim Deegan
  2012-04-24 23:06       ` Mukesh Rathor
  0 siblings, 1 reply; 17+ messages in thread
From: Tim Deegan @ 2012-04-24  9:36 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Keir Fraser, Xen-devel, Ian Campbell, stefano.stabellini

At 18:37 -0700 on 23 Apr (1335206229), Mukesh Rathor wrote:
> On Thu, 19 Apr 2012 15:15:27 +0100
> Tim Deegan <tim@xen.org> wrote:
> 
> > At 18:29 -0700 on 13 Apr (1334341792), Mukesh Rathor wrote:
> >  - AFAICT you're using set_mmio_p2m_entry and adding a new unmap
> >    operation just to avoid having the m2p updated.  Since you can't
> > rely on the unmap always happening through the new call (and you don't
> >    enforce it anywhere), it would be better to add a new p2m_type
> >    just for non-grant foreign mappings.  Then you can gate the m2p
> >    updates in the existing code on the map being normal RAM, as is
> >    already done for p2m_is_grant().
>  
> Hi Tim,
> 
> The variants of get_page* are confusing me, so wanna double check with 
> you.  I should be able to do something like following, right?
> 

[...]

>     if ( (rc=get_page_and_type_from_pagenr(mfn, PGT_writable_page,fdom,0,0)) ) {
>         put_pg_owner(fdom);
>         return rc;
>     }

Yes, but: 

 - You should use get_page_from_pagenr() if fdom is paging_mode_external()
   and reference/copy the comment in get_page_from_l1e() to explain why:

    /* Foreign mappings into guests in shadow external mode don't       
     * contribute to writeable mapping refcounts.  (This allows the
     * qemu-dm helper process in dom0 to map the domain's memory without
     * messing up the count of "real" writable mappings.) */

 - You should drop the refcount (and typecount, if you took one) if the 
   mapping fails.

 - You need to make sure that _any_ path that removes the mapping drops
   the ref/type (_after_ any TLB flushes have happened, please!)  Maybe
   the best way to do that is in ept_set_entry() for EPT and
   paging_write_p2m_entry() for NPT/shadow. 

 - You need to handle the p2m teardown path as well.  I think the best
   way to do that is to hoist the relinquish_shared_pages() loop 
   up into a new function in p2m.c, and add your put_page[_and_type] 
   calls in there. 

Cheers,

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-24  9:36     ` Tim Deegan
@ 2012-04-24 23:06       ` Mukesh Rathor
  2012-04-26  9:08         ` Tim Deegan
  0 siblings, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-24 23:06 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Keir Fraser, Xen-devel, Ian Campbell, stefano.stabellini

On Tue, 24 Apr 2012 10:36:26 +0100
Tim Deegan <tim@xen.org> wrote:

> At 18:37 -0700 on 23 Apr (1335206229), Mukesh Rathor wrote:
> > On Thu, 19 Apr 2012 15:15:27 +0100
> > Tim Deegan <tim@xen.org> wrote:

>you still have this mapping.  You should take a PGT_writeable_page
>typecount, too, if the foreign domain isn't in paging_mode_external

Ok, I've it as:
    if (paging_mode_external(fdom)) {
        if (get_page_from_pagenr(mfn, fdom) == 0)
	    failed = 1;
    } else {
        if (get_page_and_type_from_pagenr(mfn, PGT_writable_page, fdom,0,0))
            failed = 1;
    }

But then later fails when it tries to pin the page,
MMUEXT_PIN_L4_TABLE, from the lib at:

        rc = pin_table(dom->xch, pgd_type,
	                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
			dom->guest_domid);

(XEN) mm.c:2424:d0 Bad type (saw 7400000000000001 != exp 4000000000000000) for mfn 1bc160 (pfn 2eed)

thanks,
-m

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-24 23:06       ` Mukesh Rathor
@ 2012-04-26  9:08         ` Tim Deegan
  2012-04-26 18:18           ` Mukesh Rathor
  0 siblings, 1 reply; 17+ messages in thread
From: Tim Deegan @ 2012-04-26  9:08 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Keir Fraser, Xen-devel, stefano.stabellini, Ian Campbell

At 16:06 -0700 on 24 Apr (1335283603), Mukesh Rathor wrote:
> On Tue, 24 Apr 2012 10:36:26 +0100
> Tim Deegan <tim@xen.org> wrote:
> 
> > At 18:37 -0700 on 23 Apr (1335206229), Mukesh Rathor wrote:
> > > On Thu, 19 Apr 2012 15:15:27 +0100
> > > Tim Deegan <tim@xen.org> wrote:
> 
> >you still have this mapping.  You should take a PGT_writeable_page
> >typecount, too, if the foreign domain isn't in paging_mode_external
> 
> Ok, I've it as:
>     if (paging_mode_external(fdom)) {
>         if (get_page_from_pagenr(mfn, fdom) == 0)
> 	    failed = 1;
>     } else {
>         if (get_page_and_type_from_pagenr(mfn, PGT_writable_page, fdom,0,0))
>             failed = 1;
>     }
> 
> But then later fails when it tries to pin the page,
> MMUEXT_PIN_L4_TABLE, from the lib at:

What's trying to pin an l4 table?  I thought your hybrid dom0 didn't use
the PV MMU.

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-26  9:08         ` Tim Deegan
@ 2012-04-26 18:18           ` Mukesh Rathor
  2012-04-26 19:57             ` Tim Deegan
  0 siblings, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-26 18:18 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Keir Fraser, Xen-devel, stefano.stabellini, Ian Campbell

On Thu, 26 Apr 2012 10:08:47 +0100
Tim Deegan <tim@xen.org> wrote:

> At 16:06 -0700 on 24 Apr (1335283603), Mukesh Rathor wrote:
> > On Tue, 24 Apr 2012 10:36:26 +0100
> > Tim Deegan <tim@xen.org> wrote:
> > 
> > > At 18:37 -0700 on 23 Apr (1335206229), Mukesh Rathor wrote:
> > > > On Thu, 19 Apr 2012 15:15:27 +0100
> > > > Tim Deegan <tim@xen.org> wrote:
> > 
> > >you still have this mapping.  You should take a PGT_writeable_page
> > >typecount, too, if the foreign domain isn't in paging_mode_external
> > 
> > Ok, I've it as:
> >     if (paging_mode_external(fdom)) {
> >         if (get_page_from_pagenr(mfn, fdom) == 0)
> > 	    failed = 1;
> >     } else {
> >         if (get_page_and_type_from_pagenr(mfn, PGT_writable_page,
> > fdom,0,0)) failed = 1;
> >     }
> > 
> > But then later fails when it tries to pin the page,
> > MMUEXT_PIN_L4_TABLE, from the lib at:
> 
> What's trying to pin an l4 table?  I thought your hybrid dom0 didn't
> use the PV MMU.
> 
> Tim.

Right, hybrid doesn't use PV mmu. 
Here, xl/xc is building a pv guest while running on *hybrid* dom0. 
As a result, privcmd is calling this function to map
foreign mfns to pfns: 

xc_dom_x86.c:
      arch_setup_bootlate -> pin_table -> xc_mmuext_op().

thanks,
Mukesh

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-26 18:18           ` Mukesh Rathor
@ 2012-04-26 19:57             ` Tim Deegan
  2012-04-27  1:56               ` Mukesh Rathor
  0 siblings, 1 reply; 17+ messages in thread
From: Tim Deegan @ 2012-04-26 19:57 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Ian Campbell, Keir Fraser, Xen-devel, stefano.stabellini

At 11:18 -0700 on 26 Apr (1335439128), Mukesh Rathor wrote:
> On Thu, 26 Apr 2012 10:08:47 +0100
> Tim Deegan <tim@xen.org> wrote:
> 
> > At 16:06 -0700 on 24 Apr (1335283603), Mukesh Rathor wrote:
> > > On Tue, 24 Apr 2012 10:36:26 +0100
> > > Tim Deegan <tim@xen.org> wrote:
> > > 
> > > > At 18:37 -0700 on 23 Apr (1335206229), Mukesh Rathor wrote:
> > > > > On Thu, 19 Apr 2012 15:15:27 +0100
> > > > > Tim Deegan <tim@xen.org> wrote:
> > > 
> > > >you still have this mapping.  You should take a PGT_writeable_page
> > > >typecount, too, if the foreign domain isn't in paging_mode_external
> > > 
> > > Ok, I've it as:
> > >     if (paging_mode_external(fdom)) {
> > >         if (get_page_from_pagenr(mfn, fdom) == 0)
> > > 	    failed = 1;
> > >     } else {
> > >         if (get_page_and_type_from_pagenr(mfn, PGT_writable_page,
> > > fdom,0,0)) failed = 1;
> > >     }
> > > 
> > > But then later fails when it tries to pin the page,
> > > MMUEXT_PIN_L4_TABLE, from the lib at:
> > 
> > What's trying to pin an l4 table?  I thought your hybrid dom0 didn't
> > use the PV MMU.
> > 
> > Tim.
> 
> Right, hybrid doesn't use PV mmu. 
> Here, xl/xc is building a pv guest while running on *hybrid* dom0. 

Oh, I see.  This is the domU's L4.  In that case I suspect that what's
missing is the translation from GFNs to MFNs in the domU. 

To do that, we may finally have to reintroduce the dreaded 'tell me what
MFN backs this domU GFN' call, so the dom0 tools can build proper
pagetables and p2m for the pv domU.  Or have you already taken care of
that?

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-26 19:57             ` Tim Deegan
@ 2012-04-27  1:56               ` Mukesh Rathor
  2012-04-27  8:51                 ` Tim Deegan
  0 siblings, 1 reply; 17+ messages in thread
From: Mukesh Rathor @ 2012-04-27  1:56 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Campbell, Keir Fraser, Xen-devel, stefano.stabellini

On Thu, 26 Apr 2012 20:57:12 +0100
Tim Deegan <tim@xen.org> wrote:

> At 11:18 -0700 on 26 Apr (1335439128), Mukesh Rathor wrote:
> > On Thu, 26 Apr 2012 10:08:47 +0100
> 
> Oh, I see.  This is the domU's L4.  In that case I suspect that what's
> missing is the translation from GFNs to MFNs in the domU. 
> 
> To do that, we may finally have to reintroduce the dreaded 'tell me
> what MFN backs this domU GFN' call, so the dom0 tools can build proper
> pagetables and p2m for the pv domU.  Or have you already taken care of
> that?


The tools get an array of the PV domU mfn's. Next to build pagetables, it
needs to map them. It does via privcmd. I generate needed pfn space (not
virtual address space) via ballooning. Next I need to map each pfn to 
the domU mfns. This is a pv guest being built. So, these are mfns' that
don't need looking up. This mapping is temporary, while the guest is being 
built. For building a hybrid domU, it doesn't need to pin the L4 as the 
hybrid guest doesn't use PV MMU. So, these mfn's that are mapped just 
need temporary page count. 

thanks,
Mukesh

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
  2012-04-27  1:56               ` Mukesh Rathor
@ 2012-04-27  8:51                 ` Tim Deegan
  0 siblings, 0 replies; 17+ messages in thread
From: Tim Deegan @ 2012-04-27  8:51 UTC (permalink / raw)
  To: Mukesh Rathor; +Cc: Ian Campbell, Keir Fraser, Xen-devel, stefano.stabellini

At 18:56 -0700 on 26 Apr (1335466565), Mukesh Rathor wrote:
> The tools get an array of the PV domU mfn's. Next to build pagetables, it
> needs to map them. It does via privcmd. I generate needed pfn space (not
> virtual address space) via ballooning. Next I need to map each pfn to 
> the domU mfns. This is a pv guest being built. So, these are mfns' that
> don't need looking up.

I'm sorry, my brain was addled from staring at spinlock code too long.
Of course, since the domU is PV you already have MFNs. 

In that case, I can't think of any obvious reasons for the failure.
you'll just have to dig a bit further -- see exactly which entry it's
complaining about, whether it matches what the dom0 tools thought they
put there, and what you would expect to be there.

Cheers,

Tim.

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

* Re: [hybrid]: code review for function mapping pfn to foreign mfn
       [not found] <mailman.2710.1334825330.1399.xen-devel@lists.xen.org>
@ 2012-04-19 14:40 ` Andres Lagar-Cavilla
  0 siblings, 0 replies; 17+ messages in thread
From: Andres Lagar-Cavilla @ 2012-04-19 14:40 UTC (permalink / raw)
  To: xen-devel; +Cc: keir.xen, tim, Ian.Campbell, Stefano.Stabellini

> On Thu, 2012-04-19 at 00:29 +0100, Mukesh Rathor wrote:
>> On Tue, 17 Apr 2012 10:05:28 +0100
>> Ian Campbell <Ian.Campbell@citrix.com> wrote:
>>
>> > On Tue, 2012-04-17 at 02:53 +0100, Mukesh Rathor wrote:
>> > > On Mon, 16 Apr 2012 14:53:22 +0100
>> > > Ian Campbell <Ian.Campbell@citrix.com> wrote:
>> >
>> > Sorry, I meant why a whole new subcall instead of a new
>> > XENMAPSPACE ;-)
>> >
>> > e.g. On ARM I did:
>> >
>> > diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
>> > index 86d02c8..b2adfbe 100644
>> > --- a/xen/include/public/memory.h
>> > +++ b/xen/include/public/memory.h
>> > @@ -212,11 +212,13 @@ struct xen_add_to_physmap {
>> >      uint16_t    size;
>> >
>> >      /* Source mapping space. */
>> > -#define XENMAPSPACE_shared_info 0 /* shared info page */
>> > -#define XENMAPSPACE_grant_table 1 /* grant table page */
>> > -#define XENMAPSPACE_gmfn        2 /* GMFN */
>> > -#define XENMAPSPACE_gmfn_range  3 /* GMFN range */
>> > -    unsigned int space;
>> > +#define XENMAPSPACE_shared_info  0 /* shared info page */
>> > +#define XENMAPSPACE_grant_table  1 /* grant table page */
>> > +#define XENMAPSPACE_gmfn         2 /* GMFN */
>> > +#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
>> > +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
>> > +    uint16_t space;
>> > +    domid_t foreign_domid; /* IFF gmfn_foreign */
>>
>>
>> Well, for several reasons, I didn't use it, mainly, it doesn't allow
>> for count. So requests have to come in one frame at a time.
>
> I've got it that way on ARM too at the moment but I was planning to make
> it behave like gmfn_range and use the size parameter to map multiple at
> a time (unless I've misunderstood what the gmfn_range variant does).
>
>>  Second, none of the common code can be used by my new request,
>
> I don't think that's an impediment to the API, XENMAPSPACE_gmfn_foreign
> is in pretty much the same position.
>
>>  because:
>>    - frame is not removed from foreign domain in my case
>>    - i don't want to update the m2p with new info.
>>
>> Anyways, I put it there for now. With ballooning change in dom0, I'm
>> now doing the hcall one frame at a time anyways. We can always enhance
>> in the future.
>>
>>         case XENMAPSPACE_gmfn_foreign:
>>         {
>>             rc = _add_foreign_to_pmap_batch(&xatp);
>>             rcu_unlock_domain(d);
>>             return rc;
>>         }
>>
>>
>> >> static long noinline _rem_foreign_pmap_batch(XEN_GUEST_HANDLE(void)
>> >> arg)
>>
>> >Can't XENMEM_remove_from_physmap be used here?
>>
>> Well, that calls guest_physmap_remove_page() which calls
>> p2m_remove_page which updates the M2P with INVALID_M2P_ENTRY. Whereas,
>> i just need to remove from the dom0 p2m and leave M2P as is (mfn to
>> domU gmfn). I could add a flag to the struct causing it to just call
>> set_p2m_entry() directly?
>
> Would it be useful to track the fact that a p2m entry is foreign
> somewhere? That would let you do the appropriate type of teardown etc
> without relying on the tools to get it right.
>
> Are there s/w bits available in the p2m entry itself on x86 or do we use
> them all already?

A few still available. We're at 14 types and EPT uses 4 bits.

NPT has even more room, unless it's sharing its p2m tables with iommu
tables -- in which case it can't really do fancy p2m typing. That would be
an unwelcome side-effect for a hybrid dom0 on amd, but I'm not aware of
how bad it would be.

The more general value here is to allow hvm backends arbitrary mapping
capabilities, correct? Right now all hvm backends/driver domains are
supposed to use grant table code (and there are p2m types for those).

A domain builder/checkpointing hvm domain would require equivalent
capabilities to those being discussed here, if I'm not mistaken.

So, a p2m_foreign_map would be the way to go.

My two cents
Andres


>
> Ian.

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

end of thread, other threads:[~2012-04-27  8:51 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-14  1:29 [hybrid]: code review for function mapping pfn to foreign mfn Mukesh Rathor
2012-04-16 13:53 ` Ian Campbell
2012-04-16 14:02   ` Tim Deegan
2012-04-17  1:53   ` Mukesh Rathor
2012-04-17  9:05     ` Ian Campbell
2012-04-18 23:29       ` Mukesh Rathor
2012-04-19  7:22         ` Ian Campbell
2012-04-19 14:15 ` Tim Deegan
2012-04-24  1:37   ` Mukesh Rathor
2012-04-24  9:36     ` Tim Deegan
2012-04-24 23:06       ` Mukesh Rathor
2012-04-26  9:08         ` Tim Deegan
2012-04-26 18:18           ` Mukesh Rathor
2012-04-26 19:57             ` Tim Deegan
2012-04-27  1:56               ` Mukesh Rathor
2012-04-27  8:51                 ` Tim Deegan
     [not found] <mailman.2710.1334825330.1399.xen-devel@lists.xen.org>
2012-04-19 14:40 ` Andres Lagar-Cavilla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.