This is rebased onto 0e9e3e306c7e (AKA current Linus, which now includes
the previously prerequisite series "xen: build fixes and interface
tweaks") and Konrad's stable/pvh.v5 branch.
For convenience I've also pushed to
git://xenbits.xen.org/people/ianc/linux.git
arm-privcmd-on-x86-pvh5
Note that this contains my merge of Konrad's branch into Linus' tree at
the base. You might want to cherry pick it rather than merge it.
Ian.
Squeezing the necessary fields into the existing XENMEM_add_to_physmap
interface was proving to be a bit tricky so we have decided to go with
a new interface upstream (the XENMAPSPACE_gmfn_foreign interface using
XENMEM_add_to_physmap was never committed anywhere). This interface
also allows for batching which was impossible to support at the same
time as foreign mfns in the old interface.
This reverts the relevant parts of "PVH: basic and header changes,
elfnote changes, ..." and followups and trivially converts
pvh_add_to_xen_p2m over.
Signed-off-by: Ian Campbell <[email protected]>
Acked-by: Stefano Stabellini <[email protected]>
---
arch/x86/xen/enlighten.c | 1 -
arch/x86/xen/mmu.c | 18 ++++++++++++------
drivers/xen/grant-table.c | 1 -
include/xen/interface/memory.h | 18 +++++++++---------
4 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index bf6313b..eb9a567 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1546,7 +1546,6 @@ void __ref xen_hvm_init_shared_info(void)
xatp.domid = DOMID_SELF;
xatp.idx = 0;
xatp.space = XENMAPSPACE_shared_info;
- xatp.foreign_domid = 0;
xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 58f2084..fee34fe 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2500,13 +2500,19 @@ static int pvh_add_to_xen_p2m(unsigned long lpfn, unsigned long fgmfn,
unsigned int domid)
{
int rc;
- struct xen_add_to_physmap xatp = { .foreign_domid = domid };
+ struct xen_add_to_physmap_range xatp = {
+ .domid = DOMID_SELF,
+ .foreign_domid = domid,
+ .size = 1,
+ .space = XENMAPSPACE_gmfn_foreign,
+ };
+ xen_ulong_t idx = fgmfn;
+ xen_pfn_t gpfn = lpfn;
+
+ set_xen_guest_handle(xatp.idxs, &idx);
+ set_xen_guest_handle(xatp.gpfns, &gpfn);
- xatp.gpfn = lpfn;
- xatp.idx = fgmfn;
- xatp.domid = DOMID_SELF;
- xatp.space = XENMAPSPACE_gmfn_foreign;
- rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+ rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
if (rc)
pr_warn("d0: Failed to map pfn (0x%lx) to mfn (0x%lx) rc:%d\n",
lpfn, fgmfn, rc);
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index adaa4c2..1ab8630 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -1049,7 +1049,6 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
do {
xatp.domid = DOMID_SELF;
xatp.idx = i;
- xatp.foreign_domid = 0;
xatp.space = XENMAPSPACE_grant_table;
xatp.gpfn = start_gpfn + i;
rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index 5de2b36..9dad393 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -153,6 +153,14 @@ struct xen_machphys_mapping {
};
DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
+#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, XENMEM_add_to_physmap only. */
+#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
+ * XENMEM_add_to_physmap_range only.
+ */
+
/*
* Sets the GPFN at which a particular page appears in the specified guest's
* pseudophysical address space.
@@ -167,15 +175,7 @@ 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 */
-#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
- uint16_t space;
- domid_t foreign_domid; /* IFF XENMAPSPACE_gmfn_foreign */
-
-#define XENMAPIDX_grant_table_status 0x80000000
+ unsigned int space;
/* Index into source mapping space. */
xen_ulong_t idx;
--
1.7.2.5
The code is no in a state where can just enable it.
Drop the *_xenballloned_pages duplicates since these are now supplied
by the balloon code.
Signed-off-by: Ian Campbell <[email protected]>
Acked-by: Stefano Stabellini <[email protected]>
---
arch/arm/xen/enlighten.c | 23 +++++------------------
drivers/xen/Makefile | 4 ++--
2 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 59bcb96..ba5cc13 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -8,6 +8,7 @@
#include <xen/features.h>
#include <xen/platform_pci.h>
#include <xen/xenbus.h>
+#include <xen/page.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <linux/interrupt.h>
@@ -29,6 +30,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+/* These are unused until we support booting "pre-ballooned" */
+unsigned long xen_released_pages;
+struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
+
/* TODO: to be removed */
__read_mostly int xen_have_vector_callback;
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
@@ -148,21 +153,3 @@ static int __init xen_init_events(void)
return 0;
}
postcore_initcall(xen_init_events);
-
-/* XXX: only until balloon is properly working */
-int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
-{
- *pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL,
- get_order(nr_pages));
- if (*pages == NULL)
- return -ENOMEM;
- return 0;
-}
-EXPORT_SYMBOL_GPL(alloc_xenballooned_pages);
-
-void free_xenballooned_pages(int nr_pages, struct page **pages)
-{
- kfree(*pages);
- *pages = NULL;
-}
-EXPORT_SYMBOL_GPL(free_xenballooned_pages);
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0e863703..909bb56 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,8 +1,8 @@
ifneq ($(CONFIG_ARM),y)
-obj-y += manage.o balloon.o
+obj-y += manage.o
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
endif
-obj-y += grant-table.o features.o events.o
+obj-y += grant-table.o features.o events.o balloon.o
obj-y += xenbus/
nostackp := $(call cc-option, -fno-stack-protector)
--
1.7.2.5
We use XENMEM_add_to_physmap_range which is the preferred interface
for foreign mappings.
Signed-off-by: Ian Campbell <[email protected]>
---
arch/arm/include/asm/xen/interface.h | 1 +
arch/arm/xen/enlighten.c | 100 +++++++++++++++++++++++++++++++++-
arch/x86/include/asm/xen/interface.h | 1 +
include/xen/interface/memory.h | 18 ++++++
4 files changed, 117 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
index 5000397..1151188 100644
--- a/arch/arm/include/asm/xen/interface.h
+++ b/arch/arm/include/asm/xen/interface.h
@@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
DEFINE_GUEST_HANDLE(xen_pfn_t);
+DEFINE_GUEST_HANDLE(xen_ulong_t);
/* Maximum number of virtual CPUs in multi-processor guests. */
#define MAX_VIRT_CPUS 1
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index ba5cc13..f28fc1a 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -9,6 +9,7 @@
#include <xen/platform_pci.h>
#include <xen/xenbus.h>
#include <xen/page.h>
+#include <xen/xen-ops.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <linux/interrupt.h>
@@ -18,6 +19,8 @@
#include <linux/of_irq.h>
#include <linux/of_address.h>
+#include <linux/mm.h>
+
struct start_info _xen_start_info;
struct start_info *xen_start_info = &_xen_start_info;
EXPORT_SYMBOL_GPL(xen_start_info);
@@ -43,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
static __read_mostly int xen_events_irq = -1;
+/* map fgmfn of domid to lpfn in the current domain */
+static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
+ unsigned int domid)
+{
+ int rc;
+ struct xen_add_to_physmap_range xatp = {
+ .domid = DOMID_SELF,
+ .foreign_domid = domid,
+ .size = 1,
+ .space = XENMAPSPACE_gmfn_foreign,
+ };
+ xen_ulong_t idx = fgmfn;
+ xen_pfn_t gpfn = lpfn;
+
+ set_xen_guest_handle(xatp.idxs, &idx);
+ set_xen_guest_handle(xatp.gpfns, &gpfn);
+
+ rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
+ if (rc) {
+ pr_warn("Failed to map pfn to mfn rc:%d pfn:%lx mfn:%lx\n",
+ rc, lpfn, fgmfn);
+ return 1;
+ }
+ return 0;
+}
+
+struct remap_data {
+ xen_pfn_t fgmfn; /* foreign domain's gmfn */
+ pgprot_t prot;
+ domid_t domid;
+ struct vm_area_struct *vma;
+ int index;
+ struct page **pages;
+ struct xen_remap_mfn_info *info;
+};
+
+static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
+ void *data)
+{
+ struct remap_data *info = data;
+ struct page *page = info->pages[info->index++];
+ unsigned long pfn = page_to_pfn(page);
+ pte_t pte = pfn_pte(pfn, info->prot);
+
+ if (map_foreign_page(pfn, info->fgmfn, info->domid))
+ return -EFAULT;
+ set_pte_at(info->vma->vm_mm, addr, ptep, pte);
+
+ return 0;
+}
+
int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
unsigned long addr,
- unsigned long mfn, int nr,
- pgprot_t prot, unsigned domid)
+ xen_pfn_t mfn, int nr,
+ pgprot_t prot, unsigned domid,
+ struct page **pages)
{
- return -ENOSYS;
+ int err;
+ struct remap_data data;
+
+ /* TBD: Batching, current sole caller only does page at a time */
+ if (nr > 1)
+ return -EINVAL;
+
+ data.fgmfn = mfn;
+ data.prot = prot;
+ data.domid = domid;
+ data.vma = vma;
+ data.index = 0;
+ data.pages = pages;
+ err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
+ remap_pte_fn, &data);
+ return err;
}
EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+ int nr, struct page **pages)
+{
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ struct xen_remove_from_physmap xrp;
+ unsigned long rc, pfn;
+
+ pfn = page_to_pfn(pages[i]);
+
+ xrp.domid = DOMID_SELF;
+ xrp.gpfn = pfn;
+ rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
+ if (rc) {
+ pr_warn("Failed to unmap pfn:%lx rc:%ld\n",
+ pfn, rc);
+ return rc;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+
/*
* see Documentation/devicetree/bindings/arm/xen.txt for the
* documentation of the Xen Device Tree format.
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index b459d2e..20e738a 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
DEFINE_GUEST_HANDLE(xen_pfn_t);
+DEFINE_GUEST_HANDLE(xen_ulong_t);
#endif
#ifndef HYPERVISOR_VIRT_START
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index ad0dff5..5de2b36 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -188,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
/*** REMOVED ***/
/*#define XENMEM_translate_gpfn_list 8*/
+#define XENMEM_add_to_physmap_range 23
+struct xen_add_to_physmap_range {
+ /* Which domain to change the mapping for. */
+ domid_t domid;
+ uint16_t space; /* => enum phys_map_space */
+
+ /* Number of pages to go through */
+ uint16_t size;
+ domid_t foreign_domid; /* IFF gmfn_foreign */
+
+ /* Indexes into space being mapped. */
+ GUEST_HANDLE(xen_ulong_t) idxs;
+
+ /* GPFN in domid where the source mapping page should appear. */
+ GUEST_HANDLE(xen_pfn_t) gpfns;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap_range);
+
/*
* Returns the pseudo-physical memory map as it was when the domain
* was started (specified by XENMEM_set_memory_map).
--
1.7.2.5
The ARM platform has no concept of PVMMU and therefor no
HYPERVISOR_update_va_mapping et al. Allow this code to be compiled out
when not required.
In some similar situations (e.g. P2M) we have defined dummy functions
to avoid this, however I think we can/should draw the line at dummying
out actual hypercalls.
Signed-off-by: Ian Campbell <[email protected]>
---
arch/x86/xen/Kconfig | 1 +
drivers/xen/Kconfig | 3 +++
drivers/xen/balloon.c | 4 ++++
3 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index c9660bf..7e938ba 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -6,6 +6,7 @@ config XEN
bool "Xen guest support"
select PARAVIRT
select PARAVIRT_CLOCK
+ select XEN_HAVE_PVMMU
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
depends on X86_CMPXCHG && X86_TSC
help
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index d4dffcd..9c00652 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -204,4 +204,7 @@ config XEN_MCE_LOG
Allow kernel fetching MCE error from Xen platform and
converting it into Linux mcelog format for mcelog tools
+config XEN_HAVE_PVMMU
+ bool
+
endmenu
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 66fad33..d42da3b 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -359,6 +359,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
set_phys_to_machine(pfn, frame_list[i]);
+#ifdef CONFIG_XEN_HAVE_PVMMU
/* Link back into the page tables if not highmem. */
if (xen_pv_domain() && !PageHighMem(page) &&
!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -370,6 +371,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
0);
BUG_ON(ret);
}
+#endif
/* Relinquish the page back to the allocator. */
ClearPageReserved(page);
@@ -418,6 +420,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
scrub_page(page);
+#ifdef CONFIG_XEN_HAVE_PVMMU
if (xen_pv_domain() && !PageHighMem(page)) {
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
ret = HYPERVISOR_update_va_mapping(
@@ -426,6 +429,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
BUG_ON(ret);
}
}
+#endif
}
/* Ensure that ballooned highmem pages don't have kmaps. */
--
1.7.2.5
For Xen on ARM a PFN is 64 bits so we need to use the appropriate
type here.
Signed-off-by: Ian Campbell <[email protected]>
Acked-by: Stefano Stabellini <[email protected]>
---
arch/x86/xen/mmu.c | 2 +-
include/xen/xen-ops.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 5747a41..58f2084 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2599,7 +2599,7 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
unsigned long addr,
- unsigned long mfn, int nr,
+ xen_pfn_t mfn, int nr,
pgprot_t prot, unsigned domid,
struct page **pages)
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 990b43e..ee188eb 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -26,7 +26,7 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
struct vm_area_struct;
int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
unsigned long addr,
- unsigned long mfn, int nr,
+ xen_pfn_t mfn, int nr,
pgprot_t prot, unsigned domid,
struct page **pages);
int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
--
1.7.2.5
On Wed, 24 Oct 2012, Ian Campbell wrote:
> We use XENMEM_add_to_physmap_range which is the preferred interface
> for foreign mappings.
>
> Signed-off-by: Ian Campbell <[email protected]>
Acked-by: Stefano Stabellini <[email protected]>
> arch/arm/include/asm/xen/interface.h | 1 +
> arch/arm/xen/enlighten.c | 100 +++++++++++++++++++++++++++++++++-
> arch/x86/include/asm/xen/interface.h | 1 +
> include/xen/interface/memory.h | 18 ++++++
> 4 files changed, 117 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
> index 5000397..1151188 100644
> --- a/arch/arm/include/asm/xen/interface.h
> +++ b/arch/arm/include/asm/xen/interface.h
> @@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void);
> DEFINE_GUEST_HANDLE(uint64_t);
> DEFINE_GUEST_HANDLE(uint32_t);
> DEFINE_GUEST_HANDLE(xen_pfn_t);
> +DEFINE_GUEST_HANDLE(xen_ulong_t);
>
> /* Maximum number of virtual CPUs in multi-processor guests. */
> #define MAX_VIRT_CPUS 1
> diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
> index ba5cc13..f28fc1a 100644
> --- a/arch/arm/xen/enlighten.c
> +++ b/arch/arm/xen/enlighten.c
> @@ -9,6 +9,7 @@
> #include <xen/platform_pci.h>
> #include <xen/xenbus.h>
> #include <xen/page.h>
> +#include <xen/xen-ops.h>
> #include <asm/xen/hypervisor.h>
> #include <asm/xen/hypercall.h>
> #include <linux/interrupt.h>
> @@ -18,6 +19,8 @@
> #include <linux/of_irq.h>
> #include <linux/of_address.h>
>
> +#include <linux/mm.h>
> +
> struct start_info _xen_start_info;
> struct start_info *xen_start_info = &_xen_start_info;
> EXPORT_SYMBOL_GPL(xen_start_info);
> @@ -43,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
>
> static __read_mostly int xen_events_irq = -1;
>
> +/* map fgmfn of domid to lpfn in the current domain */
> +static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
> + unsigned int domid)
> +{
> + int rc;
> + struct xen_add_to_physmap_range xatp = {
> + .domid = DOMID_SELF,
> + .foreign_domid = domid,
> + .size = 1,
> + .space = XENMAPSPACE_gmfn_foreign,
> + };
> + xen_ulong_t idx = fgmfn;
> + xen_pfn_t gpfn = lpfn;
> +
> + set_xen_guest_handle(xatp.idxs, &idx);
> + set_xen_guest_handle(xatp.gpfns, &gpfn);
> +
> + rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
> + if (rc) {
> + pr_warn("Failed to map pfn to mfn rc:%d pfn:%lx mfn:%lx\n",
> + rc, lpfn, fgmfn);
> + return 1;
> + }
> + return 0;
> +}
> +
> +struct remap_data {
> + xen_pfn_t fgmfn; /* foreign domain's gmfn */
> + pgprot_t prot;
> + domid_t domid;
> + struct vm_area_struct *vma;
> + int index;
> + struct page **pages;
> + struct xen_remap_mfn_info *info;
> +};
> +
> +static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
> + void *data)
> +{
> + struct remap_data *info = data;
> + struct page *page = info->pages[info->index++];
> + unsigned long pfn = page_to_pfn(page);
> + pte_t pte = pfn_pte(pfn, info->prot);
> +
> + if (map_foreign_page(pfn, info->fgmfn, info->domid))
> + return -EFAULT;
> + set_pte_at(info->vma->vm_mm, addr, ptep, pte);
> +
> + return 0;
> +}
> +
> int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
> unsigned long addr,
> - unsigned long mfn, int nr,
> - pgprot_t prot, unsigned domid)
> + xen_pfn_t mfn, int nr,
> + pgprot_t prot, unsigned domid,
> + struct page **pages)
> {
> - return -ENOSYS;
> + int err;
> + struct remap_data data;
> +
> + /* TBD: Batching, current sole caller only does page at a time */
> + if (nr > 1)
> + return -EINVAL;
> +
> + data.fgmfn = mfn;
> + data.prot = prot;
> + data.domid = domid;
> + data.vma = vma;
> + data.index = 0;
> + data.pages = pages;
> + err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
> + remap_pte_fn, &data);
> + return err;
> }
> EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
>
> +int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
> + int nr, struct page **pages)
> +{
> + int i;
> +
> + for (i = 0; i < nr; i++) {
> + struct xen_remove_from_physmap xrp;
> + unsigned long rc, pfn;
> +
> + pfn = page_to_pfn(pages[i]);
> +
> + xrp.domid = DOMID_SELF;
> + xrp.gpfn = pfn;
> + rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
> + if (rc) {
> + pr_warn("Failed to unmap pfn:%lx rc:%ld\n",
> + pfn, rc);
> + return rc;
> + }
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
> +
> /*
> * see Documentation/devicetree/bindings/arm/xen.txt for the
> * documentation of the Xen Device Tree format.
> diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
> index b459d2e..20e738a 100644
> --- a/arch/x86/include/asm/xen/interface.h
> +++ b/arch/x86/include/asm/xen/interface.h
> @@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void);
> DEFINE_GUEST_HANDLE(uint64_t);
> DEFINE_GUEST_HANDLE(uint32_t);
> DEFINE_GUEST_HANDLE(xen_pfn_t);
> +DEFINE_GUEST_HANDLE(xen_ulong_t);
> #endif
>
> #ifndef HYPERVISOR_VIRT_START
> diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
> index ad0dff5..5de2b36 100644
> --- a/include/xen/interface/memory.h
> +++ b/include/xen/interface/memory.h
> @@ -188,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
> /*** REMOVED ***/
> /*#define XENMEM_translate_gpfn_list 8*/
>
> +#define XENMEM_add_to_physmap_range 23
> +struct xen_add_to_physmap_range {
> + /* Which domain to change the mapping for. */
> + domid_t domid;
> + uint16_t space; /* => enum phys_map_space */
> +
> + /* Number of pages to go through */
> + uint16_t size;
> + domid_t foreign_domid; /* IFF gmfn_foreign */
> +
> + /* Indexes into space being mapped. */
> + GUEST_HANDLE(xen_ulong_t) idxs;
> +
> + /* GPFN in domid where the source mapping page should appear. */
> + GUEST_HANDLE(xen_pfn_t) gpfns;
> +};
> +DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap_range);
> +
> /*
> * Returns the pseudo-physical memory map as it was when the domain
> * was started (specified by XENMEM_set_memory_map).
> --
> 1.7.2.5
>
>
> #ifndef HYPERVISOR_VIRT_START
> diff --git a/include/xen/interface/memory.h
> b/include/xen/interface/memory.h index ad0dff5..5de2b36 100644
> --- a/include/xen/interface/memory.h
> +++ b/include/xen/interface/memory.h
> @@ -188,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
> /*** REMOVED ***/
> /*#define XENMEM_translate_gpfn_list 8*/
>
> +#define XENMEM_add_to_physmap_range 23
> +struct xen_add_to_physmap_range {
> + /* Which domain to change the mapping for. */
> + domid_t domid;
> + uint16_t space; /* => enum phys_map_space */
> +
> + /* Number of pages to go through */
> + uint16_t size;
> + domid_t foreign_domid; /* IFF gmfn_foreign */
> +
> + /* Indexes into space being mapped. */
> + GUEST_HANDLE(xen_ulong_t) idxs;
> +
> + /* GPFN in domid where the source mapping page should appear. */
> + GUEST_HANDLE(xen_pfn_t) gpfns;
Looking at your arm implementation in xen, doesn't look like you are
expecting idxs and gpfns to be contigous. In that case, shouldn't idxs
and gpfns be pointers, ie, they are sent down as arrays? Or does
GUEST_HANDLE do that, I can't seem to find where it's defined quickly.
thanks
Mukesh
On Wed, 24 Oct 2012 16:44:11 -0700
Mukesh Rathor <[email protected]> wrote:
> >
> > #ifndef HYPERVISOR_VIRT_START
> > diff --git a/include/xen/interface/memory.h
> > b/include/xen/interface/memory.h index ad0dff5..5de2b36 100644
> > --- a/include/xen/interface/memory.h
> > +++ b/include/xen/interface/memory.h
> > @@ -188,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
> > /*** REMOVED ***/
> > /*#define XENMEM_translate_gpfn_list 8*/
> >
> > +#define XENMEM_add_to_physmap_range 23
> > +struct xen_add_to_physmap_range {
> > + /* Which domain to change the mapping for. */
> > + domid_t domid;
> > + uint16_t space; /* => enum phys_map_space */
> > +
> > + /* Number of pages to go through */
> > + uint16_t size;
> > + domid_t foreign_domid; /* IFF gmfn_foreign */
> > +
> > + /* Indexes into space being mapped. */
> > + GUEST_HANDLE(xen_ulong_t) idxs;
> > +
> > + /* GPFN in domid where the source mapping page should appear.
> > */
> > + GUEST_HANDLE(xen_pfn_t) gpfns;
>
>
> Looking at your arm implementation in xen, doesn't look like you are
> expecting idxs and gpfns to be contigous. In that case, shouldn't idxs
> and gpfns be pointers, ie, they are sent down as arrays? Or does
> GUEST_HANDLE do that, I can't seem to find where it's defined quickly.
Never mind, I see it got corrected to XEN_GUEST_HANDLE in staging tree.
Still doesn't compile tho:
public/memory.h:246: error: expected specifier-qualifier-list before
‘__guest_handle_xen_ulong_t’
I'll figure it out.
thanks,
Mukesh
On Wed, 24 Oct 2012 17:07:46 -0700
Mukesh Rathor <[email protected]> wrote:
> On Wed, 24 Oct 2012 16:44:11 -0700
> Mukesh Rathor <[email protected]> wrote:
>
> > >
> > > #ifndef HYPERVISOR_VIRT_START
> > > diff --git a/include/xen/interface/memory.h
> > > b/include/xen/interface/memory.h index ad0dff5..5de2b36 100644
> > > --- a/include/xen/interface/memory.h
> > > +++ b/include/xen/interface/memory.h
> > > @@ -188,6 +188,24 @@
> > > DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap); /*** REMOVED ***/
> > > /*#define XENMEM_translate_gpfn_list 8*/
> > >
> > > +#define XENMEM_add_to_physmap_range 23
> > > +struct xen_add_to_physmap_range {
> > > + /* Which domain to change the mapping for. */
> > > + domid_t domid;
> > > + uint16_t space; /* => enum phys_map_space */
> > > +
> > > + /* Number of pages to go through */
> > > + uint16_t size;
> > > + domid_t foreign_domid; /* IFF gmfn_foreign */
> > > +
> > > + /* Indexes into space being mapped. */
> > > + GUEST_HANDLE(xen_ulong_t) idxs;
> > > +
> > > + /* GPFN in domid where the source mapping page should appear.
> > > */
> > > + GUEST_HANDLE(xen_pfn_t) gpfns;
> >
> >
> > Looking at your arm implementation in xen, doesn't look like you are
> > expecting idxs and gpfns to be contigous. In that case, shouldn't
> > idxs and gpfns be pointers, ie, they are sent down as arrays? Or
> > does GUEST_HANDLE do that, I can't seem to find where it's defined
> > quickly.
>
> Never mind, I see it got corrected to XEN_GUEST_HANDLE in staging
> tree. Still doesn't compile tho:
>
> public/memory.h:246: error: expected specifier-qualifier-list before
> ‘__guest_handle_xen_ulong_t’
>
> I'll figure it out.
Oh, yeah, missed:
+DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
compiles now.
On Thu, 2012-10-25 at 01:07 +0100, Mukesh Rathor wrote:
> On Wed, 24 Oct 2012 16:44:11 -0700
> Mukesh Rathor <[email protected]> wrote:
>
> > >
> > > #ifndef HYPERVISOR_VIRT_START
> > > diff --git a/include/xen/interface/memory.h
> > > b/include/xen/interface/memory.h index ad0dff5..5de2b36 100644
> > > --- a/include/xen/interface/memory.h
> > > +++ b/include/xen/interface/memory.h
> > > @@ -188,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
> > > /*** REMOVED ***/
> > > /*#define XENMEM_translate_gpfn_list 8*/
> > >
> > > +#define XENMEM_add_to_physmap_range 23
> > > +struct xen_add_to_physmap_range {
> > > + /* Which domain to change the mapping for. */
> > > + domid_t domid;
> > > + uint16_t space; /* => enum phys_map_space */
> > > +
> > > + /* Number of pages to go through */
> > > + uint16_t size;
> > > + domid_t foreign_domid; /* IFF gmfn_foreign */
> > > +
> > > + /* Indexes into space being mapped. */
> > > + GUEST_HANDLE(xen_ulong_t) idxs;
> > > +
> > > + /* GPFN in domid where the source mapping page should appear.
> > > */
> > > + GUEST_HANDLE(xen_pfn_t) gpfns;
> >
> >
> > Looking at your arm implementation in xen, doesn't look like you are
> > expecting idxs and gpfns to be contigous. In that case, shouldn't idxs
> > and gpfns be pointers, ie, they are sent down as arrays? Or does
> > GUEST_HANDLE do that, I can't seem to find where it's defined quickly.
>
> Never mind, I see it got corrected to XEN_GUEST_HANDLE in staging tree.
The macro is called XEN_GUEST_HANDLE in Xen and just GUEST_HANDLE in
Linux.
> Still doesn't compile tho:
>
> public/memory.h:246: error: expected specifier-qualifier-list before
> ‘__guest_handle_xen_ulong_t’
>
> I'll figure it out.
Looks like you've got it all sorted?
Ian.
On Wed, 24 Oct 2012 14:19:37 +0100
Ian Campbell <[email protected]> wrote:
> Squeezing the necessary fields into the existing XENMEM_add_to_physmap
> interface was proving to be a bit tricky so we have decided to go with
> a new interface upstream (the XENMAPSPACE_gmfn_foreign interface using
> XENMEM_add_to_physmap was never committed anywhere). This interface
> also allows for batching which was impossible to support at the same
> time as foreign mfns in the old interface.
>
> This reverts the relevant parts of "PVH: basic and header changes,
> elfnote changes, ..." and followups and trivially converts
> pvh_add_to_xen_p2m over.
>
> Signed-off-by: Ian Campbell <[email protected]>
> Acked-by: Stefano Stabellini <[email protected]>
Ok, I made the change on the xen side for x86 and tested it out. Works
fine. Second ack.
thanks,
Mukesh
On Thu, 25 Oct 2012 08:46:59 +0100
Ian Campbell <[email protected]> wrote:
> On Thu, 2012-10-25 at 01:07 +0100, Mukesh Rathor wrote:
> > On Wed, 24 Oct 2012 16:44:11 -0700
> > Mukesh Rathor <[email protected]> wrote:
> >
> > > >
> > > > + /* Indexes into space being mapped. */
> > > > + GUEST_HANDLE(xen_ulong_t) idxs;
> > > > +
> > > > + /* GPFN in domid where the source mapping page should
> > > > appear. */
> > > > + GUEST_HANDLE(xen_pfn_t) gpfns;
> > >
> > >
> > > Looking at your arm implementation in xen, doesn't look like you
> > > are expecting idxs and gpfns to be contigous. In that case,
> > > shouldn't idxs and gpfns be pointers, ie, they are sent down as
> > > arrays? Or does GUEST_HANDLE do that, I can't seem to find where
> > > it's defined quickly.
> >
> > Never mind, I see it got corrected to XEN_GUEST_HANDLE in staging
> > tree.
>
> The macro is called XEN_GUEST_HANDLE in Xen and just GUEST_HANDLE in
> Linux.
>
> > Still doesn't compile tho:
> >
> > public/memory.h:246: error: expected specifier-qualifier-list before
> > ‘__guest_handle_xen_ulong_t’
> >
> > I'll figure it out.
>
> Looks like you've got it all sorted?
Yup. I made the change on xen side and added this patch to my tree
and got it working after reverting Konrad's setup.c changes. Not sure
if you need an ack from x86, but if you do:
Acked-by: Mukesh Rathor <[email protected]>
thanks
Mukesh
On Fri, 2012-10-26 at 02:39 +0100, Mukesh Rathor wrote:
> Yup. I made the change on xen side and added this patch to my tree
> and got it working after reverting Konrad's setup.c changes. Not sure
> if you need an ack from x86, but if you do:
>
> Acked-by: Mukesh Rathor <[email protected]>
The more ack's the merrier, thanks!
On Wed, Oct 24, 2012 at 02:19:16PM +0100, Ian Campbell wrote:
> This is rebased onto 0e9e3e306c7e (AKA current Linus, which now includes
> the previously prerequisite series "xen: build fixes and interface
> tweaks") and Konrad's stable/pvh.v5 branch.
>
> For convenience I've also pushed to
> git://xenbits.xen.org/people/ianc/linux.git
> arm-privcmd-on-x86-pvh5
> Note that this contains my merge of Konrad's branch into Linus' tree at
> the base. You might want to cherry pick it rather than merge it.
Applied them and stuck them in 'devel/pvh.v6' - which is based on v3.7-rc3.
Will test them overnight.
>
> Ian.