fix broken IA64 forieng domain page mapping.
Cset 11726 broke IA64 foreign domain page mapping accidentally because
xenLinux/IA64 already uses vma->vm_private_data for its own purpose.
Introduced arch specific functions to check one-shot operation
of privcmd mmap.


On Thu, Oct 12, 2006 at 11:00:34AM +0100, Keir Fraser wrote:
> On 12/10/06 03:35, "Zhang, Jingke" <[EMAIL PROTECTED]> wrote:
> 
> > Hi,
> >     Cset 11725 is OK.
> >     In Cset 11726, IPF can not create both xenU and VTI domains.
> 
> Sorry about that. It can't be hard to fix, I'm sure. We'll delay the release
> if you can sort out a fix asap.
> 
>  -- Keir
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> [EMAIL PROTECTED]
> http://lists.xensource.com/xen-devel

-- 
yamahata
# HG changeset patch
# User [EMAIL PROTECTED]
# Date 1160650695 -32400
# Node ID e265f21c5d694c6cf85472bb62cc2cab4008d911
# Parent  f7d65fb7299b95b8b6d3a44134a9f2af211393c6
fix broken IA64 forieng domain page mapping.
Cset 11726 broke IA64 foreign domain page mapping accidentally because
xenLinux/IA64 already uses vma->vm_private_data for its own purpose.
Introduced arch specific functions to check one-shot operation
of privcmd mmap.
PATCHNAME: fix_privcmd

Signed-off-by: Isaku Yamahata <[EMAIL PROTECTED]>

diff -r f7d65fb7299b -r e265f21c5d69 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Tue Oct 10 22:04:01 
2006 +0100
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Thu Oct 12 19:58:15 
2006 +0900
@@ -546,6 +546,7 @@ struct xen_ia64_privcmd_range {
 };
 
 struct xen_ia64_privcmd_vma {
+       int                             is_privcmd_mmapped;
        struct xen_ia64_privcmd_range*  range;
 
        unsigned long                   num_entries;
@@ -684,12 +685,15 @@ static void
 static void
 xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
 {
+       struct xen_ia64_privcmd_vma* old_privcmd_vma = (struct 
xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_vma* privcmd_vma = (struct 
xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
 
        atomic_inc(&privcmd_range->ref_count);
        // vm_op->open() can't fail.
        privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
+       // copy original value if necessary
+       privcmd_vma->is_privcmd_mmapped = old_privcmd_vma->is_privcmd_mmapped;
 
        __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
 }
@@ -722,6 +726,23 @@ xen_ia64_privcmd_vma_close(struct vm_are
                kfree(privcmd_range->res);
                vfree(privcmd_range);
        }
+}
+
+int
+privcmd_is_vma_mmapped(struct vm_area_struct *vma)
+{
+       struct xen_ia64_privcmd_vma* privcmd_vma =
+               (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+       return privcmd_vma->is_privcmd_mmapped;
+}
+
+void
+privcmd_mark_vma_mmapped(struct vm_area_struct *vma)
+{
+       struct xen_ia64_privcmd_vma* privcmd_vma =
+               (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+       BUG_ON(privcmd_vma->is_privcmd_mmapped);
+       privcmd_vma->is_privcmd_mmapped = 1;
 }
 
 int
@@ -749,6 +770,8 @@ privcmd_mmap(struct file * file, struct 
        if (privcmd_vma == NULL) {
                goto out_enomem1;
        }
+       privcmd_vma->is_privcmd_mmapped = 0;
+
        res = kzalloc(sizeof(*res), GFP_KERNEL);
        if (res == NULL) {
                goto out_enomem1;
diff -r f7d65fb7299b -r e265f21c5d69 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Tue Oct 10 
22:04:01 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Thu Oct 12 
19:58:15 2006 +0900
@@ -34,6 +34,10 @@
 
 static struct proc_dir_entry *privcmd_intf;
 static struct proc_dir_entry *capabilities_intf;
+#ifndef HAVE_ARCH_PRIVCMD_MMAP
+static int privcmd_is_vma_mmapped(struct vm_area_struct *vma);
+static void privcmd_mark_vma_mmapped(struct vm_area_struct *vma);
+#endif
 
 static int privcmd_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long data)
@@ -122,11 +126,12 @@ static int privcmd_ioctl(struct inode *i
 
                vma = find_vma(mm, msg.va);
                rc = -EINVAL;
-               if (!vma || (msg.va != vma->vm_start) || vma->vm_private_data)
+               if (!vma || (msg.va != vma->vm_start) ||
+                   privcmd_is_vma_mmapped(vma))
                        goto mmap_out;
 
                /* Mapping is a one-shot operation per vma. */
-               vma->vm_private_data = (void *)1;
+               privcmd_mark_vma_mmapped(vma);
 
                va = vma->vm_start;
 
@@ -190,13 +195,13 @@ static int privcmd_ioctl(struct inode *i
                if (!vma ||
                    (m.addr != vma->vm_start) ||
                    ((m.addr + (m.num<<PAGE_SHIFT)) != vma->vm_end) ||
-                   vma->vm_private_data) {
+                   privcmd_is_vma_mmapped(vma)) {
                        up_read(&mm->mmap_sem);
                        return -EINVAL;
                }
 
                /* Mapping is a one-shot operation per vma. */
-               vma->vm_private_data = (void *)1;
+               privcmd_mark_vma_mmapped(vma);
 
                p = m.arr;
                addr = m.addr;
@@ -227,6 +232,16 @@ static int privcmd_ioctl(struct inode *i
 }
 
 #ifndef HAVE_ARCH_PRIVCMD_MMAP
+static int privcmd_is_vma_mmapped(struct vm_area_struct *vma)
+{
+       return vma->vm_private_data;
+}
+
+static void privcmd_mark_vma_mmapped(struct vm_area_struct *vma)
+{
+       vma->vm_private_data = (void *)1;
+}
+
 static struct page *privcmd_nopage(struct vm_area_struct *vma,
                                   unsigned long address,
                                   int *type)
diff -r f7d65fb7299b -r e265f21c5d69 
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Tue Oct 10 
22:04:01 2006 +0100
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Thu Oct 12 
19:58:15 2006 +0900
@@ -138,6 +138,8 @@ int direct_remap_pfn_range(struct vm_are
                           pgprot_t prot,
                           domid_t  domid);
 struct file;
+int privcmd_is_vma_mmapped(struct vm_area_struct *vma);
+void privcmd_mark_vma_mmapped(struct vm_area_struct *vma);
 int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
 #define HAVE_ARCH_PRIVCMD_MMAP
 
_______________________________________________
Xen-ia64-devel mailing list
[email protected]
http://lists.xensource.com/xen-ia64-devel

Reply via email to