WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] Re: Linux Stubdom Problem

To: Jiageng Yu <yujiageng734@xxxxxxxxx>
Subject: Re: [Xen-devel] Re: Linux Stubdom Problem
From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Date: Thu, 15 Sep 2011 12:13:09 +0100
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <keir.xen@xxxxxxxxx>, Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>, Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>, Tim Deegan <tim@xxxxxxx>, Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Konrad, Anthony PERARD <anthony.perard@xxxxxxxxx>, Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
Delivery-date: Thu, 15 Sep 2011 04:06:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <CAJ0pt17eoZbEnmziLaSd1Cxi+sU90rJ-c8TSgt+ikE3wZj1jhA@xxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <alpine.DEB.2.00.1109021401000.12963@kaball-desktop> <CA8694A1.20379%keir.xen@xxxxxxxxx> <CAJ0pt17eoZbEnmziLaSd1Cxi+sU90rJ-c8TSgt+ikE3wZj1jhA@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Alpine 2.00 (DEB 1167 2008-08-23)
On Wed, 14 Sep 2011, Jiageng Yu wrote:
> Hi Stefano,
> 
>      I just have a prototype of vram mapping and test it now. The
> implementation of linux-stubdom kernel part is as follows.
> xen_remap_domain_mfn_range2 function maps foreign dom's physical
> address into linux kernel space. It is similar to
> xen_remap_domain_mfn_range. But xen_remap_domain_mfn_range is used to
> map foreign pages into linux user space.
> 
>     But the page info seems wrong after executing xen_remap_domain_mfn_range2.
> 
>     struct page *page=pfn_to_page(vmalloc_to_pfn(info->fb));
> 
>     The page->_count = 0xc2c2c2c2. It is very strange.
> 
>     Did I do the right thing?
> 

use page_address instead of pfn_to_page to find the struct page


>     Greeting.
> 
> Jiageng Yu.
> 
> 
> diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
> index 204e3ba..72a7808 100644
> --- a/arch/x86/xen/mmu.c
> +++ b/arch/x86/xen/mmu.c
> @@ -2693,6 +2693,73 @@ out:
>  }
>  EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
> 
> +int xen_remap_domain_mfn_range2(unsigned long addr,unsigned long gpfn,
> +                int nr, unsigned domid)
> +{
> +    struct remap_data rmd;
> +    struct mmu_update mmu_update[REMAP_BATCH_SIZE];
> +    int level,i,batch,nr_page = nr;
> +    unsigned long range;
> +    int err = 0;
> +    unsigned long vaddr,base_addr = addr;
> +    pte_t pte,*ptep;
> +
> +    rmd.mfn = gpfn;
> +    rmd.prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |
> _PAGE_IOMAP);
> +
> +    while(nr_page) {
> +        batch = min(REMAP_BATCH_SIZE, nr);
> +        range = (unsigned long)batch << PAGE_SHIFT;
> +
> +        rmd.mmu_update = mmu_update;
> +
> +        for(i=0; i < batch; i++){
> +            pte = pte_mkspecial(pfn_pte(rmd.mfn++, rmd.prot));
> +            vaddr = base_addr + i*PAGE_SIZE;
> +            ptep = lookup_address(vaddr, &level);

you need to check if ptep is valid here and the level is PG_LEVEL_4K

> +            rmd.mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr |
> +                                        MMU_NORMAL_PT_UPDATE;

you can use pte_mfn(*ptep) instead of arbitrary_virt_to_machine


> +            rmd.mmu_update->val = pte_val_ma(pte);
> +            rmd.mmu_update++;
> +        }
> +
> +        err = -EFAULT;
> +        if(HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0)
> +            goto out;
> +
> +        nr_page -= batch;
> +        base_addr += range;
> +    }
> +
> +    err = 0;
> +
> +    base_addr = addr;
> +    for(i=0; i < nr; i++){
> +        vaddr = base_addr + i*PAGE_SIZE;
> +        set_phys_to_machine(vmalloc_to_pfn(vaddr),
> +                arbitrary_virt_to_machine(vaddr).maddr >> PAGE_SHIFT);
> +    }

