[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



2011/9/2 Keir Fraser <keir.xen@xxxxxxxxx>:
> On 02/09/2011 14:09, "Stefano Stabellini" <stefano.stabellini@xxxxxxxxxxxxx>
> wrote:
>
>>> Why? ÂHVMloader is already tightly coupled to the hypervisor and the
>>> toostack - special cases for stubdoms should be fine.
>>
>> I think think that leaking the implementation details of the device
>> model into hvmloader should be avoided, but obviously if there are no
>> alternatives, it can be done.
>
> This is a fair and more general point, that we don't want fragile
> dependencies on qemu now that we are using upstream. But as I say that's a
> more general point on our policy regarding qemu, rather than something
> specifically concerning hvmloader.
>
> Â-- Keir
>
>
>

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?

    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);
+
+            rmd.mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr |
+                                        MMU_NORMAL_PT_UPDATE;
+            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);
+    }
+
+out:
+       flush_tlb_all();
+       return err;
+}
+EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range2);
 #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);
+        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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.