fprintf(outfile, "const struct vdso_image %s = {\n", name);
        fprintf(outfile, "\t.data = raw_data,\n");
        fprintf(outfile, "\t.size = %lu,\n", data_size);
-       fprintf(outfile, "\t.pages = pages,\n");
+       fprintf(outfile, "\t.text_mapping = {\n");
+       fprintf(outfile, "\t\t.name = \"[vdso]\",\n");
+       fprintf(outfile, "\t\t.pages = pages,\n");
+       fprintf(outfile, "\t},\n");
        if (alt_sec) {
                fprintf(outfile, "\t.alt = %lu,\n",
                        (unsigned long)alt_sec->sh_offset);
 
 
        BUG_ON(image->size % PAGE_SIZE != 0);
        for (i = 0; i < npages; i++)
-               image->pages[i] = virt_to_page(image->data + i*PAGE_SIZE);
+               image->text_mapping.pages[i] =
+                       virt_to_page(image->data + i*PAGE_SIZE);
 
        apply_alternatives((struct alt_instr *)(image->data + image->alt),
                           (struct alt_instr *)(image->data + image->alt +
        unsigned long addr;
        int ret = 0;
        static struct page *no_pages[] = {NULL};
+       static struct vm_special_mapping vvar_mapping = {
+               .name = "[vvar]",
+               .pages = no_pages,
+       };
 
        if (calculate_addr) {
                addr = vdso_addr(current->mm->start_stack,
        /*
         * MAYWRITE to allow gdb to COW and set breakpoints
         */
-       ret = install_special_mapping(mm,
-                                     addr,
-                                     image->size,
-                                     VM_READ|VM_EXEC|
-                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-                                     image->pages);
+       vma = _install_special_mapping(mm,
+                                      addr,
+                                      image->size,
+                                      VM_READ|VM_EXEC|
+                                      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+                                      &image->text_mapping);
 
-       if (ret)
+       if (IS_ERR(vma)) {
+               ret = PTR_ERR(vma);
                goto up_fail;
+       }
 
        vma = _install_special_mapping(mm,
                                       addr + image->size,
                                       image->sym_end_mapping - image->size,
                                       VM_READ,
-                                      no_pages);
+                                      &vvar_mapping);
 
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);
 
        return 1;
 }
 
+static int special_mapping_fault(struct vm_area_struct *vma,
+                                struct vm_fault *vmf);
+
+/*
+ * Having a close hook prevents vma merging regardless of flags.
+ */
+static void special_mapping_close(struct vm_area_struct *vma)
+{
+}
+
+static const char *special_mapping_name(struct vm_area_struct *vma)
+{
+       return ((struct vm_special_mapping *)vma->vm_private_data)->name;
+}
+
+static const struct vm_operations_struct special_mapping_vmops = {
+       .close = special_mapping_close,
+       .fault = special_mapping_fault,
+       .name = special_mapping_name,
+};
+
+static const struct vm_operations_struct legacy_special_mapping_vmops = {
+       .close = special_mapping_close,
+       .fault = special_mapping_fault,
+};
 
 static int special_mapping_fault(struct vm_area_struct *vma,
                                struct vm_fault *vmf)
         */
        pgoff = vmf->pgoff - vma->vm_pgoff;
 
-       for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
+       if (vma->vm_ops == &legacy_special_mapping_vmops)
+               pages = vma->vm_private_data;
+       else
+               pages = ((struct vm_special_mapping *)vma->vm_private_data)->
+                       pages;
+
+       for (; pgoff && *pages; ++pages)
                pgoff--;
 
        if (*pages) {
        return VM_FAULT_SIGBUS;
 }
 
-/*
- * Having a close hook prevents vma merging regardless of flags.
- */
-static void special_mapping_close(struct vm_area_struct *vma)
-{
-}
-
-static const struct vm_operations_struct special_mapping_vmops = {
-       .close = special_mapping_close,
-       .fault = special_mapping_fault,
-};
-
-/*
- * Called with mm->mmap_sem held for writing.
- * Insert a new vma covering the given region, with the given flags.
- * Its pages are supplied by the given array of struct page *.
- * The array can be shorter than len >> PAGE_SHIFT if it's null-terminated.
- * The region past the last page supplied will always produce SIGBUS.
- * The array pointer and the pages it points to are assumed to stay alive
- * for as long as this mapping might exist.
- */
-struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
-                           unsigned long addr, unsigned long len,
-                           unsigned long vm_flags, struct page **pages)
+static struct vm_area_struct *__install_special_mapping(
+       struct mm_struct *mm,
+       unsigned long addr, unsigned long len,
+       unsigned long vm_flags, const struct vm_operations_struct *ops,
+       void *priv)
 {
        int ret;
        struct vm_area_struct *vma;
        vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND | VM_SOFTDIRTY;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
-       vma->vm_ops = &special_mapping_vmops;
-       vma->vm_private_data = pages;
+       vma->vm_ops = ops;
+       vma->vm_private_data = priv;
 
        ret = insert_vm_struct(mm, vma);
        if (ret)
        return ERR_PTR(ret);
 }
 
+/*
+ * Called with mm->mmap_sem held for writing.
+ * Insert a new vma covering the given region, with the given flags.
+ * Its pages are supplied by the given array of struct page *.
+ * The array can be shorter than len >> PAGE_SHIFT if it's null-terminated.
+ * The region past the last page supplied will always produce SIGBUS.
+ * The array pointer and the pages it points to are assumed to stay alive
+ * for as long as this mapping might exist.
+ */
+struct vm_area_struct *_install_special_mapping(
+       struct mm_struct *mm,
+       unsigned long addr, unsigned long len,
+       unsigned long vm_flags, const struct vm_special_mapping *spec)
+{
+       return __install_special_mapping(mm, addr, len, vm_flags,
+                                        &special_mapping_vmops, (void *)spec);
+}
+
 int install_special_mapping(struct mm_struct *mm,
                            unsigned long addr, unsigned long len,
                            unsigned long vm_flags, struct page **pages)
 {
-       struct vm_area_struct *vma = _install_special_mapping(mm,
-                           addr, len, vm_flags, pages);
+       struct vm_area_struct *vma = __install_special_mapping(
+               mm, addr, len, vm_flags, &legacy_special_mapping_vmops,
+               (void *)pages);
 
        if (IS_ERR(vma))
                return PTR_ERR(vma);