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