On Fri, 14 Jan 2011, Daniel De Graaf wrote:
> HVM does not allow direct PTE modification, so instead we request
> that Xen change its internal p2m mappings on the allocated pages and
> map the memory into userspace normally.
>
> Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
> ---
> drivers/xen/gntdev.c | 117
> +++++++++++++++++++++++++++++++--------------
> drivers/xen/grant-table.c | 6 ++
> 2 files changed, 87 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
> index 8a12857..1931657 100644
> --- a/drivers/xen/gntdev.c
> +++ b/drivers/xen/gntdev.c
> @@ -32,6 +32,7 @@
> #include <linux/sched.h>
> #include <linux/spinlock.h>
> #include <linux/slab.h>
> +#include <linux/highmem.h>
>
> #include <xen/xen.h>
> #include <xen/grant_table.h>
> @@ -52,6 +53,8 @@ MODULE_PARM_DESC(limit, "Maximum number of grants that may
> be mapped by "
>
> static atomic_t pages_mapped = ATOMIC_INIT(0);
>
> +static int use_ptemod = 0;
> +
> struct gntdev_priv {
> struct list_head maps;
> /* lock protects maps from concurrent changes */
> @@ -184,6 +187,9 @@ static void gntdev_put_map(struct grant_map *map)
>
> atomic_sub(map->count, &pages_mapped);
>
> + if (!use_ptemod)
> + unmap_grant_pages(map, 0, map->count);
> +
> for (i = 0; i < map->count; i++) {
> if (map->pages[i])
> __free_page(map->pages[i]);
> @@ -212,9 +218,12 @@ static int find_grant_ptes(pte_t *pte, pgtable_t token,
> static int map_grant_pages(struct grant_map *map)
> {
> int i, flags, err = 0;
> + phys_addr_t addr;
> struct gnttab_map_grant_ref* map_ops = NULL;
>
> - flags = GNTMAP_host_map | GNTMAP_application_map | GNTMAP_contains_pte;
> + flags = GNTMAP_host_map;
> + if (use_ptemod)
> + flags |= GNTMAP_application_map | GNTMAP_contains_pte;
> if (map->is_ro)
> flags |= GNTMAP_readonly;
>
> @@ -224,7 +233,11 @@ static int map_grant_pages(struct grant_map *map)
> goto out;
>
> for(i=0; i < map->count; i++) {
> - gnttab_set_map_op(&map_ops[i], map->pginfo[i].pte_maddr, flags,
> + if (use_ptemod)
> + addr = map->pginfo[i].pte_maddr;
> + else
> + addr =
> (phys_addr_t)pfn_to_kaddr(page_to_pfn(map->pages[i]));
> + gnttab_set_map_op(&map_ops[i], addr, flags,
> map->pginfo[i].target.ref,
> map->pginfo[i].target.domid);
> }
If I am not mistaken you are asking Xen to modify the virtual kernel
mappings of map->pages, but it is not enough to have correctly working
userspace mappings of map->pages: you need gnttab_map_refs to correctly
fix the p2m and add an entry to m2p_override too.
However in the last gntdev patch series I sent, requests with
!GNTMAP_contains_pte are not added to m2p_override and the p2m entries
of map->pages are not updated either.
Therefore you probably need this (untested) patch to make it work:
---
Add support for !GNTMAP_contains_pte mappings to gnttab_map_refs
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 9ef54eb..7d6d2ba 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -459,12 +459,38 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
return ret;
for (i = 0; i < count; i++) {
- /* m2p override only supported for GNTMAP_contains_pte mappings
*/
- if (!(map_ops[i].flags & GNTMAP_contains_pte))
- continue;
- pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
- (map_ops[i].host_addr & ~PAGE_MASK));
- mfn = pte_mfn(*pte);
+ if ((map_ops[i].flags & GNTMAP_contains_pte)) {
+ pte = (pte_t *)
(mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
+ (map_ops[i].host_addr & ~PAGE_MASK));
+ mfn = pte_mfn(*pte);
+ } else {
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ unsigned long addr = map_ops[i].host_addr;
+ pgd = pgd_offset(current->active_mm, addr);
+ if (pgd_none(*pgd)) {
+ printk(KERN_WARNING "invalid pgd found, skip
address=%lx\n", addr);
+ continue;
+ }
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud)) {
+ printk(KERN_WARNING "invalid pud found, skip
address=%lx\n", addr);
+ continue;
+ }
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd)) {
+ printk(KERN_WARNING "invalid pmd found, skip
address=%lx\n", addr);
+ continue;
+ }
+ pte = pte_offset_map(pmd, addr);
+ if (pte_none(*pte)) {
+ printk(KERN_WARNING "invalid pte found, skip
address=%lx\n", addr);
+ continue;
+ }
+ mfn = pte_mfn(*pte);
+ pte_unmap(pte);
+ }
ret = m2p_add_override(mfn, pages[i]);
if (ret)
return ret;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|