The second argument (mfn) to set_phys_to_machine is wrong:
arbitrary_virt_to_machine ends up calling virt_to_machine if
virt_addr_valid. You need to manually call pte_mfn:

/* the ptep content has been updated by Xen so we can lookup the foreign
 * mfn from the pte now */
pte = lookup_address(vaddr, &level);
BUG_ON(pte == NULL);
offset = vaddr & ~PAGE_MASK;
mfn = XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset);


> +
> +out:
> +     flush_tlb_all();
> +     return err;
> +}
> +EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range2);

the name should be changed to xen_remap_foreign_gpfn_range


>  #ifdef CONFIG_XEN_PVHVM
>  static void xen_hvm_exit_mmap(struct mm_struct *mm)
>  {
> diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
> index dc72563..82da2ee 100644
> --- a/drivers/video/xen-fbfront.c
> +++ b/drivers/video/xen-fbfront.c
> @@ -25,8 +25,12 @@
>  #include <linux/module.h>
>  #include <linux/vmalloc.h>
>  #include <linux/mm.h>
> +#include <linux/sched.h>
> +#include <asm/pgtable.h>
> +#include <asm/page.h>
> 
>  #include <asm/xen/hypervisor.h>
> +#include <asm/xen/page.h>
> 
>  #include <xen/xen.h>
>  #include <xen/events.h>
> @@ -34,6 +38,7 @@
>  #include <xen/interface/io/fbif.h>
>  #include <xen/interface/io/protocols.h>
>  #include <xen/xenbus.h>
> +#include <xen/xen-ops.h>
> 
>  struct xenfb_info {
>       unsigned char           *fb;
> @@ -62,6 +67,12 @@ module_param_array(video, int, NULL, 0);
>  MODULE_PARM_DESC(video,
>       "Video memory size in MB, width, height in pixels (default 2,800,600)");
> 
> +static unsigned long foreign_vaddr = 0;
> +module_param(foreign_vaddr, ulong, S_IRUGO);
> +
> +static unsigned long foreign_domid = 0;
> +module_param(foreign_domid, ulong, S_IRUGO);
> +
>  static void xenfb_make_preferred_console(void);
>  static int xenfb_remove(struct xenbus_device *);
>  static void xenfb_init_shared_page(struct xenfb_info *, struct fb_info *);
> @@ -398,7 +408,17 @@ static int __devinit xenfb_probe(struct xenbus_device 
> *dev,
>       if (info->fb == NULL)
>               goto error_nomem;
>       memset(info->fb, 0, fb_size);
> -
> +    if((foreign_vaddr != 0) && (foreign_domid != 0)){
> +        ret = xen_remap_domain_mfn_range2((unsigned long)(info->fb),
> +                                    foreign_vaddr >> PAGE_SHIFT,
> +                                    fb_size >> PAGE_SHIFT, foreign_domid);

you should rename foreign_vaddr to foreign_gpfn and pass the gpfn value
that is the ram_addr (page shifted) passed to xen_ram_alloc in qemu.

> +        if(ret < 0){
> +            printk("Can not remap vram of hvm guest.\n");
> +            goto error;
> +        }
> +    }
>       info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> 
>       info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages);
> diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
> index 4349e89..1554531 100644
> --- a/include/xen/xen-ops.h
> +++ b/include/xen/xen-ops.h
> @@ -20,6 +20,10 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
>                              unsigned long mfn, int nr,
>                              pgprot_t prot, unsigned domid);
> 
> +int xen_remap_domain_mfn_range2(unsigned long addr,unsigned long mfn,
> +                int nr, unsigned domid);
>  extern unsigned long *xen_contiguous_bitmap;
>  int xen_create_contiguous_region(unsigned long vstart, unsigned int order,
>                               unsigned int address_bits);
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>