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: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Subject: Re: [Xen-devel] Re: Linux Stubdom Problem
From: Jiageng Yu <yujiageng734@xxxxxxxxx>
Date: Thu, 27 Oct 2011 22:56:43 +0800
Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>, Tim Deegan <tim@xxxxxxx>, Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Keir Fraser <keir.xen@xxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxx>, Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
Delivery-date: Fri, 28 Oct 2011 09:23:46 -0700
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=lSJVjCsuMtqITD0KQSUyWkeBa295MRNiyoIaJ7CRceo=; b=Um3V9Oy1q21MpU1ueWcyrgn3+RwwstggcohNO5fy1K14cbjPA97ptujGJihey+fnaw 8m27bRETLDJMoZtvhekLCndBGp6GpAG72AbpNQgnlKyKwgzBMDzO0iVe7Pm4ihPPjIB/ gVL6SC9mPE51FxsQT/1SG9zSC0Hs2g1KCQNwc=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <alpine.DEB.2.00.1109151110020.12963@kaball-desktop>
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> <alpine.DEB.2.00.1109151110020.12963@kaball-desktop>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
2011/9/15 Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>:
> 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);
>>
>


Hi Stefano,

        I have some progress in linux based stubdom project. As shown in the
attached video, I have started the emulated vga device in the linux
based stubdom.

        In a short conclusion, for the linux based stubdom, there are two
major problems about vga device emulation. The first is the vram
mapping, which we discussed a lot previously and handled it. Another
is the vga BIOS mapping (address 0xc0000-0xc8fff of hvm guest).

        I found the vga BIOS mapping problem in remap_area_mfn_pte_fn()
function. The pte_mkspecial() will return invalid value when I try to
map 0xc0000-0xc8fff into linux based stubdom.

pte_mkspecial()
        ->pte_set_flags()
                ->native_pte_val()
                ->native_make_pte()

        According to my test, the root cause of vga BIOS mapping problem is
native_xxx functions. We could avoid the problem by invoking functions
defined in paravirt.h instead. The patch is as follows. But I think it
is not a good way to handle the problem. Maybe you can give me some
suggestions.

        I also found the hard disk didn’t work well. I will investigate it 
these days.


--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2639,12 +2640,16 @@ static int remap_area_mfn_pte_fn(pte_t *ptep,
pgtable_t token,
                                 unsigned long addr, void *data)
 {
        struct remap_data *rmd = data;
-       pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
+    if((rmd->mfn & 0xfffffff0) == 0xc0){
+           pte_t pte = pfn_pte(rmd->mfn++, rmd->prot);
+           rmd->mmu_update->val = pte_val(pte);
+    }else{
+           pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
+           rmd->mmu_update->val = pte_val_ma(pte);
+    }

        rmd->mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr;
-       rmd->mmu_update->val = pte_val_ma(pte);
        rmd->mmu_update++;
-
        return 0;
 }

Attachment: out.ogv
Description: video/ogg

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • Re: [Xen-devel] Re: Linux Stubdom Problem, Jiageng Yu <=