From: Mukesh Rathor <mukesh.rathor@oracle.com>
To: "Xen-devel@lists.xensource.com" <Xen-devel@lists.xensource.com>
Subject: [RFC PATCH 14/16]: PVH xen: add xenmem_add_foreign_to_pmap()
Date: Fri, 11 Jan 2013 18:11:03 -0800 [thread overview]
Message-ID: <20130111181103.5bfeed98@mantra.us.oracle.com> (raw)
In this patch, I add a new function, xenmem_add_foreign_to_pmap(), to
map pages from foreign gue st into current dom0 for domU creation.
Also, some minor grant changes for PVH.
Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com>
diff -r 2c894340b16f -r 47d2e652bd4d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Jan 11 16:43:02 2013 -0800
+++ b/xen/arch/x86/mm.c Fri Jan 11 16:45:36 2013 -0800
@@ -2608,7 +2608,7 @@ static struct domain *get_pg_owner(domid
goto out;
}
- if ( unlikely(paging_mode_translate(curr)) )
+ if ( !is_pvh_domain(curr) && unlikely(paging_mode_translate(curr)) )
{
MEM_LOG("Cannot mix foreign mappings with translated domains");
goto out;
@@ -3734,16 +3734,34 @@ static int replace_grant_p2m_mapping(
old_mfn = get_gfn(d, gfn, &type);
if ( !p2m_is_grant(type) || mfn_x(old_mfn) != frame )
{
- put_gfn(d, gfn);
gdprintk(XENLOG_WARNING,
- "replace_grant_p2m_mapping: old mapping invalid (type %d, mfn %lx, frame %lx)\n",
+ "replace_grant_p2m_mapping: old mapping invalid "
+ "(type %d, mfn %lx, frame %lx)\n",
type, mfn_x(old_mfn), frame);
- return GNTST_general_error;
+ goto out_err;
}
guest_physmap_remove_page(d, gfn, frame, PAGE_ORDER_4K);
+ /* PVH: Because we free the existing mfn in XENMEM_add_to_physmap during
+ * grant map, we undo that here so the guest P2M (EPT/NPT) is consistent */
+ if ( is_pvh_domain(d) ) {
+ struct page_info *page = alloc_domheap_page(d, 0);
+
+ if ( page == NULL ) {
+ gdprintk(XENLOG_ERR, "Unable to alloc domheap page\n");
+ goto out_err;
+ }
+ if ( guest_physmap_add_page(d, gfn, page_to_mfn(page), 0) != 0 ) {
+ gdprintk(XENLOG_ERR, "Unable to add mfn to replace grant\n");
+ goto out_err;
+ }
+ }
put_gfn(d, gfn);
return GNTST_okay;
+
+out_err:
+ put_gfn(d, gfn);
+ return GNTST_general_error;
}
int replace_grant_host_mapping(
@@ -4143,7 +4161,7 @@ long do_update_descriptor(u64 pa, u64 de
page = get_page_from_gfn(dom, gmfn, NULL, P2M_ALLOC);
if ( (((unsigned int)pa % sizeof(struct desc_struct)) != 0) ||
!page ||
- !check_descriptor(dom, &d) )
+ (!is_pvh_domain(dom) && !check_descriptor(dom, &d)) )
{
if ( page )
put_page(page);
@@ -4217,7 +4235,81 @@ static int handle_iomem_range(unsigned l
return 0;
}
-static int xenmem_add_to_physmap_once(
+/* add frames from foreign domain to current domain's physmap. Similar to
+ * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
+ * and is not removed from foreign domain.
+ * Usage: libxl on pvh dom0 creating a guest and doing privcmd_ioctl_mmap
+ * Returns: 0 ==> success
+ */
+static long noinline xenmem_add_foreign_to_pmap( domid_t foreign_domid,
+ unsigned long fgmfn, unsigned long gpfn)
+{
+ unsigned long rc=0, prev_mfn, mfn = 0;
+ struct domain *fdom, *currd = current->domain;
+ p2m_type_t p2mt, p2mt_prev;
+
+ if ( (fdom = get_pg_owner(foreign_domid)) == NULL ) {
+ return -EPERM;
+ }
+
+ mfn = mfn_x(get_gfn_query_unlocked(fdom, fgmfn, &p2mt));
+
+ /* qemu, running on PVH dom0, mapping hvm domain's io pages during domain
+ * creation, doesn't have mfns in the HAP table */
+ if ( !mfn_valid(mfn) && p2m_is_mmio(p2mt) ) {
+
+ if (!is_hvm_domain(fdom)) {
+ printk("mmio type for non-hvm domain. fd:%d fgmfn:%lx gpfn:%lx\n",
+ foreign_domid, fgmfn, gpfn);
+ return -EINVAL;
+ }
+ mfn = fgmfn; /* map 1 to 1 */
+ }
+
+ if ( !p2m_is_valid(p2mt) ) {
+ put_pg_owner(fdom);
+ return -EINVAL;
+ }
+
+ if ( !p2m_is_mmio(p2mt) && !get_page_from_pagenr(mfn, fdom) ) {
+ put_pg_owner(fdom);
+ return -EINVAL;
+ }
+
+ /* Remove previously mapped page if it was present. */
+ prev_mfn = mfn_x(get_gfn_query_unlocked(currd, gpfn, &p2mt_prev));
+ 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 which will result in mfn --> gpfn of dom0
+ * and not gpfn of domU. */
+ if ( p2m_is_mmio(p2mt) ) {
+ if ( set_mmio_p2m_entry(currd, gpfn, _mfn(mfn)) == 0 ) {
+ printk("set_mmio_p2m failed. gpfn:%lx mfn:%lx fgmfn:%lx\n",
+ gpfn, mfn, fgmfn);
+ rc = -EINVAL;
+ }
+
+ } else if ( set_foreign_p2m_entry(currd, gpfn, _mfn(mfn)) == 0 ) {
+
+ printk("guest_physmap_add_page failed1. gpfn:%lx mfn:%lx fgmfn:%lx\n",
+ gpfn, mfn, fgmfn);
+ put_page(mfn_to_page(mfn));
+ rc = -EINVAL;
+ }
+ put_pg_owner(fdom);
+ return rc;
+}
+
+static int noinline xenmem_add_to_physmap_once(
struct domain *d, uint16_t xatp_space, domid_t foreign_domid,
unsigned long xatp_idx, unsigned long xatp_gpfn)
{
@@ -4278,6 +4370,13 @@ static int xenmem_add_to_physmap_once(
page = mfn_to_page(mfn);
break;
}
+
+ case XENMAPSPACE_gmfn_foreign:
+ {
+ rc = xenmem_add_foreign_to_pmap(foreign_domid, xatp_idx, xatp_gpfn);
+ return rc;
+ }
+
default:
break;
}
diff -r 2c894340b16f -r 47d2e652bd4d xen/common/grant_table.c
--- a/xen/common/grant_table.c Fri Jan 11 16:43:02 2013 -0800
+++ b/xen/common/grant_table.c Fri Jan 11 16:45:36 2013 -0800
@@ -529,7 +529,7 @@ static void mapcount(
* addr is _either_ a host virtual address, or the address of the pte to
* update, as indicated by the GNTMAP_contains_pte flag.
*/
-static void
+static noinline void
__gnttab_map_grant_ref(
struct gnttab_map_grant_ref *op)
{
@@ -745,7 +745,7 @@ __gnttab_map_grant_ref(
double_gt_lock(lgt, rgt);
- if ( !is_hvm_domain(ld) && need_iommu(ld) )
+ if ( !is_hvm_or_pvh_domain(ld) && need_iommu(ld) )
{
unsigned int wrc, rdc;
int err = 0;
@@ -956,7 +956,7 @@ __gnttab_unmap_common(
act->pin -= GNTPIN_hstw_inc;
}
- if ( !is_hvm_domain(ld) && need_iommu(ld) )
+ if ( !is_hvm_or_pvh_domain(ld) && need_iommu(ld) )
{
unsigned int wrc, rdc;
int err = 0;
next reply other threads:[~2013-01-12 2:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-12 2:11 Mukesh Rathor [this message]
2013-01-24 17:31 ` [RFC PATCH 14/16]: PVH xen: add xenmem_add_foreign_to_pmap() Tim Deegan
2013-02-12 2:18 ` Mukesh Rathor
2013-02-14 2:34 ` Mukesh Rathor
2013-02-14 10:22 ` Tim Deegan
2013-02-14 10:39 ` Tim Deegan
2013-02-16 0:17 ` Mukesh Rathor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130111181103.5bfeed98@mantra.us.oracle.com \
--to=mukesh.rathor@oracle.com \
--cc=Xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).