diff options
author | Mark Salter <msalter@redhat.com> | 2014-04-07 18:39:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 19:36:15 -0400 |
commit | 5b7c73e00968c7fdf908c3ced31e1cc83c01ba14 (patch) | |
tree | 5d733047855bc22d40e022ea27a11ba7b52b03e4 /arch/x86/mm | |
parent | 9e5c33d7aeeef62e5fa7e74f94432685bd03026b (diff) |
x86: use generic early_ioremap
Move x86 over to the generic early ioremap implementation.
Signed-off-by: Mark Salter <msalter@redhat.com>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/ioremap.c | 228 | ||||
-rw-r--r-- | arch/x86/mm/pgtable_32.c | 2 |
2 files changed, 4 insertions, 226 deletions
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index bbb450412810..597ac155c91c 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -328,17 +328,6 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr) | |||
328 | return; | 328 | return; |
329 | } | 329 | } |
330 | 330 | ||
331 | static int __initdata early_ioremap_debug; | ||
332 | |||
333 | static int __init early_ioremap_debug_setup(char *str) | ||
334 | { | ||
335 | early_ioremap_debug = 1; | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | early_param("early_ioremap_debug", early_ioremap_debug_setup); | ||
340 | |||
341 | static __initdata int after_paging_init; | ||
342 | static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss; | 331 | static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss; |
343 | 332 | ||
344 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) | 333 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) |
@@ -362,18 +351,11 @@ bool __init is_early_ioremap_ptep(pte_t *ptep) | |||
362 | return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)]; | 351 | return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)]; |
363 | } | 352 | } |
364 | 353 | ||
365 | static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata; | ||
366 | |||
367 | void __init early_ioremap_init(void) | 354 | void __init early_ioremap_init(void) |
368 | { | 355 | { |
369 | pmd_t *pmd; | 356 | pmd_t *pmd; |
370 | int i; | ||
371 | 357 | ||
372 | if (early_ioremap_debug) | 358 | early_ioremap_setup(); |
373 | printk(KERN_INFO "early_ioremap_init()\n"); | ||
374 | |||
375 | for (i = 0; i < FIX_BTMAPS_SLOTS; i++) | ||
376 | slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i); | ||
377 | 359 | ||
378 | pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); | 360 | pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); |
379 | memset(bm_pte, 0, sizeof(bm_pte)); | 361 | memset(bm_pte, 0, sizeof(bm_pte)); |
@@ -402,13 +384,8 @@ void __init early_ioremap_init(void) | |||
402 | } | 384 | } |
403 | } | 385 | } |
404 | 386 | ||
405 | void __init early_ioremap_reset(void) | 387 | void __init __early_set_fixmap(enum fixed_addresses idx, |
406 | { | 388 | phys_addr_t phys, pgprot_t flags) |
407 | after_paging_init = 1; | ||
408 | } | ||
409 | |||
410 | static void __init __early_set_fixmap(enum fixed_addresses idx, | ||
411 | phys_addr_t phys, pgprot_t flags) | ||
412 | { | 389 | { |
413 | unsigned long addr = __fix_to_virt(idx); | 390 | unsigned long addr = __fix_to_virt(idx); |
414 | pte_t *pte; | 391 | pte_t *pte; |
@@ -425,202 +402,3 @@ static void __init __early_set_fixmap(enum fixed_addresses idx, | |||
425 | pte_clear(&init_mm, addr, pte); | 402 | pte_clear(&init_mm, addr, pte); |
426 | __flush_tlb_one(addr); | 403 | __flush_tlb_one(addr); |
427 | } | 404 | } |
428 | |||
429 | static inline void __init early_set_fixmap(enum fixed_addresses idx, | ||
430 | phys_addr_t phys, pgprot_t prot) | ||
431 | { | ||
432 | if (after_paging_init) | ||
433 | __set_fixmap(idx, phys, prot); | ||
434 | else | ||
435 | __early_set_fixmap(idx, phys, prot); | ||
436 | } | ||
437 | |||
438 | static inline void __init early_clear_fixmap(enum fixed_addresses idx) | ||
439 | { | ||
440 | if (after_paging_init) | ||
441 | clear_fixmap(idx); | ||
442 | else | ||
443 | __early_set_fixmap(idx, 0, __pgprot(0)); | ||
444 | } | ||
445 | |||
446 | static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata; | ||
447 | static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; | ||
448 | |||
449 | void __init fixup_early_ioremap(void) | ||
450 | { | ||
451 | int i; | ||
452 | |||
453 | for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { | ||
454 | if (prev_map[i]) { | ||
455 | WARN_ON(1); | ||
456 | break; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | early_ioremap_init(); | ||
461 | } | ||
462 | |||
463 | static int __init check_early_ioremap_leak(void) | ||
464 | { | ||
465 | int count = 0; | ||
466 | int i; | ||
467 | |||
468 | for (i = 0; i < FIX_BTMAPS_SLOTS; i++) | ||
469 | if (prev_map[i]) | ||
470 | count++; | ||
471 | |||
472 | if (!count) | ||
473 | return 0; | ||
474 | WARN(1, KERN_WARNING | ||
475 | "Debug warning: early ioremap leak of %d areas detected.\n", | ||
476 | count); | ||
477 | printk(KERN_WARNING | ||
478 | "please boot with early_ioremap_debug and report the dmesg.\n"); | ||
479 | |||
480 | return 1; | ||
481 | } | ||
482 | late_initcall(check_early_ioremap_leak); | ||
483 | |||
484 | static void __init __iomem * | ||
485 | __early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) | ||
486 | { | ||
487 | unsigned long offset; | ||
488 | resource_size_t last_addr; | ||
489 | unsigned int nrpages; | ||
490 | enum fixed_addresses idx; | ||
491 | int i, slot; | ||
492 | |||
493 | WARN_ON(system_state != SYSTEM_BOOTING); | ||
494 | |||
495 | slot = -1; | ||
496 | for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { | ||
497 | if (!prev_map[i]) { | ||
498 | slot = i; | ||
499 | break; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | if (slot < 0) { | ||
504 | printk(KERN_INFO "%s(%08llx, %08lx) not found slot\n", | ||
505 | __func__, (u64)phys_addr, size); | ||
506 | WARN_ON(1); | ||
507 | return NULL; | ||
508 | } | ||
509 | |||
510 | if (early_ioremap_debug) { | ||
511 | printk(KERN_INFO "%s(%08llx, %08lx) [%d] => ", | ||
512 | __func__, (u64)phys_addr, size, slot); | ||
513 | dump_stack(); | ||
514 | } | ||
515 | |||
516 | /* Don't allow wraparound or zero size */ | ||
517 | last_addr = phys_addr + size - 1; | ||
518 | if (!size || last_addr < phys_addr) { | ||
519 | WARN_ON(1); | ||
520 | return NULL; | ||
521 | } | ||
522 | |||
523 | prev_size[slot] = size; | ||
524 | /* | ||
525 | * Mappings have to be page-aligned | ||
526 | */ | ||
527 | offset = phys_addr & ~PAGE_MASK; | ||
528 | phys_addr &= PAGE_MASK; | ||
529 | size = PAGE_ALIGN(last_addr + 1) - phys_addr; | ||
530 | |||
531 | /* | ||
532 | * Mappings have to fit in the FIX_BTMAP area. | ||
533 | */ | ||
534 | nrpages = size >> PAGE_SHIFT; | ||
535 | if (nrpages > NR_FIX_BTMAPS) { | ||
536 | WARN_ON(1); | ||
537 | return NULL; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * Ok, go for it.. | ||
542 | */ | ||
543 | idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; | ||
544 | while (nrpages > 0) { | ||
545 | early_set_fixmap(idx, phys_addr, prot); | ||
546 | phys_addr += PAGE_SIZE; | ||
547 | --idx; | ||
548 | --nrpages; | ||
549 | } | ||
550 | if (early_ioremap_debug) | ||
551 | printk(KERN_CONT "%08lx + %08lx\n", offset, slot_virt[slot]); | ||
552 | |||
553 | prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]); | ||
554 | return prev_map[slot]; | ||
555 | } | ||
556 | |||
557 | /* Remap an IO device */ | ||
558 | void __init __iomem * | ||
559 | early_ioremap(resource_size_t phys_addr, unsigned long size) | ||
560 | { | ||
561 | return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); | ||
562 | } | ||
563 | |||
564 | /* Remap memory */ | ||
565 | void __init *early_memremap(resource_size_t phys_addr, unsigned long size) | ||
566 | { | ||
567 | return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL); | ||
568 | } | ||
569 | |||
570 | void __init early_iounmap(void __iomem *addr, unsigned long size) | ||
571 | { | ||
572 | unsigned long virt_addr; | ||
573 | unsigned long offset; | ||
574 | unsigned int nrpages; | ||
575 | enum fixed_addresses idx; | ||
576 | int i, slot; | ||
577 | |||
578 | slot = -1; | ||
579 | for (i = 0; i < FIX_BTMAPS_SLOTS; i++) { | ||
580 | if (prev_map[i] == addr) { | ||
581 | slot = i; | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | if (slot < 0) { | ||
587 | printk(KERN_INFO "early_iounmap(%p, %08lx) not found slot\n", | ||
588 | addr, size); | ||
589 | WARN_ON(1); | ||
590 | return; | ||
591 | } | ||
592 | |||
593 | if (prev_size[slot] != size) { | ||
594 | printk(KERN_INFO "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n", | ||
595 | addr, size, slot, prev_size[slot]); | ||
596 | WARN_ON(1); | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | if (early_ioremap_debug) { | ||
601 | printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, | ||
602 | size, slot); | ||
603 | dump_stack(); | ||
604 | } | ||
605 | |||
606 | virt_addr = (unsigned long)addr; | ||
607 | if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)) { | ||
608 | WARN_ON(1); | ||
609 | return; | ||
610 | } | ||
611 | offset = virt_addr & ~PAGE_MASK; | ||
612 | nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT; | ||
613 | |||
614 | idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot; | ||
615 | while (nrpages > 0) { | ||
616 | early_clear_fixmap(idx); | ||
617 | --idx; | ||
618 | --nrpages; | ||
619 | } | ||
620 | prev_map[slot] = NULL; | ||
621 | } | ||
622 | |||
623 | void __init early_memunmap(void *addr, unsigned long size) | ||
624 | { | ||
625 | early_iounmap((__force void __iomem *)addr, size); | ||
626 | } | ||
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index a69bcb8c7621..4dd8cf652579 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -127,7 +127,7 @@ static int __init parse_reservetop(char *arg) | |||
127 | 127 | ||
128 | address = memparse(arg, &arg); | 128 | address = memparse(arg, &arg); |
129 | reserve_top_address(address); | 129 | reserve_top_address(address); |
130 | fixup_early_ioremap(); | 130 | early_ioremap_init(); |
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
133 | early_param("reservetop", parse_reservetop); | 133 | early_param("reservetop", parse_reservetop); |