linux/arch/powerpc/kernel/vdso.c
<<
>>
Prefs
   1
   2/*
   3 *    Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
   4 *                       <benh@kernel.crashing.org>
   5 *
   6 *  This program is free software; you can redistribute it and/or
   7 *  modify it under the terms of the GNU General Public License
   8 *  as published by the Free Software Foundation; either version
   9 *  2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/errno.h>
  14#include <linux/sched.h>
  15#include <linux/kernel.h>
  16#include <linux/mm.h>
  17#include <linux/smp.h>
  18#include <linux/stddef.h>
  19#include <linux/unistd.h>
  20#include <linux/slab.h>
  21#include <linux/user.h>
  22#include <linux/elf.h>
  23#include <linux/security.h>
  24#include <linux/bootmem.h>
  25#include <linux/memblock.h>
  26
  27#include <asm/pgtable.h>
  28#include <asm/system.h>
  29#include <asm/processor.h>
  30#include <asm/mmu.h>
  31#include <asm/mmu_context.h>
  32#include <asm/prom.h>
  33#include <asm/machdep.h>
  34#include <asm/cputable.h>
  35#include <asm/sections.h>
  36#include <asm/firmware.h>
  37#include <asm/vdso.h>
  38#include <asm/vdso_datapage.h>
  39
  40#include "setup.h"
  41
  42#undef DEBUG
  43
  44#ifdef DEBUG
  45#define DBG(fmt...) printk(fmt)
  46#else
  47#define DBG(fmt...)
  48#endif
  49
  50/* Max supported size for symbol names */
  51#define MAX_SYMNAME     64
  52
  53/* The alignment of the vDSO */
  54#define VDSO_ALIGNMENT  (1 << 16)
  55
  56extern char vdso32_start, vdso32_end;
  57static void *vdso32_kbase = &vdso32_start;
  58static unsigned int vdso32_pages;
  59static struct page **vdso32_pagelist;
  60unsigned long vdso32_sigtramp;
  61unsigned long vdso32_rt_sigtramp;
  62
  63#ifdef CONFIG_PPC64
  64extern char vdso64_start, vdso64_end;
  65static void *vdso64_kbase = &vdso64_start;
  66static unsigned int vdso64_pages;
  67static struct page **vdso64_pagelist;
  68unsigned long vdso64_rt_sigtramp;
  69#endif /* CONFIG_PPC64 */
  70
  71static int vdso_ready;
  72
  73/*
  74 * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
  75 * Once the early boot kernel code no longer needs to muck around
  76 * with it, it will become dynamically allocated
  77 */
  78static union {
  79        struct vdso_data        data;
  80        u8                      page[PAGE_SIZE];
  81} vdso_data_store __page_aligned_data;
  82struct vdso_data *vdso_data = &vdso_data_store.data;
  83
  84/* Format of the patch table */
  85struct vdso_patch_def
  86{
  87        unsigned long   ftr_mask, ftr_value;
  88        const char      *gen_name;
  89        const char      *fix_name;
  90};
  91
  92/* Table of functions to patch based on the CPU type/revision
  93 *
  94 * Currently, we only change sync_dicache to do nothing on processors
  95 * with a coherent icache
  96 */
  97static struct vdso_patch_def vdso_patches[] = {
  98        {
  99                CPU_FTR_COHERENT_ICACHE, CPU_FTR_COHERENT_ICACHE,
 100                "__kernel_sync_dicache", "__kernel_sync_dicache_p5"
 101        },
 102        {
 103                CPU_FTR_USE_TB, 0,
 104                "__kernel_gettimeofday", NULL
 105        },
 106        {
 107                CPU_FTR_USE_TB, 0,
 108                "__kernel_clock_gettime", NULL
 109        },
 110        {
 111                CPU_FTR_USE_TB, 0,
 112                "__kernel_clock_getres", NULL
 113        },
 114        {
 115                CPU_FTR_USE_TB, 0,
 116                "__kernel_get_tbfreq", NULL
 117        },
 118};
 119
 120/*
 121 * Some infos carried around for each of them during parsing at
 122 * boot time.
 123 */
 124struct lib32_elfinfo
 125{
 126        Elf32_Ehdr      *hdr;           /* ptr to ELF */
 127        Elf32_Sym       *dynsym;        /* ptr to .dynsym section */
 128        unsigned long   dynsymsize;     /* size of .dynsym section */
 129        char            *dynstr;        /* ptr to .dynstr section */
 130        unsigned long   text;           /* offset of .text section in .so */
 131};
 132
 133struct lib64_elfinfo
 134{
 135        Elf64_Ehdr      *hdr;
 136        Elf64_Sym       *dynsym;
 137        unsigned long   dynsymsize;
 138        char            *dynstr;
 139        unsigned long   text;
 140};
 141
 142
 143#ifdef __DEBUG
 144static void dump_one_vdso_page(struct page *pg, struct page *upg)
 145{
 146        printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
 147               page_count(pg),
 148               pg->flags);
 149        if (upg && !IS_ERR(upg) /* && pg != upg*/) {
 150                printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg)
 151                                                       << PAGE_SHIFT),
 152                       page_count(upg),
 153                       upg->flags);
 154        }
 155        printk("\n");
 156}
 157
 158static void dump_vdso_pages(struct vm_area_struct * vma)
 159{
 160        int i;
 161
 162        if (!vma || is_32bit_task()) {
 163                printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase);
 164                for (i=0; i<vdso32_pages; i++) {
 165                        struct page *pg = virt_to_page(vdso32_kbase +
 166                                                       i*PAGE_SIZE);
 167                        struct page *upg = (vma && vma->vm_mm) ?
 168                                follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
 169                                : NULL;
 170                        dump_one_vdso_page(pg, upg);
 171                }
 172        }
 173        if (!vma || !is_32bit_task()) {
 174                printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase);
 175                for (i=0; i<vdso64_pages; i++) {
 176                        struct page *pg = virt_to_page(vdso64_kbase +
 177                                                       i*PAGE_SIZE);
 178                        struct page *upg = (vma && vma->vm_mm) ?
 179                                follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
 180                                : NULL;
 181                        dump_one_vdso_page(pg, upg);
 182                }
 183        }
 184}
 185#endif /* DEBUG */
 186
 187/*
 188 * This is called from binfmt_elf, we create the special vma for the
 189 * vDSO and insert it into the mm struct tree
 190 */
 191int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 192{
 193        struct mm_struct *mm = current->mm;
 194        struct page **vdso_pagelist;
 195        unsigned long vdso_pages;
 196        unsigned long vdso_base;
 197        int rc;
 198
 199        if (!vdso_ready)
 200                return 0;
 201
 202#ifdef CONFIG_PPC64
 203        if (is_32bit_task()) {
 204                vdso_pagelist = vdso32_pagelist;
 205                vdso_pages = vdso32_pages;
 206                vdso_base = VDSO32_MBASE;
 207        } else {
 208                vdso_pagelist = vdso64_pagelist;
 209                vdso_pages = vdso64_pages;
 210                /*
 211                 * On 64bit we don't have a preferred map address. This
 212                 * allows get_unmapped_area to find an area near other mmaps
 213                 * and most likely share a SLB entry.
 214                 */
 215                vdso_base = 0;
 216        }
 217#else
 218        vdso_pagelist = vdso32_pagelist;
 219        vdso_pages = vdso32_pages;
 220        vdso_base = VDSO32_MBASE;
 221#endif
 222
 223        current->mm->context.vdso_base = 0;
 224
 225        /* vDSO has a problem and was disabled, just don't "enable" it for the
 226         * process
 227         */
 228        if (vdso_pages == 0)
 229                return 0;
 230        /* Add a page to the vdso size for the data page */
 231        vdso_pages ++;
 232
 233        /*
 234         * pick a base address for the vDSO in process space. We try to put it
 235         * at vdso_base which is the "natural" base for it, but we might fail
 236         * and end up putting it elsewhere.
 237         * Add enough to the size so that the result can be aligned.
 238         */
 239        down_write(&mm->mmap_sem);
 240        vdso_base = get_unmapped_area(NULL, vdso_base,
 241                                      (vdso_pages << PAGE_SHIFT) +
 242                                      ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
 243                                      0, 0);
 244        if (IS_ERR_VALUE(vdso_base)) {
 245                rc = vdso_base;
 246                goto fail_mmapsem;
 247        }
 248
 249        /* Add required alignment. */
 250        vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT);
 251
 252        /*
 253         * Put vDSO base into mm struct. We need to do this before calling
 254         * install_special_mapping or the perf counter mmap tracking code
 255         * will fail to recognise it as a vDSO (since arch_vma_name fails).
 256         */
 257        current->mm->context.vdso_base = vdso_base;
 258
 259        /*
 260         * our vma flags don't have VM_WRITE so by default, the process isn't
 261         * allowed to write those pages.
 262         * gdb can break that with ptrace interface, and thus trigger COW on
 263         * those pages but it's then your responsibility to never do that on
 264         * the "data" page of the vDSO or you'll stop getting kernel updates
 265         * and your nice userland gettimeofday will be totally dead.
 266         * It's fine to use that for setting breakpoints in the vDSO code
 267         * pages though
 268         *
 269         * Make sure the vDSO gets into every core dump.
 270         * Dumping its contents makes post-mortem fully interpretable later
 271         * without matching up the same kernel and hardware config to see
 272         * what PC values meant.
 273         */
 274        rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
 275                                     VM_READ|VM_EXEC|
 276                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
 277                                     VM_ALWAYSDUMP,
 278                                     vdso_pagelist);
 279        if (rc) {
 280                current->mm->context.vdso_base = 0;
 281                goto fail_mmapsem;
 282        }
 283
 284        up_write(&mm->mmap_sem);
 285        return 0;
 286
 287 fail_mmapsem:
 288        up_write(&mm->mmap_sem);
 289        return rc;
 290}
 291
 292const char *arch_vma_name(struct vm_area_struct *vma)
 293{
 294        if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base)
 295                return "[vdso]";
 296        return NULL;
 297}
 298
 299
 300
 301static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
 302                                  unsigned long *size)
 303{
 304        Elf32_Shdr *sechdrs;
 305        unsigned int i;
 306        char *secnames;
 307
 308        /* Grab section headers and strings so we can tell who is who */
 309        sechdrs = (void *)ehdr + ehdr->e_shoff;
 310        secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
 311
 312        /* Find the section they want */
 313        for (i = 1; i < ehdr->e_shnum; i++) {
 314                if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
 315                        if (size)
 316                                *size = sechdrs[i].sh_size;
 317                        return (void *)ehdr + sechdrs[i].sh_offset;
 318                }
 319        }
 320        *size = 0;
 321        return NULL;
 322}
 323
 324static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib,
 325                                        const char *symname)
 326{
 327        unsigned int i;
 328        char name[MAX_SYMNAME], *c;
 329
 330        for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
 331                if (lib->dynsym[i].st_name == 0)
 332                        continue;
 333                strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
 334                        MAX_SYMNAME);
 335                c = strchr(name, '@');
 336                if (c)
 337                        *c = 0;
 338                if (strcmp(symname, name) == 0)
 339                        return &lib->dynsym[i];
 340        }
 341        return NULL;
 342}
 343
 344/* Note that we assume the section is .text and the symbol is relative to
 345 * the library base
 346 */
 347static unsigned long __init find_function32(struct lib32_elfinfo *lib,
 348                                            const char *symname)
 349{
 350        Elf32_Sym *sym = find_symbol32(lib, symname);
 351
 352        if (sym == NULL) {
 353                printk(KERN_WARNING "vDSO32: function %s not found !\n",
 354                       symname);
 355                return 0;
 356        }
 357        return sym->st_value - VDSO32_LBASE;
 358}
 359
 360static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,
 361                                       struct lib64_elfinfo *v64,
 362                                       const char *orig, const char *fix)
 363{
 364        Elf32_Sym *sym32_gen, *sym32_fix;
 365
 366        sym32_gen = find_symbol32(v32, orig);
 367        if (sym32_gen == NULL) {
 368                printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig);
 369                return -1;
 370        }
 371        if (fix == NULL) {
 372                sym32_gen->st_name = 0;
 373                return 0;
 374        }
 375        sym32_fix = find_symbol32(v32, fix);
 376        if (sym32_fix == NULL) {
 377                printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix);
 378                return -1;
 379        }
 380        sym32_gen->st_value = sym32_fix->st_value;
 381        sym32_gen->st_size = sym32_fix->st_size;
 382        sym32_gen->st_info = sym32_fix->st_info;
 383        sym32_gen->st_other = sym32_fix->st_other;
 384        sym32_gen->st_shndx = sym32_fix->st_shndx;
 385
 386        return 0;
 387}
 388
 389
 390#ifdef CONFIG_PPC64
 391
 392static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname,
 393                                  unsigned long *size)
 394{
 395        Elf64_Shdr *sechdrs;
 396        unsigned int i;
 397        char *secnames;
 398
 399        /* Grab section headers and strings so we can tell who is who */
 400        sechdrs = (void *)ehdr + ehdr->e_shoff;
 401        secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
 402
 403        /* Find the section they want */
 404        for (i = 1; i < ehdr->e_shnum; i++) {
 405                if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
 406                        if (size)
 407                                *size = sechdrs[i].sh_size;
 408                        return (void *)ehdr + sechdrs[i].sh_offset;
 409                }
 410        }
 411        if (size)
 412                *size = 0;
 413        return NULL;
 414}
 415
 416static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib,
 417                                        const char *symname)
 418{
 419        unsigned int i;
 420        char name[MAX_SYMNAME], *c;
 421
 422        for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) {
 423                if (lib->dynsym[i].st_name == 0)
 424                        continue;
 425                strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
 426                        MAX_SYMNAME);
 427                c = strchr(name, '@');
 428                if (c)
 429                        *c = 0;
 430                if (strcmp(symname, name) == 0)
 431                        return &lib->dynsym[i];
 432        }
 433        return NULL;
 434}
 435
 436/* Note that we assume the section is .text and the symbol is relative to
 437 * the library base
 438 */
 439static unsigned long __init find_function64(struct lib64_elfinfo *lib,
 440                                            const char *symname)
 441{
 442        Elf64_Sym *sym = find_symbol64(lib, symname);
 443
 444        if (sym == NULL) {
 445                printk(KERN_WARNING "vDSO64: function %s not found !\n",
 446                       symname);
 447                return 0;
 448        }
 449#ifdef VDS64_HAS_DESCRIPTORS
 450        return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) -
 451                VDSO64_LBASE;
 452#else
 453        return sym->st_value - VDSO64_LBASE;
 454#endif
 455}
 456
 457static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32,
 458                                       struct lib64_elfinfo *v64,
 459                                       const char *orig, const char *fix)
 460{
 461        Elf64_Sym *sym64_gen, *sym64_fix;
 462
 463        sym64_gen = find_symbol64(v64, orig);
 464        if (sym64_gen == NULL) {
 465                printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig);
 466                return -1;
 467        }
 468        if (fix == NULL) {
 469                sym64_gen->st_name = 0;
 470                return 0;
 471        }
 472        sym64_fix = find_symbol64(v64, fix);
 473        if (sym64_fix == NULL) {
 474                printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix);
 475                return -1;
 476        }
 477        sym64_gen->st_value = sym64_fix->st_value;
 478        sym64_gen->st_size = sym64_fix->st_size;
 479        sym64_gen->st_info = sym64_fix->st_info;
 480        sym64_gen->st_other = sym64_fix->st_other;
 481        sym64_gen->st_shndx = sym64_fix->st_shndx;
 482
 483        return 0;
 484}
 485
 486#endif /* CONFIG_PPC64 */
 487
 488
 489static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
 490                                        struct lib64_elfinfo *v64)
 491{
 492        void *sect;
 493
 494        /*
 495         * Locate symbol tables & text section
 496         */
 497
 498        v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);
 499        v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);
 500        if (v32->dynsym == NULL || v32->dynstr == NULL) {
 501                printk(KERN_ERR "vDSO32: required symbol section not found\n");
 502                return -1;
 503        }
 504        sect = find_section32(v32->hdr, ".text", NULL);
 505        if (sect == NULL) {
 506                printk(KERN_ERR "vDSO32: the .text section was not found\n");
 507                return -1;
 508        }
 509        v32->text = sect - vdso32_kbase;
 510
 511#ifdef CONFIG_PPC64
 512        v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);
 513        v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL);
 514        if (v64->dynsym == NULL || v64->dynstr == NULL) {
 515                printk(KERN_ERR "vDSO64: required symbol section not found\n");
 516                return -1;
 517        }
 518        sect = find_section64(v64->hdr, ".text", NULL);
 519        if (sect == NULL) {
 520                printk(KERN_ERR "vDSO64: the .text section was not found\n");
 521                return -1;
 522        }
 523        v64->text = sect - vdso64_kbase;
 524#endif /* CONFIG_PPC64 */
 525
 526        return 0;
 527}
 528
 529static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
 530                                          struct lib64_elfinfo *v64)
 531{
 532        /*
 533         * Find signal trampolines
 534         */
 535
 536#ifdef CONFIG_PPC64
 537        vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64");
 538#endif
 539        vdso32_sigtramp    = find_function32(v32, "__kernel_sigtramp32");
 540        vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
 541}
 542
 543static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
 544                                       struct lib64_elfinfo *v64)
 545{
 546        Elf32_Sym *sym32;
 547#ifdef CONFIG_PPC64
 548        Elf64_Sym *sym64;
 549
 550        sym64 = find_symbol64(v64, "__kernel_datapage_offset");
 551        if (sym64 == NULL) {
 552                printk(KERN_ERR "vDSO64: Can't find symbol "
 553                       "__kernel_datapage_offset !\n");
 554                return -1;
 555        }
 556        *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
 557                (vdso64_pages << PAGE_SHIFT) -
 558                (sym64->st_value - VDSO64_LBASE);
 559#endif /* CONFIG_PPC64 */
 560
 561        sym32 = find_symbol32(v32, "__kernel_datapage_offset");
 562        if (sym32 == NULL) {
 563                printk(KERN_ERR "vDSO32: Can't find symbol "
 564                       "__kernel_datapage_offset !\n");
 565                return -1;
 566        }
 567        *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
 568                (vdso32_pages << PAGE_SHIFT) -
 569                (sym32->st_value - VDSO32_LBASE);
 570
 571        return 0;
 572}
 573
 574
 575static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
 576                                      struct lib64_elfinfo *v64)
 577{
 578        void *start32;
 579        unsigned long size32;
 580
 581#ifdef CONFIG_PPC64
 582        void *start64;
 583        unsigned long size64;
 584
 585        start64 = find_section64(v64->hdr, "__ftr_fixup", &size64);
 586        if (start64)
 587                do_feature_fixups(cur_cpu_spec->cpu_features,
 588                                  start64, start64 + size64);
 589
 590        start64 = find_section64(v64->hdr, "__mmu_ftr_fixup", &size64);
 591        if (start64)
 592                do_feature_fixups(cur_cpu_spec->mmu_features,
 593                                  start64, start64 + size64);
 594
 595        start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64);
 596        if (start64)
 597                do_feature_fixups(powerpc_firmware_features,
 598                                  start64, start64 + size64);
 599
 600        start64 = find_section64(v64->hdr, "__lwsync_fixup", &size64);
 601        if (start64)
 602                do_lwsync_fixups(cur_cpu_spec->cpu_features,
 603                                 start64, start64 + size64);
 604#endif /* CONFIG_PPC64 */
 605
 606        start32 = find_section32(v32->hdr, "__ftr_fixup", &size32);
 607        if (start32)
 608                do_feature_fixups(cur_cpu_spec->cpu_features,
 609                                  start32, start32 + size32);
 610
 611        start32 = find_section32(v32->hdr, "__mmu_ftr_fixup", &size32);
 612        if (start32)
 613                do_feature_fixups(cur_cpu_spec->mmu_features,
 614                                  start32, start32 + size32);
 615
 616#ifdef CONFIG_PPC64
 617        start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32);
 618        if (start32)
 619                do_feature_fixups(powerpc_firmware_features,
 620                                  start32, start32 + size32);
 621#endif /* CONFIG_PPC64 */
 622
 623        start32 = find_section32(v32->hdr, "__lwsync_fixup", &size32);
 624        if (start32)
 625                do_lwsync_fixups(cur_cpu_spec->cpu_features,
 626                                 start32, start32 + size32);
 627
 628        return 0;
 629}
 630
 631static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
 632                                       struct lib64_elfinfo *v64)
 633{
 634        int i;
 635
 636        for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) {
 637                struct vdso_patch_def *patch = &vdso_patches[i];
 638                int match = (cur_cpu_spec->cpu_features & patch->ftr_mask)
 639                        == patch->ftr_value;
 640                if (!match)
 641                        continue;
 642
 643                DBG("replacing %s with %s...\n", patch->gen_name,
 644                    patch->fix_name ? "NONE" : patch->fix_name);
 645
 646                /*
 647                 * Patch the 32 bits and 64 bits symbols. Note that we do not
 648                 * patch the "." symbol on 64 bits.
 649                 * It would be easy to do, but doesn't seem to be necessary,
 650                 * patching the OPD symbol is enough.
 651                 */
 652                vdso_do_func_patch32(v32, v64, patch->gen_name,
 653                                     patch->fix_name);
 654#ifdef CONFIG_PPC64
 655                vdso_do_func_patch64(v32, v64, patch->gen_name,
 656                                     patch->fix_name);
 657#endif /* CONFIG_PPC64 */
 658        }
 659
 660        return 0;
 661}
 662
 663
 664static __init int vdso_setup(void)
 665{
 666        struct lib32_elfinfo    v32;
 667        struct lib64_elfinfo    v64;
 668
 669        v32.hdr = vdso32_kbase;
 670#ifdef CONFIG_PPC64
 671        v64.hdr = vdso64_kbase;
 672#endif
 673        if (vdso_do_find_sections(&v32, &v64))
 674                return -1;
 675
 676        if (vdso_fixup_datapage(&v32, &v64))
 677                return -1;
 678
 679        if (vdso_fixup_features(&v32, &v64))
 680                return -1;
 681
 682        if (vdso_fixup_alt_funcs(&v32, &v64))
 683                return -1;
 684
 685        vdso_setup_trampolines(&v32, &v64);
 686
 687        return 0;
 688}
 689
 690/*
 691 * Called from setup_arch to initialize the bitmap of available
 692 * syscalls in the systemcfg page
 693 */
 694static void __init vdso_setup_syscall_map(void)
 695{
 696        unsigned int i;
 697        extern unsigned long *sys_call_table;
 698        extern unsigned long sys_ni_syscall;
 699
 700
 701        for (i = 0; i < __NR_syscalls; i++) {
 702#ifdef CONFIG_PPC64
 703                if (sys_call_table[i*2] != sys_ni_syscall)
 704                        vdso_data->syscall_map_64[i >> 5] |=
 705                                0x80000000UL >> (i & 0x1f);
 706                if (sys_call_table[i*2+1] != sys_ni_syscall)
 707                        vdso_data->syscall_map_32[i >> 5] |=
 708                                0x80000000UL >> (i & 0x1f);
 709#else /* CONFIG_PPC64 */
 710                if (sys_call_table[i] != sys_ni_syscall)
 711                        vdso_data->syscall_map_32[i >> 5] |=
 712                                0x80000000UL >> (i & 0x1f);
 713#endif /* CONFIG_PPC64 */
 714        }
 715}
 716
 717
 718static int __init vdso_init(void)
 719{
 720        int i;
 721
 722#ifdef CONFIG_PPC64
 723        /*
 724         * Fill up the "systemcfg" stuff for backward compatibility
 725         */
 726        strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
 727        vdso_data->version.major = SYSTEMCFG_MAJOR;
 728        vdso_data->version.minor = SYSTEMCFG_MINOR;
 729        vdso_data->processor = mfspr(SPRN_PVR);
 730        /*
 731         * Fake the old platform number for pSeries and iSeries and add
 732         * in LPAR bit if necessary
 733         */
 734        vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100;
 735        if (firmware_has_feature(FW_FEATURE_LPAR))
 736                vdso_data->platform |= 1;
 737        vdso_data->physicalMemorySize = memblock_phys_mem_size();
 738        vdso_data->dcache_size = ppc64_caches.dsize;
 739        vdso_data->dcache_line_size = ppc64_caches.dline_size;
 740        vdso_data->icache_size = ppc64_caches.isize;
 741        vdso_data->icache_line_size = ppc64_caches.iline_size;
 742
 743        /* XXXOJN: Blocks should be added to ppc64_caches and used instead */
 744        vdso_data->dcache_block_size = ppc64_caches.dline_size;
 745        vdso_data->icache_block_size = ppc64_caches.iline_size;
 746        vdso_data->dcache_log_block_size = ppc64_caches.log_dline_size;
 747        vdso_data->icache_log_block_size = ppc64_caches.log_iline_size;
 748
 749        /*
 750         * Calculate the size of the 64 bits vDSO
 751         */
 752        vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
 753        DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);
 754#else
 755        vdso_data->dcache_block_size = L1_CACHE_BYTES;
 756        vdso_data->dcache_log_block_size = L1_CACHE_SHIFT;
 757        vdso_data->icache_block_size = L1_CACHE_BYTES;
 758        vdso_data->icache_log_block_size = L1_CACHE_SHIFT;
 759#endif /* CONFIG_PPC64 */
 760
 761
 762        /*
 763         * Calculate the size of the 32 bits vDSO
 764         */
 765        vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
 766        DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
 767
 768
 769        /*
 770         * Setup the syscall map in the vDOS
 771         */
 772        vdso_setup_syscall_map();
 773
 774        /*
 775         * Initialize the vDSO images in memory, that is do necessary
 776         * fixups of vDSO symbols, locate trampolines, etc...
 777         */
 778        if (vdso_setup()) {
 779                printk(KERN_ERR "vDSO setup failure, not enabled !\n");
 780                vdso32_pages = 0;
 781#ifdef CONFIG_PPC64
 782                vdso64_pages = 0;
 783#endif
 784                return 0;
 785        }
 786
 787        /* Make sure pages are in the correct state */
 788        vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2),
 789                                  GFP_KERNEL);
 790        BUG_ON(vdso32_pagelist == NULL);
 791        for (i = 0; i < vdso32_pages; i++) {
 792                struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
 793                ClearPageReserved(pg);
 794                get_page(pg);
 795                vdso32_pagelist[i] = pg;
 796        }
 797        vdso32_pagelist[i++] = virt_to_page(vdso_data);
 798        vdso32_pagelist[i] = NULL;
 799
 800#ifdef CONFIG_PPC64
 801        vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2),
 802                                  GFP_KERNEL);
 803        BUG_ON(vdso64_pagelist == NULL);
 804        for (i = 0; i < vdso64_pages; i++) {
 805                struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
 806                ClearPageReserved(pg);
 807                get_page(pg);
 808                vdso64_pagelist[i] = pg;
 809        }
 810        vdso64_pagelist[i++] = virt_to_page(vdso_data);
 811        vdso64_pagelist[i] = NULL;
 812#endif /* CONFIG_PPC64 */
 813
 814        get_page(virt_to_page(vdso_data));
 815
 816        smp_wmb();
 817        vdso_ready = 1;
 818
 819        return 0;
 820}
 821arch_initcall(vdso_init);
 822
 823int in_gate_area_no_task(unsigned long addr)
 824{
 825        return 0;
 826}
 827
 828int in_gate_area(struct task_struct *task, unsigned long addr)
 829{
 830        return 0;
 831}
 832
 833struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
 834{
 835        return NULL;
 836}
 837
 838