diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-06-06 18:17:50 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-06-06 18:17:50 -0400 |
commit | 3eba148d75670f61463dd3c9ef8672da8f290f36 (patch) | |
tree | 45cb8fbda6d6ce9d73aeeac673282e37b0be2531 /arch | |
parent | 057b0a7518e4b8fca26201715996d6d928a62300 (diff) | |
parent | 4cf563c5d97c83d4b2fb3a778dd7d5e362cc3e34 (diff) |
Merge branch 'acpi-pm' into pm-sleep
Diffstat (limited to 'arch')
103 files changed, 1378 insertions, 710 deletions
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 819dd5f7eb05..29b82adbf0b4 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S | |||
@@ -614,11 +614,13 @@ resume_user_mode_begin: | |||
614 | 614 | ||
615 | resume_kernel_mode: | 615 | resume_kernel_mode: |
616 | 616 | ||
617 | #ifdef CONFIG_PREEMPT | 617 | ; Disable Interrupts from this point on |
618 | 618 | ; CONFIG_PREEMPT: This is a must for preempt_schedule_irq() | |
619 | ; This is a must for preempt_schedule_irq() | 619 | ; !CONFIG_PREEMPT: To ensure restore_regs is intr safe |
620 | IRQ_DISABLE r9 | 620 | IRQ_DISABLE r9 |
621 | 621 | ||
622 | #ifdef CONFIG_PREEMPT | ||
623 | |||
622 | ; Can't preempt if preemption disabled | 624 | ; Can't preempt if preemption disabled |
623 | GET_CURR_THR_INFO_FROM_SP r10 | 625 | GET_CURR_THR_INFO_FROM_SP r10 |
624 | ld r8, [r10, THREAD_INFO_PREEMPT_COUNT] | 626 | ld r8, [r10, THREAD_INFO_PREEMPT_COUNT] |
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 07f283c20eb1..cb6811e5ae5a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi | |||
@@ -802,7 +802,7 @@ | |||
802 | <0x46000000 0x400000>; | 802 | <0x46000000 0x400000>; |
803 | reg-names = "mpu", "dat"; | 803 | reg-names = "mpu", "dat"; |
804 | interrupts = <80>, <81>; | 804 | interrupts = <80>, <81>; |
805 | interrupts-names = "tx", "rx"; | 805 | interrupt-names = "tx", "rx"; |
806 | status = "disabled"; | 806 | status = "disabled"; |
807 | dmas = <&edma 8>, | 807 | dmas = <&edma 8>, |
808 | <&edma 9>; | 808 | <&edma 9>; |
@@ -816,7 +816,7 @@ | |||
816 | <0x46400000 0x400000>; | 816 | <0x46400000 0x400000>; |
817 | reg-names = "mpu", "dat"; | 817 | reg-names = "mpu", "dat"; |
818 | interrupts = <82>, <83>; | 818 | interrupts = <82>, <83>; |
819 | interrupts-names = "tx", "rx"; | 819 | interrupt-names = "tx", "rx"; |
820 | status = "disabled"; | 820 | status = "disabled"; |
821 | dmas = <&edma 10>, | 821 | dmas = <&edma 10>, |
822 | <&edma 11>; | 822 | <&edma 11>; |
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 36d523a26831..d1f8707ff1df 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi | |||
@@ -691,7 +691,7 @@ | |||
691 | <0x46000000 0x400000>; | 691 | <0x46000000 0x400000>; |
692 | reg-names = "mpu", "dat"; | 692 | reg-names = "mpu", "dat"; |
693 | interrupts = <80>, <81>; | 693 | interrupts = <80>, <81>; |
694 | interrupts-names = "tx", "rx"; | 694 | interrupt-names = "tx", "rx"; |
695 | status = "disabled"; | 695 | status = "disabled"; |
696 | dmas = <&edma 8>, | 696 | dmas = <&edma 8>, |
697 | <&edma 9>; | 697 | <&edma 9>; |
@@ -705,7 +705,7 @@ | |||
705 | <0x46400000 0x400000>; | 705 | <0x46400000 0x400000>; |
706 | reg-names = "mpu", "dat"; | 706 | reg-names = "mpu", "dat"; |
707 | interrupts = <82>, <83>; | 707 | interrupts = <82>, <83>; |
708 | interrupts-names = "tx", "rx"; | 708 | interrupt-names = "tx", "rx"; |
709 | status = "disabled"; | 709 | status = "disabled"; |
710 | dmas = <&edma 10>, | 710 | dmas = <&edma 10>, |
711 | <&edma 11>; | 711 | <&edma 11>; |
diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi index f09fb10a3791..81df870e5ee6 100644 --- a/arch/arm/boot/dts/stih415-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi | |||
@@ -49,7 +49,7 @@ | |||
49 | reg = <0xfe61f080 0x4>; | 49 | reg = <0xfe61f080 0x4>; |
50 | reg-names = "irqmux"; | 50 | reg-names = "irqmux"; |
51 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; | 51 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; |
52 | interrupts-names = "irqmux"; | 52 | interrupt-names = "irqmux"; |
53 | ranges = <0 0xfe610000 0x5000>; | 53 | ranges = <0 0xfe610000 0x5000>; |
54 | 54 | ||
55 | PIO0: gpio@fe610000 { | 55 | PIO0: gpio@fe610000 { |
@@ -187,7 +187,7 @@ | |||
187 | reg = <0xfee0f080 0x4>; | 187 | reg = <0xfee0f080 0x4>; |
188 | reg-names = "irqmux"; | 188 | reg-names = "irqmux"; |
189 | interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; | 189 | interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; |
190 | interrupts-names = "irqmux"; | 190 | interrupt-names = "irqmux"; |
191 | ranges = <0 0xfee00000 0x8000>; | 191 | ranges = <0 0xfee00000 0x8000>; |
192 | 192 | ||
193 | PIO5: gpio@fee00000 { | 193 | PIO5: gpio@fee00000 { |
@@ -282,7 +282,7 @@ | |||
282 | reg = <0xfe82f080 0x4>; | 282 | reg = <0xfe82f080 0x4>; |
283 | reg-names = "irqmux"; | 283 | reg-names = "irqmux"; |
284 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; | 284 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
285 | interrupts-names = "irqmux"; | 285 | interrupt-names = "irqmux"; |
286 | ranges = <0 0xfe820000 0x8000>; | 286 | ranges = <0 0xfe820000 0x8000>; |
287 | 287 | ||
288 | PIO13: gpio@fe820000 { | 288 | PIO13: gpio@fe820000 { |
@@ -423,7 +423,7 @@ | |||
423 | reg = <0xfd6bf080 0x4>; | 423 | reg = <0xfd6bf080 0x4>; |
424 | reg-names = "irqmux"; | 424 | reg-names = "irqmux"; |
425 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; | 425 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
426 | interrupts-names = "irqmux"; | 426 | interrupt-names = "irqmux"; |
427 | ranges = <0 0xfd6b0000 0x3000>; | 427 | ranges = <0 0xfd6b0000 0x3000>; |
428 | 428 | ||
429 | PIO100: gpio@fd6b0000 { | 429 | PIO100: gpio@fd6b0000 { |
@@ -460,7 +460,7 @@ | |||
460 | reg = <0xfd33f080 0x4>; | 460 | reg = <0xfd33f080 0x4>; |
461 | reg-names = "irqmux"; | 461 | reg-names = "irqmux"; |
462 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; | 462 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
463 | interrupts-names = "irqmux"; | 463 | interrupt-names = "irqmux"; |
464 | ranges = <0 0xfd330000 0x5000>; | 464 | ranges = <0 0xfd330000 0x5000>; |
465 | 465 | ||
466 | PIO103: gpio@fd330000 { | 466 | PIO103: gpio@fd330000 { |
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi index aeea304086eb..250d5ecc951e 100644 --- a/arch/arm/boot/dts/stih416-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi | |||
@@ -53,7 +53,7 @@ | |||
53 | reg = <0xfe61f080 0x4>; | 53 | reg = <0xfe61f080 0x4>; |
54 | reg-names = "irqmux"; | 54 | reg-names = "irqmux"; |
55 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; | 55 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
56 | interrupts-names = "irqmux"; | 56 | interrupt-names = "irqmux"; |
57 | ranges = <0 0xfe610000 0x6000>; | 57 | ranges = <0 0xfe610000 0x6000>; |
58 | 58 | ||
59 | PIO0: gpio@fe610000 { | 59 | PIO0: gpio@fe610000 { |
@@ -201,7 +201,7 @@ | |||
201 | reg = <0xfee0f080 0x4>; | 201 | reg = <0xfee0f080 0x4>; |
202 | reg-names = "irqmux"; | 202 | reg-names = "irqmux"; |
203 | interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; | 203 | interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; |
204 | interrupts-names = "irqmux"; | 204 | interrupt-names = "irqmux"; |
205 | ranges = <0 0xfee00000 0x10000>; | 205 | ranges = <0 0xfee00000 0x10000>; |
206 | 206 | ||
207 | PIO5: gpio@fee00000 { | 207 | PIO5: gpio@fee00000 { |
@@ -333,7 +333,7 @@ | |||
333 | reg = <0xfe82f080 0x4>; | 333 | reg = <0xfe82f080 0x4>; |
334 | reg-names = "irqmux"; | 334 | reg-names = "irqmux"; |
335 | interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; | 335 | interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; |
336 | interrupts-names = "irqmux"; | 336 | interrupt-names = "irqmux"; |
337 | ranges = <0 0xfe820000 0x6000>; | 337 | ranges = <0 0xfe820000 0x6000>; |
338 | 338 | ||
339 | PIO13: gpio@fe820000 { | 339 | PIO13: gpio@fe820000 { |
@@ -461,7 +461,7 @@ | |||
461 | reg = <0xfd6bf080 0x4>; | 461 | reg = <0xfd6bf080 0x4>; |
462 | reg-names = "irqmux"; | 462 | reg-names = "irqmux"; |
463 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; | 463 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
464 | interrupts-names = "irqmux"; | 464 | interrupt-names = "irqmux"; |
465 | ranges = <0 0xfd6b0000 0x3000>; | 465 | ranges = <0 0xfd6b0000 0x3000>; |
466 | 466 | ||
467 | PIO100: gpio@fd6b0000 { | 467 | PIO100: gpio@fd6b0000 { |
@@ -498,7 +498,7 @@ | |||
498 | reg = <0xfd33f080 0x4>; | 498 | reg = <0xfd33f080 0x4>; |
499 | reg-names = "irqmux"; | 499 | reg-names = "irqmux"; |
500 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; | 500 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
501 | interrupts-names = "irqmux"; | 501 | interrupt-names = "irqmux"; |
502 | ranges = <0 0xfd330000 0x5000>; | 502 | ranges = <0 0xfd330000 0x5000>; |
503 | 503 | ||
504 | PIO103: gpio@fd330000 { | 504 | PIO103: gpio@fd330000 { |
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 466bd299b1a8..4be5bb150bdd 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
@@ -23,7 +23,7 @@ config KVM | |||
23 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
24 | select KVM_MMIO | 24 | select KVM_MMIO |
25 | select KVM_ARM_HOST | 25 | select KVM_ARM_HOST |
26 | depends on ARM_VIRT_EXT && ARM_LPAE | 26 | depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN |
27 | ---help--- | 27 | ---help--- |
28 | Support hosting virtualized guest machines. You will also | 28 | Support hosting virtualized guest machines. You will also |
29 | need to select one or more of the processor modules below. | 29 | need to select one or more of the processor modules below. |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 80bb1e6c2c29..16f804938b8f 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -42,6 +42,8 @@ static unsigned long hyp_idmap_start; | |||
42 | static unsigned long hyp_idmap_end; | 42 | static unsigned long hyp_idmap_end; |
43 | static phys_addr_t hyp_idmap_vector; | 43 | static phys_addr_t hyp_idmap_vector; |
44 | 44 | ||
45 | #define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) | ||
46 | |||
45 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) | 47 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) |
46 | 48 | ||
47 | static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) | 49 | static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) |
@@ -293,14 +295,14 @@ void free_boot_hyp_pgd(void) | |||
293 | if (boot_hyp_pgd) { | 295 | if (boot_hyp_pgd) { |
294 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); | 296 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); |
295 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); | 297 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); |
296 | kfree(boot_hyp_pgd); | 298 | free_pages((unsigned long)boot_hyp_pgd, pgd_order); |
297 | boot_hyp_pgd = NULL; | 299 | boot_hyp_pgd = NULL; |
298 | } | 300 | } |
299 | 301 | ||
300 | if (hyp_pgd) | 302 | if (hyp_pgd) |
301 | unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); | 303 | unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); |
302 | 304 | ||
303 | kfree(init_bounce_page); | 305 | free_page((unsigned long)init_bounce_page); |
304 | init_bounce_page = NULL; | 306 | init_bounce_page = NULL; |
305 | 307 | ||
306 | mutex_unlock(&kvm_hyp_pgd_mutex); | 308 | mutex_unlock(&kvm_hyp_pgd_mutex); |
@@ -330,7 +332,7 @@ void free_hyp_pgds(void) | |||
330 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) | 332 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) |
331 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); | 333 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); |
332 | 334 | ||
333 | kfree(hyp_pgd); | 335 | free_pages((unsigned long)hyp_pgd, pgd_order); |
334 | hyp_pgd = NULL; | 336 | hyp_pgd = NULL; |
335 | } | 337 | } |
336 | 338 | ||
@@ -1024,7 +1026,7 @@ int kvm_mmu_init(void) | |||
1024 | size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; | 1026 | size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; |
1025 | phys_addr_t phys_base; | 1027 | phys_addr_t phys_base; |
1026 | 1028 | ||
1027 | init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1029 | init_bounce_page = (void *)__get_free_page(GFP_KERNEL); |
1028 | if (!init_bounce_page) { | 1030 | if (!init_bounce_page) { |
1029 | kvm_err("Couldn't allocate HYP init bounce page\n"); | 1031 | kvm_err("Couldn't allocate HYP init bounce page\n"); |
1030 | err = -ENOMEM; | 1032 | err = -ENOMEM; |
@@ -1050,8 +1052,9 @@ int kvm_mmu_init(void) | |||
1050 | (unsigned long)phys_base); | 1052 | (unsigned long)phys_base); |
1051 | } | 1053 | } |
1052 | 1054 | ||
1053 | hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); | 1055 | hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); |
1054 | boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); | 1056 | boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); |
1057 | |||
1055 | if (!hyp_pgd || !boot_hyp_pgd) { | 1058 | if (!hyp_pgd || !boot_hyp_pgd) { |
1056 | kvm_err("Hyp mode PGD not allocated\n"); | 1059 | kvm_err("Hyp mode PGD not allocated\n"); |
1057 | err = -ENOMEM; | 1060 | err = -ENOMEM; |
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index 93f4b2dd9248..f8c40a66e65d 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi | |||
@@ -307,6 +307,7 @@ | |||
307 | <0x0 0x1f21e000 0x0 0x1000>, | 307 | <0x0 0x1f21e000 0x0 0x1000>, |
308 | <0x0 0x1f217000 0x0 0x1000>; | 308 | <0x0 0x1f217000 0x0 0x1000>; |
309 | interrupts = <0x0 0x86 0x4>; | 309 | interrupts = <0x0 0x86 0x4>; |
310 | dma-coherent; | ||
310 | status = "disabled"; | 311 | status = "disabled"; |
311 | clocks = <&sata01clk 0>; | 312 | clocks = <&sata01clk 0>; |
312 | phys = <&phy1 0>; | 313 | phys = <&phy1 0>; |
@@ -321,6 +322,7 @@ | |||
321 | <0x0 0x1f22e000 0x0 0x1000>, | 322 | <0x0 0x1f22e000 0x0 0x1000>, |
322 | <0x0 0x1f227000 0x0 0x1000>; | 323 | <0x0 0x1f227000 0x0 0x1000>; |
323 | interrupts = <0x0 0x87 0x4>; | 324 | interrupts = <0x0 0x87 0x4>; |
325 | dma-coherent; | ||
324 | status = "ok"; | 326 | status = "ok"; |
325 | clocks = <&sata23clk 0>; | 327 | clocks = <&sata23clk 0>; |
326 | phys = <&phy2 0>; | 328 | phys = <&phy2 0>; |
@@ -334,6 +336,7 @@ | |||
334 | <0x0 0x1f23d000 0x0 0x1000>, | 336 | <0x0 0x1f23d000 0x0 0x1000>, |
335 | <0x0 0x1f23e000 0x0 0x1000>; | 337 | <0x0 0x1f23e000 0x0 0x1000>; |
336 | interrupts = <0x0 0x88 0x4>; | 338 | interrupts = <0x0 0x88 0x4>; |
339 | dma-coherent; | ||
337 | status = "ok"; | 340 | status = "ok"; |
338 | clocks = <&sata45clk 0>; | 341 | clocks = <&sata45clk 0>; |
339 | phys = <&phy3 0>; | 342 | phys = <&phy3 0>; |
diff --git a/arch/arm64/kernel/early_printk.c b/arch/arm64/kernel/early_printk.c index ffbbdde7aba1..2dc36d00addf 100644 --- a/arch/arm64/kernel/early_printk.c +++ b/arch/arm64/kernel/early_printk.c | |||
@@ -143,10 +143,8 @@ static int __init setup_early_printk(char *buf) | |||
143 | } | 143 | } |
144 | /* no options parsing yet */ | 144 | /* no options parsing yet */ |
145 | 145 | ||
146 | if (paddr) { | 146 | if (paddr) |
147 | set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr); | 147 | early_base = (void __iomem *)set_fixmap_offset_io(FIX_EARLYCON_MEM_BASE, paddr); |
148 | early_base = (void __iomem *)fix_to_virt(FIX_EARLYCON_MEM_BASE); | ||
149 | } | ||
150 | 148 | ||
151 | printch = match->printch; | 149 | printch = match->printch; |
152 | early_console = &early_console_dev; | 150 | early_console = &early_console_dev; |
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 93e7df8968fe..7ec784653b29 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
@@ -396,7 +396,7 @@ static int __init arm64_device_init(void) | |||
396 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 396 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | arch_initcall(arm64_device_init); | 399 | arch_initcall_sync(arm64_device_init); |
400 | 400 | ||
401 | static DEFINE_PER_CPU(struct cpu, cpu_data); | 401 | static DEFINE_PER_CPU(struct cpu, cpu_data); |
402 | 402 | ||
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 0ba347e59f06..c851eb44dc50 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c | |||
@@ -22,8 +22,11 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
24 | #include <linux/dma-contiguous.h> | 24 | #include <linux/dma-contiguous.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/platform_device.h> | ||
25 | #include <linux/vmalloc.h> | 27 | #include <linux/vmalloc.h> |
26 | #include <linux/swiotlb.h> | 28 | #include <linux/swiotlb.h> |
29 | #include <linux/amba/bus.h> | ||
27 | 30 | ||
28 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
29 | 32 | ||
@@ -305,17 +308,45 @@ struct dma_map_ops coherent_swiotlb_dma_ops = { | |||
305 | }; | 308 | }; |
306 | EXPORT_SYMBOL(coherent_swiotlb_dma_ops); | 309 | EXPORT_SYMBOL(coherent_swiotlb_dma_ops); |
307 | 310 | ||
311 | static int dma_bus_notifier(struct notifier_block *nb, | ||
312 | unsigned long event, void *_dev) | ||
313 | { | ||
314 | struct device *dev = _dev; | ||
315 | |||
316 | if (event != BUS_NOTIFY_ADD_DEVICE) | ||
317 | return NOTIFY_DONE; | ||
318 | |||
319 | if (of_property_read_bool(dev->of_node, "dma-coherent")) | ||
320 | set_dma_ops(dev, &coherent_swiotlb_dma_ops); | ||
321 | |||
322 | return NOTIFY_OK; | ||
323 | } | ||
324 | |||
325 | static struct notifier_block platform_bus_nb = { | ||
326 | .notifier_call = dma_bus_notifier, | ||
327 | }; | ||
328 | |||
329 | static struct notifier_block amba_bus_nb = { | ||
330 | .notifier_call = dma_bus_notifier, | ||
331 | }; | ||
332 | |||
308 | extern int swiotlb_late_init_with_default_size(size_t default_size); | 333 | extern int swiotlb_late_init_with_default_size(size_t default_size); |
309 | 334 | ||
310 | static int __init swiotlb_late_init(void) | 335 | static int __init swiotlb_late_init(void) |
311 | { | 336 | { |
312 | size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); | 337 | size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); |
313 | 338 | ||
314 | dma_ops = &coherent_swiotlb_dma_ops; | 339 | /* |
340 | * These must be registered before of_platform_populate(). | ||
341 | */ | ||
342 | bus_register_notifier(&platform_bus_type, &platform_bus_nb); | ||
343 | bus_register_notifier(&amba_bustype, &amba_bus_nb); | ||
344 | |||
345 | dma_ops = &noncoherent_swiotlb_dma_ops; | ||
315 | 346 | ||
316 | return swiotlb_late_init_with_default_size(swiotlb_size); | 347 | return swiotlb_late_init_with_default_size(swiotlb_size); |
317 | } | 348 | } |
318 | subsys_initcall(swiotlb_late_init); | 349 | arch_initcall(swiotlb_late_init); |
319 | 350 | ||
320 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 | 351 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 |
321 | 352 | ||
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6b7e89569a3a..0a472c41a67f 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -374,6 +374,9 @@ int kern_addr_valid(unsigned long addr) | |||
374 | if (pmd_none(*pmd)) | 374 | if (pmd_none(*pmd)) |
375 | return 0; | 375 | return 0; |
376 | 376 | ||
377 | if (pmd_sect(*pmd)) | ||
378 | return pfn_valid(pmd_pfn(*pmd)); | ||
379 | |||
377 | pte = pte_offset_kernel(pmd, addr); | 380 | pte = pte_offset_kernel(pmd, addr); |
378 | if (pte_none(*pte)) | 381 | if (pte_none(*pte)) |
379 | return 0; | 382 | return 0; |
diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h deleted file mode 100644 index 4e863daea25b..000000000000 --- a/arch/hexagon/include/asm/barrier.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * Memory barrier definitions for the Hexagon architecture | ||
3 | * | ||
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 and | ||
8 | * only version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | * 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _ASM_BARRIER_H | ||
22 | #define _ASM_BARRIER_H | ||
23 | |||
24 | #define rmb() barrier() | ||
25 | #define read_barrier_depends() barrier() | ||
26 | #define wmb() barrier() | ||
27 | #define mb() barrier() | ||
28 | #define smp_rmb() barrier() | ||
29 | #define smp_read_barrier_depends() barrier() | ||
30 | #define smp_wmb() barrier() | ||
31 | #define smp_mb() barrier() | ||
32 | |||
33 | /* Set a value and use a memory barrier. Used by the scheduler somewhere. */ | ||
34 | #define set_mb(var, value) \ | ||
35 | do { var = value; mb(); } while (0) | ||
36 | |||
37 | #endif /* _ASM_BARRIER_H */ | ||
diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild index a580642555b6..348356c99514 100644 --- a/arch/parisc/include/uapi/asm/Kbuild +++ b/arch/parisc/include/uapi/asm/Kbuild | |||
@@ -1,6 +1,8 @@ | |||
1 | # UAPI Header export list | 1 | # UAPI Header export list |
2 | include include/uapi/asm-generic/Kbuild.asm | 2 | include include/uapi/asm-generic/Kbuild.asm |
3 | 3 | ||
4 | generic-y += resource.h | ||
5 | |||
4 | header-y += bitsperlong.h | 6 | header-y += bitsperlong.h |
5 | header-y += byteorder.h | 7 | header-y += byteorder.h |
6 | header-y += errno.h | 8 | header-y += errno.h |
@@ -13,7 +15,6 @@ header-y += msgbuf.h | |||
13 | header-y += pdc.h | 15 | header-y += pdc.h |
14 | header-y += posix_types.h | 16 | header-y += posix_types.h |
15 | header-y += ptrace.h | 17 | header-y += ptrace.h |
16 | header-y += resource.h | ||
17 | header-y += sembuf.h | 18 | header-y += sembuf.h |
18 | header-y += setup.h | 19 | header-y += setup.h |
19 | header-y += shmbuf.h | 20 | header-y += shmbuf.h |
diff --git a/arch/parisc/include/uapi/asm/resource.h b/arch/parisc/include/uapi/asm/resource.h deleted file mode 100644 index 8b06343b62ed..000000000000 --- a/arch/parisc/include/uapi/asm/resource.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef _ASM_PARISC_RESOURCE_H | ||
2 | #define _ASM_PARISC_RESOURCE_H | ||
3 | |||
4 | #define _STK_LIM_MAX 10 * _STK_LIM | ||
5 | #include <asm-generic/resource.h> | ||
6 | |||
7 | #endif | ||
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index a28f02165e97..d367a0aece2a 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -139,18 +139,18 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, | |||
139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). | 139 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). |
140 | * The buffer is put in it's own section so that tools may locate it easier. | 140 | * The buffer is put in it's own section so that tools may locate it easier. |
141 | */ | 141 | */ |
142 | static char cmdline[COMMAND_LINE_SIZE] | 142 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
143 | __attribute__((__section__("__builtin_cmdline"))); | 143 | __attribute__((__section__("__builtin_cmdline"))); |
144 | 144 | ||
145 | static void prep_cmdline(void *chosen) | 145 | static void prep_cmdline(void *chosen) |
146 | { | 146 | { |
147 | if (cmdline[0] == '\0') | 147 | if (cmdline[0] == '\0') |
148 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 148 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
149 | 149 | ||
150 | printf("\n\rLinux/PowerPC load: %s", cmdline); | 150 | printf("\n\rLinux/PowerPC load: %s", cmdline); |
151 | /* If possible, edit the command line */ | 151 | /* If possible, edit the command line */ |
152 | if (console_ops.edit_cmdline) | 152 | if (console_ops.edit_cmdline) |
153 | console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); | 153 | console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); |
154 | printf("\n\r"); | 154 | printf("\n\r"); |
155 | 155 | ||
156 | /* Put the command line back into the devtree for the kernel */ | 156 | /* Put the command line back into the devtree for the kernel */ |
@@ -174,7 +174,7 @@ void start(void) | |||
174 | * built-in command line wasn't set by an external tool */ | 174 | * built-in command line wasn't set by an external tool */ |
175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) | 175 | if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) |
176 | memmove(cmdline, loader_info.cmdline, | 176 | memmove(cmdline, loader_info.cmdline, |
177 | min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); | 177 | min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1)); |
178 | 178 | ||
179 | if (console_ops.open && (console_ops.open() < 0)) | 179 | if (console_ops.open && (console_ops.open() < 0)) |
180 | exit(); | 180 | exit(); |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index b3218ce451bb..8aad3c55aeda 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "types.h" | 15 | #include "types.h" |
16 | #include "string.h" | 16 | #include "string.h" |
17 | 17 | ||
18 | #define COMMAND_LINE_SIZE 512 | 18 | #define BOOT_COMMAND_LINE_SIZE 2048 |
19 | #define MAX_PATH_LEN 256 | 19 | #define MAX_PATH_LEN 256 |
20 | #define MAX_PROP_LEN 256 /* What should this be? */ | 20 | #define MAX_PROP_LEN 256 /* What should this be? */ |
21 | 21 | ||
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 9954d98871d0..4ec2d86d3c50 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c | |||
@@ -47,13 +47,13 @@ BSS_STACK(4096); | |||
47 | * The buffer is put in it's own section so that tools may locate it easier. | 47 | * The buffer is put in it's own section so that tools may locate it easier. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | static char cmdline[COMMAND_LINE_SIZE] | 50 | static char cmdline[BOOT_COMMAND_LINE_SIZE] |
51 | __attribute__((__section__("__builtin_cmdline"))); | 51 | __attribute__((__section__("__builtin_cmdline"))); |
52 | 52 | ||
53 | static void prep_cmdline(void *chosen) | 53 | static void prep_cmdline(void *chosen) |
54 | { | 54 | { |
55 | if (cmdline[0] == '\0') | 55 | if (cmdline[0] == '\0') |
56 | getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); | 56 | getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); |
57 | else | 57 | else |
58 | setprop_str(chosen, "bootargs", cmdline); | 58 | setprop_str(chosen, "bootargs", cmdline); |
59 | 59 | ||
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a2efdaa020b0..66ad7a74116f 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -41,14 +41,14 @@ struct opal_takeover_args { | |||
41 | * size except the last one in the list to be as well. | 41 | * size except the last one in the list to be as well. |
42 | */ | 42 | */ |
43 | struct opal_sg_entry { | 43 | struct opal_sg_entry { |
44 | void *data; | 44 | __be64 data; |
45 | long length; | 45 | __be64 length; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* sg list */ | 48 | /* SG list */ |
49 | struct opal_sg_list { | 49 | struct opal_sg_list { |
50 | unsigned long num_entries; | 50 | __be64 length; |
51 | struct opal_sg_list *next; | 51 | __be64 next; |
52 | struct opal_sg_entry entry[]; | 52 | struct opal_sg_entry entry[]; |
53 | }; | 53 | }; |
54 | 54 | ||
@@ -858,8 +858,8 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, | |||
858 | int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, | 858 | int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, |
859 | uint32_t addr, __be32 *data, uint32_t sz); | 859 | uint32_t addr, __be32 *data, uint32_t sz); |
860 | 860 | ||
861 | int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id); | 861 | int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id); |
862 | int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type); | 862 | int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type); |
863 | int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); | 863 | int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); |
864 | int64_t opal_send_ack_elog(uint64_t log_id); | 864 | int64_t opal_send_ack_elog(uint64_t log_id); |
865 | void opal_resend_pending_logs(void); | 865 | void opal_resend_pending_logs(void); |
@@ -868,23 +868,24 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result); | |||
868 | int64_t opal_manage_flash(uint8_t op); | 868 | int64_t opal_manage_flash(uint8_t op); |
869 | int64_t opal_update_flash(uint64_t blk_list); | 869 | int64_t opal_update_flash(uint64_t blk_list); |
870 | int64_t opal_dump_init(uint8_t dump_type); | 870 | int64_t opal_dump_init(uint8_t dump_type); |
871 | int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size); | 871 | int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size); |
872 | int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type); | 872 | int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type); |
873 | int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); | 873 | int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); |
874 | int64_t opal_dump_ack(uint32_t dump_id); | 874 | int64_t opal_dump_ack(uint32_t dump_id); |
875 | int64_t opal_dump_resend_notification(void); | 875 | int64_t opal_dump_resend_notification(void); |
876 | 876 | ||
877 | int64_t opal_get_msg(uint64_t buffer, size_t size); | 877 | int64_t opal_get_msg(uint64_t buffer, uint64_t size); |
878 | int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); | 878 | int64_t opal_check_completion(uint64_t buffer, uint64_t size, uint64_t token); |
879 | int64_t opal_sync_host_reboot(void); | 879 | int64_t opal_sync_host_reboot(void); |
880 | int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, | 880 | int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, |
881 | size_t length); | 881 | uint64_t length); |
882 | int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, | 882 | int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, |
883 | size_t length); | 883 | uint64_t length); |
884 | int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); | 884 | int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); |
885 | 885 | ||
886 | /* Internal functions */ | 886 | /* Internal functions */ |
887 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); | 887 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, |
888 | int depth, void *data); | ||
888 | extern int early_init_dt_scan_recoverable_ranges(unsigned long node, | 889 | extern int early_init_dt_scan_recoverable_ranges(unsigned long node, |
889 | const char *uname, int depth, void *data); | 890 | const char *uname, int depth, void *data); |
890 | 891 | ||
@@ -893,10 +894,6 @@ extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | |||
893 | 894 | ||
894 | extern void hvc_opal_init_early(void); | 895 | extern void hvc_opal_init_early(void); |
895 | 896 | ||
896 | /* Internal functions */ | ||
897 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, | ||
898 | int depth, void *data); | ||
899 | |||
900 | extern int opal_notifier_register(struct notifier_block *nb); | 897 | extern int opal_notifier_register(struct notifier_block *nb); |
901 | extern int opal_notifier_unregister(struct notifier_block *nb); | 898 | extern int opal_notifier_unregister(struct notifier_block *nb); |
902 | 899 | ||
@@ -906,9 +903,6 @@ extern void opal_notifier_enable(void); | |||
906 | extern void opal_notifier_disable(void); | 903 | extern void opal_notifier_disable(void); |
907 | extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val); | 904 | extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val); |
908 | 905 | ||
909 | extern int opal_get_chars(uint32_t vtermno, char *buf, int count); | ||
910 | extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); | ||
911 | |||
912 | extern int __opal_async_get_token(void); | 906 | extern int __opal_async_get_token(void); |
913 | extern int opal_async_get_token_interruptible(void); | 907 | extern int opal_async_get_token_interruptible(void); |
914 | extern int __opal_async_release_token(int token); | 908 | extern int __opal_async_release_token(int token); |
@@ -916,8 +910,6 @@ extern int opal_async_release_token(int token); | |||
916 | extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); | 910 | extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); |
917 | extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); | 911 | extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); |
918 | 912 | ||
919 | extern void hvc_opal_init_early(void); | ||
920 | |||
921 | struct rtc_time; | 913 | struct rtc_time; |
922 | extern int opal_set_rtc_time(struct rtc_time *tm); | 914 | extern int opal_set_rtc_time(struct rtc_time *tm); |
923 | extern void opal_get_rtc_time(struct rtc_time *tm); | 915 | extern void opal_get_rtc_time(struct rtc_time *tm); |
@@ -937,6 +929,10 @@ extern int opal_resync_timebase(void); | |||
937 | 929 | ||
938 | extern void opal_lpc_init(void); | 930 | extern void opal_lpc_init(void); |
939 | 931 | ||
932 | struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, | ||
933 | unsigned long vmalloc_size); | ||
934 | void opal_free_sg_list(struct opal_sg_list *sg); | ||
935 | |||
940 | #endif /* __ASSEMBLY__ */ | 936 | #endif /* __ASSEMBLY__ */ |
941 | 937 | ||
942 | #endif /* __OPAL_H */ | 938 | #endif /* __OPAL_H */ |
diff --git a/arch/powerpc/include/uapi/asm/setup.h b/arch/powerpc/include/uapi/asm/setup.h index 552df83f1a49..ae3fb68cb28e 100644 --- a/arch/powerpc/include/uapi/asm/setup.h +++ b/arch/powerpc/include/uapi/asm/setup.h | |||
@@ -1 +1,6 @@ | |||
1 | #include <asm-generic/setup.h> | 1 | #ifndef _UAPI_ASM_POWERPC_SETUP_H |
2 | #define _UAPI_ASM_POWERPC_SETUP_H | ||
3 | |||
4 | #define COMMAND_LINE_SIZE 2048 | ||
5 | |||
6 | #endif /* _UAPI_ASM_POWERPC_SETUP_H */ | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 3bd77edd7610..450850a49dce 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -120,6 +120,7 @@ EXPORT_SYMBOL(giveup_spe); | |||
120 | EXPORT_SYMBOL(flush_instruction_cache); | 120 | EXPORT_SYMBOL(flush_instruction_cache); |
121 | #endif | 121 | #endif |
122 | EXPORT_SYMBOL(flush_dcache_range); | 122 | EXPORT_SYMBOL(flush_dcache_range); |
123 | EXPORT_SYMBOL(flush_icache_range); | ||
123 | 124 | ||
124 | #ifdef CONFIG_SMP | 125 | #ifdef CONFIG_SMP |
125 | #ifdef CONFIG_PPC32 | 126 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 2f3cdb01506d..658e89d2025b 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
@@ -705,7 +705,7 @@ static int __init rtas_flash_init(void) | |||
705 | if (rtas_token("ibm,update-flash-64-and-reboot") == | 705 | if (rtas_token("ibm,update-flash-64-and-reboot") == |
706 | RTAS_UNKNOWN_SERVICE) { | 706 | RTAS_UNKNOWN_SERVICE) { |
707 | pr_info("rtas_flash: no firmware flash support\n"); | 707 | pr_info("rtas_flash: no firmware flash support\n"); |
708 | return 1; | 708 | return -EINVAL; |
709 | } | 709 | } |
710 | 710 | ||
711 | rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); | 711 | rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index ffbb871c2bd8..b031f932c0cc 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -242,6 +242,12 @@ kvm_novcpu_exit: | |||
242 | */ | 242 | */ |
243 | .globl kvm_start_guest | 243 | .globl kvm_start_guest |
244 | kvm_start_guest: | 244 | kvm_start_guest: |
245 | |||
246 | /* Set runlatch bit the minute you wake up from nap */ | ||
247 | mfspr r1, SPRN_CTRLF | ||
248 | ori r1, r1, 1 | ||
249 | mtspr SPRN_CTRLT, r1 | ||
250 | |||
245 | ld r2,PACATOC(r13) | 251 | ld r2,PACATOC(r13) |
246 | 252 | ||
247 | li r0,KVM_HWTHREAD_IN_KVM | 253 | li r0,KVM_HWTHREAD_IN_KVM |
@@ -309,6 +315,11 @@ kvm_no_guest: | |||
309 | li r0, KVM_HWTHREAD_IN_NAP | 315 | li r0, KVM_HWTHREAD_IN_NAP |
310 | stb r0, HSTATE_HWTHREAD_STATE(r13) | 316 | stb r0, HSTATE_HWTHREAD_STATE(r13) |
311 | kvm_do_nap: | 317 | kvm_do_nap: |
318 | /* Clear the runlatch bit before napping */ | ||
319 | mfspr r2, SPRN_CTRLF | ||
320 | clrrdi r2, r2, 1 | ||
321 | mtspr SPRN_CTRLT, r2 | ||
322 | |||
312 | li r3, LPCR_PECE0 | 323 | li r3, LPCR_PECE0 |
313 | mfspr r4, SPRN_LPCR | 324 | mfspr r4, SPRN_LPCR |
314 | rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 | 325 | rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 |
@@ -1999,8 +2010,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | |||
1999 | 2010 | ||
2000 | /* | 2011 | /* |
2001 | * Take a nap until a decrementer or external or doobell interrupt | 2012 | * Take a nap until a decrementer or external or doobell interrupt |
2002 | * occurs, with PECE1, PECE0 and PECEDP set in LPCR | 2013 | * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the |
2014 | * runlatch bit before napping. | ||
2003 | */ | 2015 | */ |
2016 | mfspr r2, SPRN_CTRLF | ||
2017 | clrrdi r2, r2, 1 | ||
2018 | mtspr SPRN_CTRLT, r2 | ||
2019 | |||
2004 | li r0,1 | 2020 | li r0,1 |
2005 | stb r0,HSTATE_HWTHREAD_REQ(r13) | 2021 | stb r0,HSTATE_HWTHREAD_REQ(r13) |
2006 | mfspr r5,SPRN_LPCR | 2022 | mfspr r5,SPRN_LPCR |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 3ea26c25590b..cf1d325eae8b 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -82,17 +82,14 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) | |||
82 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); | 82 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
83 | va |= penc << 12; | 83 | va |= penc << 12; |
84 | va |= ssize << 8; | 84 | va |= ssize << 8; |
85 | /* Add AVAL part */ | 85 | /* |
86 | if (psize != apsize) { | 86 | * AVAL bits: |
87 | /* | 87 | * We don't need all the bits, but rest of the bits |
88 | * MPSS, 64K base page size and 16MB parge page size | 88 | * must be ignored by the processor. |
89 | * We don't need all the bits, but rest of the bits | 89 | * vpn cover upto 65 bits of va. (0...65) and we need |
90 | * must be ignored by the processor. | 90 | * 58..64 bits of va. |
91 | * vpn cover upto 65 bits of va. (0...65) and we need | 91 | */ |
92 | * 58..64 bits of va. | 92 | va |= (vpn & 0xfe); /* AVAL */ |
93 | */ | ||
94 | va |= (vpn & 0xfe); | ||
95 | } | ||
96 | va |= 1; /* L */ | 93 | va |= 1; /* L */ |
97 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) | 94 | asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) |
98 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) | 95 | : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) |
@@ -133,17 +130,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) | |||
133 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); | 130 | va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); |
134 | va |= penc << 12; | 131 | va |= penc << 12; |
135 | va |= ssize << 8; | 132 | va |= ssize << 8; |
136 | /* Add AVAL part */ | 133 | /* |
137 | if (psize != apsize) { | 134 | * AVAL bits: |
138 | /* | 135 | * We don't need all the bits, but rest of the bits |
139 | * MPSS, 64K base page size and 16MB parge page size | 136 | * must be ignored by the processor. |
140 | * We don't need all the bits, but rest of the bits | 137 | * vpn cover upto 65 bits of va. (0...65) and we need |
141 | * must be ignored by the processor. | 138 | * 58..64 bits of va. |
142 | * vpn cover upto 65 bits of va. (0...65) and we need | 139 | */ |
143 | * 58..64 bits of va. | 140 | va |= (vpn & 0xfe); |
144 | */ | ||
145 | va |= (vpn & 0xfe); | ||
146 | } | ||
147 | va |= 1; /* L */ | 141 | va |= 1; /* L */ |
148 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" | 142 | asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" |
149 | : : "r"(va) : "memory"); | 143 | : : "r"(va) : "memory"); |
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 297c91051413..e0766b82e165 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c | |||
@@ -155,16 +155,28 @@ static ssize_t read_offset_data(void *dest, size_t dest_len, | |||
155 | return copy_len; | 155 | return copy_len; |
156 | } | 156 | } |
157 | 157 | ||
158 | static unsigned long h_get_24x7_catalog_page(char page[static 4096], | 158 | static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096, |
159 | u32 version, u32 index) | 159 | unsigned long version, |
160 | unsigned long index) | ||
160 | { | 161 | { |
161 | WARN_ON(!IS_ALIGNED((unsigned long)page, 4096)); | 162 | pr_devel("h_get_24x7_catalog_page(0x%lx, %lu, %lu)", |
163 | phys_4096, | ||
164 | version, | ||
165 | index); | ||
166 | WARN_ON(!IS_ALIGNED(phys_4096, 4096)); | ||
162 | return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE, | 167 | return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE, |
163 | virt_to_phys(page), | 168 | phys_4096, |
164 | version, | 169 | version, |
165 | index); | 170 | index); |
166 | } | 171 | } |
167 | 172 | ||
173 | static unsigned long h_get_24x7_catalog_page(char page[], | ||
174 | u64 version, u32 index) | ||
175 | { | ||
176 | return h_get_24x7_catalog_page_(virt_to_phys(page), | ||
177 | version, index); | ||
178 | } | ||
179 | |||
168 | static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | 180 | static ssize_t catalog_read(struct file *filp, struct kobject *kobj, |
169 | struct bin_attribute *bin_attr, char *buf, | 181 | struct bin_attribute *bin_attr, char *buf, |
170 | loff_t offset, size_t count) | 182 | loff_t offset, size_t count) |
@@ -173,7 +185,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
173 | ssize_t ret = 0; | 185 | ssize_t ret = 0; |
174 | size_t catalog_len = 0, catalog_page_len = 0, page_count = 0; | 186 | size_t catalog_len = 0, catalog_page_len = 0, page_count = 0; |
175 | loff_t page_offset = 0; | 187 | loff_t page_offset = 0; |
176 | uint32_t catalog_version_num = 0; | 188 | uint64_t catalog_version_num = 0; |
177 | void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); | 189 | void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); |
178 | struct hv_24x7_catalog_page_0 *page_0 = page; | 190 | struct hv_24x7_catalog_page_0 *page_0 = page; |
179 | if (!page) | 191 | if (!page) |
@@ -185,7 +197,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
185 | goto e_free; | 197 | goto e_free; |
186 | } | 198 | } |
187 | 199 | ||
188 | catalog_version_num = be32_to_cpu(page_0->version); | 200 | catalog_version_num = be64_to_cpu(page_0->version); |
189 | catalog_page_len = be32_to_cpu(page_0->length); | 201 | catalog_page_len = be32_to_cpu(page_0->length); |
190 | catalog_len = catalog_page_len * 4096; | 202 | catalog_len = catalog_page_len * 4096; |
191 | 203 | ||
@@ -208,8 +220,9 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, | |||
208 | page, 4096, page_offset * 4096); | 220 | page, 4096, page_offset * 4096); |
209 | e_free: | 221 | e_free: |
210 | if (hret) | 222 | if (hret) |
211 | pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n", | 223 | pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:" |
212 | catalog_version_num, page_offset, hret); | 224 | " rc=%ld\n", |
225 | catalog_version_num, page_offset, hret); | ||
213 | kfree(page); | 226 | kfree(page); |
214 | 227 | ||
215 | pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n", | 228 | pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n", |
@@ -243,7 +256,7 @@ e_free: \ | |||
243 | static DEVICE_ATTR_RO(_name) | 256 | static DEVICE_ATTR_RO(_name) |
244 | 257 | ||
245 | PAGE_0_ATTR(catalog_version, "%lld\n", | 258 | PAGE_0_ATTR(catalog_version, "%lld\n", |
246 | (unsigned long long)be32_to_cpu(page_0->version)); | 259 | (unsigned long long)be64_to_cpu(page_0->version)); |
247 | PAGE_0_ATTR(catalog_len, "%lld\n", | 260 | PAGE_0_ATTR(catalog_len, "%lld\n", |
248 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); | 261 | (unsigned long long)be32_to_cpu(page_0->length) * 4096); |
249 | static BIN_ATTR_RO(catalog, 0/* real length varies */); | 262 | static BIN_ATTR_RO(catalog, 0/* real length varies */); |
@@ -485,13 +498,13 @@ static int hv_24x7_init(void) | |||
485 | struct hv_perf_caps caps; | 498 | struct hv_perf_caps caps; |
486 | 499 | ||
487 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { | 500 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
488 | pr_info("not a virtualized system, not enabling\n"); | 501 | pr_debug("not a virtualized system, not enabling\n"); |
489 | return -ENODEV; | 502 | return -ENODEV; |
490 | } | 503 | } |
491 | 504 | ||
492 | hret = hv_perf_caps_get(&caps); | 505 | hret = hv_perf_caps_get(&caps); |
493 | if (hret) { | 506 | if (hret) { |
494 | pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", | 507 | pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", |
495 | hret); | 508 | hret); |
496 | return -ENODEV; | 509 | return -ENODEV; |
497 | } | 510 | } |
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 278ba7b9c2b5..c9d399a2df82 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c | |||
@@ -78,7 +78,7 @@ static ssize_t kernel_version_show(struct device *dev, | |||
78 | return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); | 78 | return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); |
79 | } | 79 | } |
80 | 80 | ||
81 | DEVICE_ATTR_RO(kernel_version); | 81 | static DEVICE_ATTR_RO(kernel_version); |
82 | HV_CAPS_ATTR(version, "0x%x\n"); | 82 | HV_CAPS_ATTR(version, "0x%x\n"); |
83 | HV_CAPS_ATTR(ga, "%d\n"); | 83 | HV_CAPS_ATTR(ga, "%d\n"); |
84 | HV_CAPS_ATTR(expanded, "%d\n"); | 84 | HV_CAPS_ATTR(expanded, "%d\n"); |
@@ -273,13 +273,13 @@ static int hv_gpci_init(void) | |||
273 | struct hv_perf_caps caps; | 273 | struct hv_perf_caps caps; |
274 | 274 | ||
275 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { | 275 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
276 | pr_info("not a virtualized system, not enabling\n"); | 276 | pr_debug("not a virtualized system, not enabling\n"); |
277 | return -ENODEV; | 277 | return -ENODEV; |
278 | } | 278 | } |
279 | 279 | ||
280 | hret = hv_perf_caps_get(&caps); | 280 | hret = hv_perf_caps_get(&caps); |
281 | if (hret) { | 281 | if (hret) { |
282 | pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", | 282 | pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", |
283 | hret); | 283 | hret); |
284 | return -ENODEV; | 284 | return -ENODEV; |
285 | } | 285 | } |
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index b9827b0d87e4..788a1977b9a5 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c | |||
@@ -209,89 +209,20 @@ static struct kobj_type dump_ktype = { | |||
209 | .default_attrs = dump_default_attrs, | 209 | .default_attrs = dump_default_attrs, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | static void free_dump_sg_list(struct opal_sg_list *list) | 212 | static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type) |
213 | { | ||
214 | struct opal_sg_list *sg1; | ||
215 | while (list) { | ||
216 | sg1 = list->next; | ||
217 | kfree(list); | ||
218 | list = sg1; | ||
219 | } | ||
220 | list = NULL; | ||
221 | } | ||
222 | |||
223 | static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump) | ||
224 | { | ||
225 | struct opal_sg_list *sg1, *list = NULL; | ||
226 | void *addr; | ||
227 | int64_t size; | ||
228 | |||
229 | addr = dump->buffer; | ||
230 | size = dump->size; | ||
231 | |||
232 | sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
233 | if (!sg1) | ||
234 | goto nomem; | ||
235 | |||
236 | list = sg1; | ||
237 | sg1->num_entries = 0; | ||
238 | while (size > 0) { | ||
239 | /* Translate virtual address to physical address */ | ||
240 | sg1->entry[sg1->num_entries].data = | ||
241 | (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); | ||
242 | |||
243 | if (size > PAGE_SIZE) | ||
244 | sg1->entry[sg1->num_entries].length = PAGE_SIZE; | ||
245 | else | ||
246 | sg1->entry[sg1->num_entries].length = size; | ||
247 | |||
248 | sg1->num_entries++; | ||
249 | if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { | ||
250 | sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
251 | if (!sg1->next) | ||
252 | goto nomem; | ||
253 | |||
254 | sg1 = sg1->next; | ||
255 | sg1->num_entries = 0; | ||
256 | } | ||
257 | addr += PAGE_SIZE; | ||
258 | size -= PAGE_SIZE; | ||
259 | } | ||
260 | return list; | ||
261 | |||
262 | nomem: | ||
263 | pr_err("%s : Failed to allocate memory\n", __func__); | ||
264 | free_dump_sg_list(list); | ||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | static void sglist_to_phy_addr(struct opal_sg_list *list) | ||
269 | { | ||
270 | struct opal_sg_list *sg, *next; | ||
271 | |||
272 | for (sg = list; sg; sg = next) { | ||
273 | next = sg->next; | ||
274 | /* Don't translate NULL pointer for last entry */ | ||
275 | if (sg->next) | ||
276 | sg->next = (struct opal_sg_list *)__pa(sg->next); | ||
277 | else | ||
278 | sg->next = NULL; | ||
279 | |||
280 | /* Convert num_entries to length */ | ||
281 | sg->num_entries = | ||
282 | sg->num_entries * sizeof(struct opal_sg_entry) + 16; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type) | ||
287 | { | 213 | { |
214 | __be32 id, size, type; | ||
288 | int rc; | 215 | int rc; |
289 | *type = 0xffffffff; | ||
290 | 216 | ||
291 | rc = opal_dump_info2(id, size, type); | 217 | type = cpu_to_be32(0xffffffff); |
292 | 218 | ||
219 | rc = opal_dump_info2(&id, &size, &type); | ||
293 | if (rc == OPAL_PARAMETER) | 220 | if (rc == OPAL_PARAMETER) |
294 | rc = opal_dump_info(id, size); | 221 | rc = opal_dump_info(&id, &size); |
222 | |||
223 | *dump_id = be32_to_cpu(id); | ||
224 | *dump_size = be32_to_cpu(size); | ||
225 | *dump_type = be32_to_cpu(type); | ||
295 | 226 | ||
296 | if (rc) | 227 | if (rc) |
297 | pr_warn("%s: Failed to get dump info (%d)\n", | 228 | pr_warn("%s: Failed to get dump info (%d)\n", |
@@ -314,15 +245,12 @@ static int64_t dump_read_data(struct dump_obj *dump) | |||
314 | } | 245 | } |
315 | 246 | ||
316 | /* Generate SG list */ | 247 | /* Generate SG list */ |
317 | list = dump_data_to_sglist(dump); | 248 | list = opal_vmalloc_to_sg_list(dump->buffer, dump->size); |
318 | if (!list) { | 249 | if (!list) { |
319 | rc = -ENOMEM; | 250 | rc = -ENOMEM; |
320 | goto out; | 251 | goto out; |
321 | } | 252 | } |
322 | 253 | ||
323 | /* Translate sg list addr to real address */ | ||
324 | sglist_to_phy_addr(list); | ||
325 | |||
326 | /* First entry address */ | 254 | /* First entry address */ |
327 | addr = __pa(list); | 255 | addr = __pa(list); |
328 | 256 | ||
@@ -341,7 +269,7 @@ static int64_t dump_read_data(struct dump_obj *dump) | |||
341 | __func__, dump->id); | 269 | __func__, dump->id); |
342 | 270 | ||
343 | /* Free SG list */ | 271 | /* Free SG list */ |
344 | free_dump_sg_list(list); | 272 | opal_free_sg_list(list); |
345 | 273 | ||
346 | out: | 274 | out: |
347 | return rc; | 275 | return rc; |
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index ef7bc2a97862..10268c41d830 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c | |||
@@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) | |||
238 | 238 | ||
239 | static void elog_work_fn(struct work_struct *work) | 239 | static void elog_work_fn(struct work_struct *work) |
240 | { | 240 | { |
241 | size_t elog_size; | 241 | __be64 size; |
242 | __be64 id; | ||
243 | __be64 type; | ||
244 | uint64_t elog_size; | ||
242 | uint64_t log_id; | 245 | uint64_t log_id; |
243 | uint64_t elog_type; | 246 | uint64_t elog_type; |
244 | int rc; | 247 | int rc; |
245 | char name[2+16+1]; | 248 | char name[2+16+1]; |
246 | 249 | ||
247 | rc = opal_get_elog_size(&log_id, &elog_size, &elog_type); | 250 | rc = opal_get_elog_size(&id, &size, &type); |
248 | if (rc != OPAL_SUCCESS) { | 251 | if (rc != OPAL_SUCCESS) { |
249 | pr_err("ELOG: Opal log read failed\n"); | 252 | pr_err("ELOG: Opal log read failed\n"); |
250 | return; | 253 | return; |
251 | } | 254 | } |
252 | 255 | ||
256 | elog_size = be64_to_cpu(size); | ||
257 | log_id = be64_to_cpu(id); | ||
258 | elog_type = be64_to_cpu(type); | ||
259 | |||
253 | BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); | 260 | BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); |
254 | 261 | ||
255 | if (elog_size >= OPAL_MAX_ERRLOG_SIZE) | 262 | if (elog_size >= OPAL_MAX_ERRLOG_SIZE) |
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index 714ef972406b..dc487ff04704 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c | |||
@@ -79,9 +79,6 @@ | |||
79 | /* XXX: Assume candidate image size is <= 1GB */ | 79 | /* XXX: Assume candidate image size is <= 1GB */ |
80 | #define MAX_IMAGE_SIZE 0x40000000 | 80 | #define MAX_IMAGE_SIZE 0x40000000 |
81 | 81 | ||
82 | /* Flash sg list version */ | ||
83 | #define SG_LIST_VERSION (1UL) | ||
84 | |||
85 | /* Image status */ | 82 | /* Image status */ |
86 | enum { | 83 | enum { |
87 | IMAGE_INVALID, | 84 | IMAGE_INVALID, |
@@ -131,11 +128,15 @@ static DEFINE_MUTEX(image_data_mutex); | |||
131 | */ | 128 | */ |
132 | static inline void opal_flash_validate(void) | 129 | static inline void opal_flash_validate(void) |
133 | { | 130 | { |
134 | struct validate_flash_t *args_buf = &validate_flash_data; | 131 | long ret; |
132 | void *buf = validate_flash_data.buf; | ||
133 | __be32 size, result; | ||
135 | 134 | ||
136 | args_buf->status = opal_validate_flash(__pa(args_buf->buf), | 135 | ret = opal_validate_flash(__pa(buf), &size, &result); |
137 | &(args_buf->buf_size), | 136 | |
138 | &(args_buf->result)); | 137 | validate_flash_data.status = ret; |
138 | validate_flash_data.buf_size = be32_to_cpu(size); | ||
139 | validate_flash_data.result = be32_to_cpu(result); | ||
139 | } | 140 | } |
140 | 141 | ||
141 | /* | 142 | /* |
@@ -268,93 +269,11 @@ static ssize_t manage_store(struct kobject *kobj, | |||
268 | } | 269 | } |
269 | 270 | ||
270 | /* | 271 | /* |
271 | * Free sg list | ||
272 | */ | ||
273 | static void free_sg_list(struct opal_sg_list *list) | ||
274 | { | ||
275 | struct opal_sg_list *sg1; | ||
276 | while (list) { | ||
277 | sg1 = list->next; | ||
278 | kfree(list); | ||
279 | list = sg1; | ||
280 | } | ||
281 | list = NULL; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Build candidate image scatter gather list | ||
286 | * | ||
287 | * list format: | ||
288 | * ----------------------------------- | ||
289 | * | VER (8) | Entry length in bytes | | ||
290 | * ----------------------------------- | ||
291 | * | Pointer to next entry | | ||
292 | * ----------------------------------- | ||
293 | * | Address of memory area 1 | | ||
294 | * ----------------------------------- | ||
295 | * | Length of memory area 1 | | ||
296 | * ----------------------------------- | ||
297 | * | ......... | | ||
298 | * ----------------------------------- | ||
299 | * | ......... | | ||
300 | * ----------------------------------- | ||
301 | * | Address of memory area N | | ||
302 | * ----------------------------------- | ||
303 | * | Length of memory area N | | ||
304 | * ----------------------------------- | ||
305 | */ | ||
306 | static struct opal_sg_list *image_data_to_sglist(void) | ||
307 | { | ||
308 | struct opal_sg_list *sg1, *list = NULL; | ||
309 | void *addr; | ||
310 | int size; | ||
311 | |||
312 | addr = image_data.data; | ||
313 | size = image_data.size; | ||
314 | |||
315 | sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
316 | if (!sg1) | ||
317 | return NULL; | ||
318 | |||
319 | list = sg1; | ||
320 | sg1->num_entries = 0; | ||
321 | while (size > 0) { | ||
322 | /* Translate virtual address to physical address */ | ||
323 | sg1->entry[sg1->num_entries].data = | ||
324 | (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); | ||
325 | |||
326 | if (size > PAGE_SIZE) | ||
327 | sg1->entry[sg1->num_entries].length = PAGE_SIZE; | ||
328 | else | ||
329 | sg1->entry[sg1->num_entries].length = size; | ||
330 | |||
331 | sg1->num_entries++; | ||
332 | if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { | ||
333 | sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
334 | if (!sg1->next) { | ||
335 | pr_err("%s : Failed to allocate memory\n", | ||
336 | __func__); | ||
337 | goto nomem; | ||
338 | } | ||
339 | |||
340 | sg1 = sg1->next; | ||
341 | sg1->num_entries = 0; | ||
342 | } | ||
343 | addr += PAGE_SIZE; | ||
344 | size -= PAGE_SIZE; | ||
345 | } | ||
346 | return list; | ||
347 | nomem: | ||
348 | free_sg_list(list); | ||
349 | return NULL; | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * OPAL update flash | 272 | * OPAL update flash |
354 | */ | 273 | */ |
355 | static int opal_flash_update(int op) | 274 | static int opal_flash_update(int op) |
356 | { | 275 | { |
357 | struct opal_sg_list *sg, *list, *next; | 276 | struct opal_sg_list *list; |
358 | unsigned long addr; | 277 | unsigned long addr; |
359 | int64_t rc = OPAL_PARAMETER; | 278 | int64_t rc = OPAL_PARAMETER; |
360 | 279 | ||
@@ -364,30 +283,13 @@ static int opal_flash_update(int op) | |||
364 | goto flash; | 283 | goto flash; |
365 | } | 284 | } |
366 | 285 | ||
367 | list = image_data_to_sglist(); | 286 | list = opal_vmalloc_to_sg_list(image_data.data, image_data.size); |
368 | if (!list) | 287 | if (!list) |
369 | goto invalid_img; | 288 | goto invalid_img; |
370 | 289 | ||
371 | /* First entry address */ | 290 | /* First entry address */ |
372 | addr = __pa(list); | 291 | addr = __pa(list); |
373 | 292 | ||
374 | /* Translate sg list address to absolute */ | ||
375 | for (sg = list; sg; sg = next) { | ||
376 | next = sg->next; | ||
377 | /* Don't translate NULL pointer for last entry */ | ||
378 | if (sg->next) | ||
379 | sg->next = (struct opal_sg_list *)__pa(sg->next); | ||
380 | else | ||
381 | sg->next = NULL; | ||
382 | |||
383 | /* | ||
384 | * Convert num_entries to version/length format | ||
385 | * to satisfy OPAL. | ||
386 | */ | ||
387 | sg->num_entries = (SG_LIST_VERSION << 56) | | ||
388 | (sg->num_entries * sizeof(struct opal_sg_entry) + 16); | ||
389 | } | ||
390 | |||
391 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); | 293 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); |
392 | pr_alert("FLASH: Image update requested\n"); | 294 | pr_alert("FLASH: Image update requested\n"); |
393 | pr_alert("FLASH: Image will be updated during system reboot\n"); | 295 | pr_alert("FLASH: Image will be updated during system reboot\n"); |
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 6b614726baf2..d202f9bc3683 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c | |||
@@ -39,10 +39,11 @@ struct param_attr { | |||
39 | struct kobj_attribute kobj_attr; | 39 | struct kobj_attribute kobj_attr; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) | 42 | static ssize_t opal_get_sys_param(u32 param_id, u32 length, void *buffer) |
43 | { | 43 | { |
44 | struct opal_msg msg; | 44 | struct opal_msg msg; |
45 | int ret, token; | 45 | ssize_t ret; |
46 | int token; | ||
46 | 47 | ||
47 | token = opal_async_get_token_interruptible(); | 48 | token = opal_async_get_token_interruptible(); |
48 | if (token < 0) { | 49 | if (token < 0) { |
@@ -59,7 +60,7 @@ static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) | |||
59 | 60 | ||
60 | ret = opal_async_wait_response(token, &msg); | 61 | ret = opal_async_wait_response(token, &msg); |
61 | if (ret) { | 62 | if (ret) { |
62 | pr_err("%s: Failed to wait for the async response, %d\n", | 63 | pr_err("%s: Failed to wait for the async response, %zd\n", |
63 | __func__, ret); | 64 | __func__, ret); |
64 | goto out_token; | 65 | goto out_token; |
65 | } | 66 | } |
@@ -111,7 +112,7 @@ static ssize_t sys_param_show(struct kobject *kobj, | |||
111 | { | 112 | { |
112 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, | 113 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, |
113 | kobj_attr); | 114 | kobj_attr); |
114 | int ret; | 115 | ssize_t ret; |
115 | 116 | ||
116 | mutex_lock(&opal_sysparam_mutex); | 117 | mutex_lock(&opal_sysparam_mutex); |
117 | ret = opal_get_sys_param(attr->param_id, attr->param_size, | 118 | ret = opal_get_sys_param(attr->param_id, attr->param_size, |
@@ -121,9 +122,10 @@ static ssize_t sys_param_show(struct kobject *kobj, | |||
121 | 122 | ||
122 | memcpy(buf, param_data_buf, attr->param_size); | 123 | memcpy(buf, param_data_buf, attr->param_size); |
123 | 124 | ||
125 | ret = attr->param_size; | ||
124 | out: | 126 | out: |
125 | mutex_unlock(&opal_sysparam_mutex); | 127 | mutex_unlock(&opal_sysparam_mutex); |
126 | return ret ? ret : attr->param_size; | 128 | return ret; |
127 | } | 129 | } |
128 | 130 | ||
129 | static ssize_t sys_param_store(struct kobject *kobj, | 131 | static ssize_t sys_param_store(struct kobject *kobj, |
@@ -131,14 +133,20 @@ static ssize_t sys_param_store(struct kobject *kobj, | |||
131 | { | 133 | { |
132 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, | 134 | struct param_attr *attr = container_of(kobj_attr, struct param_attr, |
133 | kobj_attr); | 135 | kobj_attr); |
134 | int ret; | 136 | ssize_t ret; |
137 | |||
138 | /* MAX_PARAM_DATA_LEN is sizeof(param_data_buf) */ | ||
139 | if (count > MAX_PARAM_DATA_LEN) | ||
140 | count = MAX_PARAM_DATA_LEN; | ||
135 | 141 | ||
136 | mutex_lock(&opal_sysparam_mutex); | 142 | mutex_lock(&opal_sysparam_mutex); |
137 | memcpy(param_data_buf, buf, count); | 143 | memcpy(param_data_buf, buf, count); |
138 | ret = opal_set_sys_param(attr->param_id, attr->param_size, | 144 | ret = opal_set_sys_param(attr->param_id, attr->param_size, |
139 | param_data_buf); | 145 | param_data_buf); |
140 | mutex_unlock(&opal_sysparam_mutex); | 146 | mutex_unlock(&opal_sysparam_mutex); |
141 | return ret ? ret : count; | 147 | if (!ret) |
148 | ret = count; | ||
149 | return ret; | ||
142 | } | 150 | } |
143 | 151 | ||
144 | void __init opal_sys_param_init(void) | 152 | void __init opal_sys_param_init(void) |
@@ -214,13 +222,13 @@ void __init opal_sys_param_init(void) | |||
214 | } | 222 | } |
215 | 223 | ||
216 | if (of_property_read_u32_array(sysparam, "param-len", size, count)) { | 224 | if (of_property_read_u32_array(sysparam, "param-len", size, count)) { |
217 | pr_err("SYSPARAM: Missing propery param-len in the DT\n"); | 225 | pr_err("SYSPARAM: Missing property param-len in the DT\n"); |
218 | goto out_free_perm; | 226 | goto out_free_perm; |
219 | } | 227 | } |
220 | 228 | ||
221 | 229 | ||
222 | if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { | 230 | if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { |
223 | pr_err("SYSPARAM: Missing propery param-perm in the DT\n"); | 231 | pr_err("SYSPARAM: Missing property param-perm in the DT\n"); |
224 | goto out_free_perm; | 232 | goto out_free_perm; |
225 | } | 233 | } |
226 | 234 | ||
@@ -233,6 +241,12 @@ void __init opal_sys_param_init(void) | |||
233 | 241 | ||
234 | /* For each of the parameters, populate the parameter attributes */ | 242 | /* For each of the parameters, populate the parameter attributes */ |
235 | for (i = 0; i < count; i++) { | 243 | for (i = 0; i < count; i++) { |
244 | if (size[i] > MAX_PARAM_DATA_LEN) { | ||
245 | pr_warn("SYSPARAM: Not creating parameter %d as size " | ||
246 | "exceeds buffer length\n", i); | ||
247 | continue; | ||
248 | } | ||
249 | |||
236 | sysfs_attr_init(&attr[i].kobj_attr.attr); | 250 | sysfs_attr_init(&attr[i].kobj_attr.attr); |
237 | attr[i].param_id = id[i]; | 251 | attr[i].param_id = id[i]; |
238 | attr[i].param_size = size[i]; | 252 | attr[i].param_size = size[i]; |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 49d2f00019e5..360ad80c754c 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -242,14 +242,14 @@ void opal_notifier_update_evt(uint64_t evt_mask, | |||
242 | void opal_notifier_enable(void) | 242 | void opal_notifier_enable(void) |
243 | { | 243 | { |
244 | int64_t rc; | 244 | int64_t rc; |
245 | uint64_t evt = 0; | 245 | __be64 evt = 0; |
246 | 246 | ||
247 | atomic_set(&opal_notifier_hold, 0); | 247 | atomic_set(&opal_notifier_hold, 0); |
248 | 248 | ||
249 | /* Process pending events */ | 249 | /* Process pending events */ |
250 | rc = opal_poll_events(&evt); | 250 | rc = opal_poll_events(&evt); |
251 | if (rc == OPAL_SUCCESS && evt) | 251 | if (rc == OPAL_SUCCESS && evt) |
252 | opal_do_notifier(evt); | 252 | opal_do_notifier(be64_to_cpu(evt)); |
253 | } | 253 | } |
254 | 254 | ||
255 | void opal_notifier_disable(void) | 255 | void opal_notifier_disable(void) |
@@ -529,7 +529,7 @@ static irqreturn_t opal_interrupt(int irq, void *data) | |||
529 | 529 | ||
530 | opal_handle_interrupt(virq_to_hw(irq), &events); | 530 | opal_handle_interrupt(virq_to_hw(irq), &events); |
531 | 531 | ||
532 | opal_do_notifier(events); | 532 | opal_do_notifier(be64_to_cpu(events)); |
533 | 533 | ||
534 | return IRQ_HANDLED; | 534 | return IRQ_HANDLED; |
535 | } | 535 | } |
@@ -638,3 +638,66 @@ void opal_shutdown(void) | |||
638 | 638 | ||
639 | /* Export this so that test modules can use it */ | 639 | /* Export this so that test modules can use it */ |
640 | EXPORT_SYMBOL_GPL(opal_invalid_call); | 640 | EXPORT_SYMBOL_GPL(opal_invalid_call); |
641 | |||
642 | /* Convert a region of vmalloc memory to an opal sg list */ | ||
643 | struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, | ||
644 | unsigned long vmalloc_size) | ||
645 | { | ||
646 | struct opal_sg_list *sg, *first = NULL; | ||
647 | unsigned long i = 0; | ||
648 | |||
649 | sg = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
650 | if (!sg) | ||
651 | goto nomem; | ||
652 | |||
653 | first = sg; | ||
654 | |||
655 | while (vmalloc_size > 0) { | ||
656 | uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT; | ||
657 | uint64_t length = min(vmalloc_size, PAGE_SIZE); | ||
658 | |||
659 | sg->entry[i].data = cpu_to_be64(data); | ||
660 | sg->entry[i].length = cpu_to_be64(length); | ||
661 | i++; | ||
662 | |||
663 | if (i >= SG_ENTRIES_PER_NODE) { | ||
664 | struct opal_sg_list *next; | ||
665 | |||
666 | next = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
667 | if (!next) | ||
668 | goto nomem; | ||
669 | |||
670 | sg->length = cpu_to_be64( | ||
671 | i * sizeof(struct opal_sg_entry) + 16); | ||
672 | i = 0; | ||
673 | sg->next = cpu_to_be64(__pa(next)); | ||
674 | sg = next; | ||
675 | } | ||
676 | |||
677 | vmalloc_addr += length; | ||
678 | vmalloc_size -= length; | ||
679 | } | ||
680 | |||
681 | sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16); | ||
682 | |||
683 | return first; | ||
684 | |||
685 | nomem: | ||
686 | pr_err("%s : Failed to allocate memory\n", __func__); | ||
687 | opal_free_sg_list(first); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | void opal_free_sg_list(struct opal_sg_list *sg) | ||
692 | { | ||
693 | while (sg) { | ||
694 | uint64_t next = be64_to_cpu(sg->next); | ||
695 | |||
696 | kfree(sg); | ||
697 | |||
698 | if (next) | ||
699 | sg = __va(next); | ||
700 | else | ||
701 | sg = NULL; | ||
702 | } | ||
703 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3b2b4fb3585b..98824aa99173 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -343,7 +343,6 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) | |||
343 | pci_name(dev)); | 343 | pci_name(dev)); |
344 | continue; | 344 | continue; |
345 | } | 345 | } |
346 | pci_dev_get(dev); | ||
347 | pdn->pcidev = dev; | 346 | pdn->pcidev = dev; |
348 | pdn->pe_number = pe->pe_number; | 347 | pdn->pe_number = pe->pe_number; |
349 | pe->dma_weight += pnv_ioda_dma_weight(dev); | 348 | pe->dma_weight += pnv_ioda_dma_weight(dev); |
@@ -462,7 +461,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev | |||
462 | 461 | ||
463 | pe = &phb->ioda.pe_array[pdn->pe_number]; | 462 | pe = &phb->ioda.pe_array[pdn->pe_number]; |
464 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); | 463 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); |
465 | set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table); | 464 | set_iommu_table_base(&pdev->dev, &pe->tce32_table); |
466 | } | 465 | } |
467 | 466 | ||
468 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, | 467 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 61cf8fa9c61b..8723d32632f5 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -162,18 +162,62 @@ static void pnv_shutdown(void) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef CONFIG_KEXEC | 164 | #ifdef CONFIG_KEXEC |
165 | static void pnv_kexec_wait_secondaries_down(void) | ||
166 | { | ||
167 | int my_cpu, i, notified = -1; | ||
168 | |||
169 | my_cpu = get_cpu(); | ||
170 | |||
171 | for_each_online_cpu(i) { | ||
172 | uint8_t status; | ||
173 | int64_t rc; | ||
174 | |||
175 | if (i == my_cpu) | ||
176 | continue; | ||
177 | |||
178 | for (;;) { | ||
179 | rc = opal_query_cpu_status(get_hard_smp_processor_id(i), | ||
180 | &status); | ||
181 | if (rc != OPAL_SUCCESS || status != OPAL_THREAD_STARTED) | ||
182 | break; | ||
183 | barrier(); | ||
184 | if (i != notified) { | ||
185 | printk(KERN_INFO "kexec: waiting for cpu %d " | ||
186 | "(physical %d) to enter OPAL\n", | ||
187 | i, paca[i].hw_cpu_id); | ||
188 | notified = i; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
165 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) | 194 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) |
166 | { | 195 | { |
167 | xics_kexec_teardown_cpu(secondary); | 196 | xics_kexec_teardown_cpu(secondary); |
168 | 197 | ||
169 | /* Return secondary CPUs to firmware on OPAL v3 */ | 198 | /* On OPAL v3, we return all CPUs to firmware */ |
170 | if (firmware_has_feature(FW_FEATURE_OPALv3) && secondary) { | 199 | |
200 | if (!firmware_has_feature(FW_FEATURE_OPALv3)) | ||
201 | return; | ||
202 | |||
203 | if (secondary) { | ||
204 | /* Return secondary CPUs to firmware on OPAL v3 */ | ||
171 | mb(); | 205 | mb(); |
172 | get_paca()->kexec_state = KEXEC_STATE_REAL_MODE; | 206 | get_paca()->kexec_state = KEXEC_STATE_REAL_MODE; |
173 | mb(); | 207 | mb(); |
174 | 208 | ||
175 | /* Return the CPU to OPAL */ | 209 | /* Return the CPU to OPAL */ |
176 | opal_return_cpu(); | 210 | opal_return_cpu(); |
211 | } else if (crash_shutdown) { | ||
212 | /* | ||
213 | * On crash, we don't wait for secondaries to go | ||
214 | * down as they might be unreachable or hung, so | ||
215 | * instead we just wait a bit and move on. | ||
216 | */ | ||
217 | mdelay(1); | ||
218 | } else { | ||
219 | /* Primary waits for the secondaries to have reached OPAL */ | ||
220 | pnv_kexec_wait_secondaries_down(); | ||
177 | } | 221 | } |
178 | } | 222 | } |
179 | #endif /* CONFIG_KEXEC */ | 223 | #endif /* CONFIG_KEXEC */ |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 908672bdcea6..bf5fcd452168 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/cputhreads.h> | 30 | #include <asm/cputhreads.h> |
31 | #include <asm/xics.h> | 31 | #include <asm/xics.h> |
32 | #include <asm/opal.h> | 32 | #include <asm/opal.h> |
33 | #include <asm/runlatch.h> | ||
33 | 34 | ||
34 | #include "powernv.h" | 35 | #include "powernv.h" |
35 | 36 | ||
@@ -156,7 +157,9 @@ static void pnv_smp_cpu_kill_self(void) | |||
156 | */ | 157 | */ |
157 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); | 158 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); |
158 | while (!generic_check_cpu_restart(cpu)) { | 159 | while (!generic_check_cpu_restart(cpu)) { |
160 | ppc64_runlatch_off(); | ||
159 | power7_nap(); | 161 | power7_nap(); |
162 | ppc64_runlatch_on(); | ||
160 | if (!generic_check_cpu_restart(cpu)) { | 163 | if (!generic_check_cpu_restart(cpu)) { |
161 | DBG("CPU%d Unexpected exit while offline !\n", cpu); | 164 | DBG("CPU%d Unexpected exit while offline !\n", cpu); |
162 | /* We may be getting an IPI, so we re-enable | 165 | /* We may be getting an IPI, so we re-enable |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9b8e05078a63..20d62975856f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -88,13 +88,14 @@ void set_default_offline_state(int cpu) | |||
88 | 88 | ||
89 | static void rtas_stop_self(void) | 89 | static void rtas_stop_self(void) |
90 | { | 90 | { |
91 | struct rtas_args args = { | 91 | static struct rtas_args args = { |
92 | .token = cpu_to_be32(rtas_stop_self_token), | ||
93 | .nargs = 0, | 92 | .nargs = 0, |
94 | .nret = 1, | 93 | .nret = 1, |
95 | .rets = &args.args[0], | 94 | .rets = &args.args[0], |
96 | }; | 95 | }; |
97 | 96 | ||
97 | args.token = cpu_to_be32(rtas_stop_self_token); | ||
98 | |||
98 | local_irq_disable(); | 99 | local_irq_disable(); |
99 | 100 | ||
100 | BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); | 101 | BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 573b488fc48b..7f75c94af822 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -100,10 +100,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz | |||
100 | 100 | ||
101 | start_pfn = base >> PAGE_SHIFT; | 101 | start_pfn = base >> PAGE_SHIFT; |
102 | 102 | ||
103 | if (!pfn_valid(start_pfn)) { | 103 | lock_device_hotplug(); |
104 | memblock_remove(base, memblock_size); | 104 | |
105 | return 0; | 105 | if (!pfn_valid(start_pfn)) |
106 | } | 106 | goto out; |
107 | 107 | ||
108 | block_sz = memory_block_size_bytes(); | 108 | block_sz = memory_block_size_bytes(); |
109 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; | 109 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; |
@@ -114,8 +114,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz | |||
114 | base += MIN_MEMORY_BLOCK_SIZE; | 114 | base += MIN_MEMORY_BLOCK_SIZE; |
115 | } | 115 | } |
116 | 116 | ||
117 | out: | ||
117 | /* Update memory regions for memory remove */ | 118 | /* Update memory regions for memory remove */ |
118 | memblock_remove(base, memblock_size); | 119 | memblock_remove(base, memblock_size); |
120 | unlock_device_hotplug(); | ||
119 | return 0; | 121 | return 0; |
120 | } | 122 | } |
121 | 123 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 64603a10b863..4914fd3f41ec 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -1058,7 +1058,7 @@ static int __init apm821xx_pciex_core_init(struct device_node *np) | |||
1058 | return 1; | 1058 | return 1; |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | static int apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1061 | static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1062 | { | 1062 | { |
1063 | u32 val; | 1063 | u32 val; |
1064 | 1064 | ||
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 9c36dc398f90..452d3ebd9d0f 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -276,7 +276,6 @@ static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter) | |||
276 | case BPF_S_LD_W_IND: | 276 | case BPF_S_LD_W_IND: |
277 | case BPF_S_LD_H_IND: | 277 | case BPF_S_LD_H_IND: |
278 | case BPF_S_LD_B_IND: | 278 | case BPF_S_LD_B_IND: |
279 | case BPF_S_LDX_B_MSH: | ||
280 | case BPF_S_LD_IMM: | 279 | case BPF_S_LD_IMM: |
281 | case BPF_S_LD_MEM: | 280 | case BPF_S_LD_MEM: |
282 | case BPF_S_MISC_TXA: | 281 | case BPF_S_MISC_TXA: |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 0f9e94537eee..fde5abaac0cc 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -71,6 +71,23 @@ | |||
71 | 71 | ||
72 | #include <linux/sched.h> | 72 | #include <linux/sched.h> |
73 | 73 | ||
74 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
75 | |||
76 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
77 | static inline bool __kern_addr_valid(unsigned long paddr) | ||
78 | { | ||
79 | if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL) | ||
80 | return false; | ||
81 | return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap); | ||
82 | } | ||
83 | |||
84 | static inline bool kern_addr_valid(unsigned long addr) | ||
85 | { | ||
86 | unsigned long paddr = __pa(addr); | ||
87 | |||
88 | return __kern_addr_valid(paddr); | ||
89 | } | ||
90 | |||
74 | /* Entries per page directory level. */ | 91 | /* Entries per page directory level. */ |
75 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) | 92 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) |
76 | #define PTRS_PER_PMD (1UL << PMD_BITS) | 93 | #define PTRS_PER_PMD (1UL << PMD_BITS) |
@@ -79,9 +96,12 @@ | |||
79 | /* Kernel has a separate 44bit address space. */ | 96 | /* Kernel has a separate 44bit address space. */ |
80 | #define FIRST_USER_ADDRESS 0 | 97 | #define FIRST_USER_ADDRESS 0 |
81 | 98 | ||
82 | #define pte_ERROR(e) __builtin_trap() | 99 | #define pmd_ERROR(e) \ |
83 | #define pmd_ERROR(e) __builtin_trap() | 100 | pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ |
84 | #define pgd_ERROR(e) __builtin_trap() | 101 | __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) |
102 | #define pgd_ERROR(e) \ | ||
103 | pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ | ||
104 | __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) | ||
85 | 105 | ||
86 | #endif /* !(__ASSEMBLY__) */ | 106 | #endif /* !(__ASSEMBLY__) */ |
87 | 107 | ||
@@ -258,8 +278,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
258 | { | 278 | { |
259 | unsigned long mask, tmp; | 279 | unsigned long mask, tmp; |
260 | 280 | ||
261 | /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347) | 281 | /* SUN4U: 0x630107ffffffec38 (negated == 0x9cfef800000013c7) |
262 | * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8) | 282 | * SUN4V: 0x33ffffffffffee07 (negated == 0xcc000000000011f8) |
263 | * | 283 | * |
264 | * Even if we use negation tricks the result is still a 6 | 284 | * Even if we use negation tricks the result is still a 6 |
265 | * instruction sequence, so don't try to play fancy and just | 285 | * instruction sequence, so don't try to play fancy and just |
@@ -289,10 +309,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
289 | " .previous\n" | 309 | " .previous\n" |
290 | : "=r" (mask), "=r" (tmp) | 310 | : "=r" (mask), "=r" (tmp) |
291 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | | 311 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | |
292 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | | 312 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | |
293 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), | 313 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), |
294 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | | 314 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | |
295 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | | 315 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | |
296 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); | 316 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); |
297 | 317 | ||
298 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); | 318 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); |
@@ -633,7 +653,7 @@ static inline unsigned long pmd_large(pmd_t pmd) | |||
633 | { | 653 | { |
634 | pte_t pte = __pte(pmd_val(pmd)); | 654 | pte_t pte = __pte(pmd_val(pmd)); |
635 | 655 | ||
636 | return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte); | 656 | return pte_val(pte) & _PAGE_PMD_HUGE; |
637 | } | 657 | } |
638 | 658 | ||
639 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 659 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
@@ -719,20 +739,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) | |||
719 | return __pmd(pte_val(pte)); | 739 | return __pmd(pte_val(pte)); |
720 | } | 740 | } |
721 | 741 | ||
722 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
723 | { | ||
724 | unsigned long mask; | ||
725 | |||
726 | if (tlb_type == hypervisor) | ||
727 | mask = _PAGE_PRESENT_4V; | ||
728 | else | ||
729 | mask = _PAGE_PRESENT_4U; | ||
730 | |||
731 | pmd_val(pmd) &= ~mask; | ||
732 | |||
733 | return pmd; | ||
734 | } | ||
735 | |||
736 | static inline pmd_t pmd_mksplitting(pmd_t pmd) | 742 | static inline pmd_t pmd_mksplitting(pmd_t pmd) |
737 | { | 743 | { |
738 | pte_t pte = __pte(pmd_val(pmd)); | 744 | pte_t pte = __pte(pmd_val(pmd)); |
@@ -757,6 +763,20 @@ static inline int pmd_present(pmd_t pmd) | |||
757 | 763 | ||
758 | #define pmd_none(pmd) (!pmd_val(pmd)) | 764 | #define pmd_none(pmd) (!pmd_val(pmd)) |
759 | 765 | ||
766 | /* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is | ||
767 | * very simple, it's just the physical address. PTE tables are of | ||
768 | * size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and | ||
769 | * the top bits outside of the range of any physical address size we | ||
770 | * support are clear as well. We also validate the physical itself. | ||
771 | */ | ||
772 | #define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \ | ||
773 | !__kern_addr_valid(pmd_val(pmd))) | ||
774 | |||
775 | #define pud_none(pud) (!pud_val(pud)) | ||
776 | |||
777 | #define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ | ||
778 | !__kern_addr_valid(pud_val(pud))) | ||
779 | |||
760 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 780 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
761 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 781 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
762 | pmd_t *pmdp, pmd_t pmd); | 782 | pmd_t *pmdp, pmd_t pmd); |
@@ -790,10 +810,7 @@ static inline unsigned long __pmd_page(pmd_t pmd) | |||
790 | #define pud_page_vaddr(pud) \ | 810 | #define pud_page_vaddr(pud) \ |
791 | ((unsigned long) __va(pud_val(pud))) | 811 | ((unsigned long) __va(pud_val(pud))) |
792 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) | 812 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) |
793 | #define pmd_bad(pmd) (0) | ||
794 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) | 813 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) |
795 | #define pud_none(pud) (!pud_val(pud)) | ||
796 | #define pud_bad(pud) (0) | ||
797 | #define pud_present(pud) (pud_val(pud) != 0U) | 814 | #define pud_present(pud) (pud_val(pud) != 0U) |
798 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) | 815 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) |
799 | 816 | ||
@@ -893,6 +910,10 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); | |||
893 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, | 910 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, |
894 | pmd_t *pmd); | 911 | pmd_t *pmd); |
895 | 912 | ||
913 | #define __HAVE_ARCH_PMDP_INVALIDATE | ||
914 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
915 | pmd_t *pmdp); | ||
916 | |||
896 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 917 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
897 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 918 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
898 | pgtable_t pgtable); | 919 | pgtable_t pgtable); |
@@ -919,18 +940,6 @@ extern unsigned long pte_file(pte_t); | |||
919 | extern pte_t pgoff_to_pte(unsigned long); | 940 | extern pte_t pgoff_to_pte(unsigned long); |
920 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) | 941 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) |
921 | 942 | ||
922 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
923 | |||
924 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
925 | static inline bool kern_addr_valid(unsigned long addr) | ||
926 | { | ||
927 | unsigned long paddr = __pa(addr); | ||
928 | |||
929 | if ((paddr >> 41UL) != 0UL) | ||
930 | return false; | ||
931 | return test_bit(paddr >> 22, sparc64_valid_addr_bitmap); | ||
932 | } | ||
933 | |||
934 | extern int page_in_phys_avail(unsigned long paddr); | 943 | extern int page_in_phys_avail(unsigned long paddr); |
935 | 944 | ||
936 | /* | 945 | /* |
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 2230f80d9fe3..90916f955cac 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -171,7 +171,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
171 | andcc REG1, REG2, %g0; \ | 171 | andcc REG1, REG2, %g0; \ |
172 | be,pt %xcc, 700f; \ | 172 | be,pt %xcc, 700f; \ |
173 | sethi %hi(4 * 1024 * 1024), REG2; \ | 173 | sethi %hi(4 * 1024 * 1024), REG2; \ |
174 | andn REG1, REG2, REG1; \ | 174 | brgez,pn REG1, FAIL_LABEL; \ |
175 | andn REG1, REG2, REG1; \ | ||
175 | and VADDR, REG2, REG2; \ | 176 | and VADDR, REG2, REG2; \ |
176 | brlz,pt REG1, PTE_LABEL; \ | 177 | brlz,pt REG1, PTE_LABEL; \ |
177 | or REG1, REG2, REG1; \ | 178 | or REG1, REG2, REG1; \ |
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 26b706a1867d..452f04fe8da6 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S | |||
@@ -282,8 +282,8 @@ sun4v_chip_type: | |||
282 | stx %l2, [%l4 + 0x0] | 282 | stx %l2, [%l4 + 0x0] |
283 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low | 283 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low |
284 | /* 4MB align */ | 284 | /* 4MB align */ |
285 | srlx %l3, 22, %l3 | 285 | srlx %l3, ILOG2_4MB, %l3 |
286 | sllx %l3, 22, %l3 | 286 | sllx %l3, ILOG2_4MB, %l3 |
287 | stx %l3, [%l4 + 0x8] | 287 | stx %l3, [%l4 + 0x8] |
288 | 288 | ||
289 | /* Leave service as-is, "call-method" */ | 289 | /* Leave service as-is, "call-method" */ |
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 542e96ac4d39..605d49204580 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
@@ -277,7 +277,7 @@ kvmap_dtlb_load: | |||
277 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 277 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
278 | kvmap_vmemmap: | 278 | kvmap_vmemmap: |
279 | sub %g4, %g5, %g5 | 279 | sub %g4, %g5, %g5 |
280 | srlx %g5, 22, %g5 | 280 | srlx %g5, ILOG2_4MB, %g5 |
281 | sethi %hi(vmemmap_table), %g1 | 281 | sethi %hi(vmemmap_table), %g1 |
282 | sllx %g5, 3, %g5 | 282 | sllx %g5, 3, %g5 |
283 | or %g1, %lo(vmemmap_table), %g1 | 283 | or %g1, %lo(vmemmap_table), %g1 |
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 6479256fd5a4..337094556916 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
@@ -68,27 +68,16 @@ EXPORT_SYMBOL(touch_nmi_watchdog); | |||
68 | 68 | ||
69 | static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) | 69 | static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) |
70 | { | 70 | { |
71 | int this_cpu = smp_processor_id(); | ||
72 | |||
71 | if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, | 73 | if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, |
72 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) | 74 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) |
73 | return; | 75 | return; |
74 | 76 | ||
75 | console_verbose(); | ||
76 | bust_spinlocks(1); | ||
77 | |||
78 | printk(KERN_EMERG "%s", str); | ||
79 | printk(" on CPU%d, ip %08lx, registers:\n", | ||
80 | smp_processor_id(), regs->tpc); | ||
81 | show_regs(regs); | ||
82 | dump_stack(); | ||
83 | |||
84 | bust_spinlocks(0); | ||
85 | |||
86 | if (do_panic || panic_on_oops) | 77 | if (do_panic || panic_on_oops) |
87 | panic("Non maskable interrupt"); | 78 | panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu); |
88 | 79 | else | |
89 | nmi_exit(); | 80 | WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu); |
90 | local_irq_enable(); | ||
91 | do_exit(SIGBUS); | ||
92 | } | 81 | } |
93 | 82 | ||
94 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | 83 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 9781048161ab..745a3633ce14 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -149,7 +149,7 @@ void cpu_panic(void) | |||
149 | #define NUM_ROUNDS 64 /* magic value */ | 149 | #define NUM_ROUNDS 64 /* magic value */ |
150 | #define NUM_ITERS 5 /* likewise */ | 150 | #define NUM_ITERS 5 /* likewise */ |
151 | 151 | ||
152 | static DEFINE_SPINLOCK(itc_sync_lock); | 152 | static DEFINE_RAW_SPINLOCK(itc_sync_lock); |
153 | static unsigned long go[SLAVE + 1]; | 153 | static unsigned long go[SLAVE + 1]; |
154 | 154 | ||
155 | #define DEBUG_TICK_SYNC 0 | 155 | #define DEBUG_TICK_SYNC 0 |
@@ -257,7 +257,7 @@ static void smp_synchronize_one_tick(int cpu) | |||
257 | go[MASTER] = 0; | 257 | go[MASTER] = 0; |
258 | membar_safe("#StoreLoad"); | 258 | membar_safe("#StoreLoad"); |
259 | 259 | ||
260 | spin_lock_irqsave(&itc_sync_lock, flags); | 260 | raw_spin_lock_irqsave(&itc_sync_lock, flags); |
261 | { | 261 | { |
262 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { | 262 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { |
263 | while (!go[MASTER]) | 263 | while (!go[MASTER]) |
@@ -268,7 +268,7 @@ static void smp_synchronize_one_tick(int cpu) | |||
268 | membar_safe("#StoreLoad"); | 268 | membar_safe("#StoreLoad"); |
269 | } | 269 | } |
270 | } | 270 | } |
271 | spin_unlock_irqrestore(&itc_sync_lock, flags); | 271 | raw_spin_unlock_irqrestore(&itc_sync_lock, flags); |
272 | } | 272 | } |
273 | 273 | ||
274 | #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) | 274 | #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index f7c72b6efc27..d066eb18650c 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -44,7 +44,7 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) | |||
44 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) | 44 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) |
45 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) | 45 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) |
46 | SIGN1(sys32_select, compat_sys_select, %o0) | 46 | SIGN1(sys32_select, compat_sys_select, %o0) |
47 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) | 47 | SIGN1(sys32_futex, compat_sys_futex, %o1) |
48 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) | 48 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) |
49 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) | 49 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) |
50 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) | 50 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 3c1a7cb31579..35ab8b60d256 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -166,17 +166,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) | |||
166 | unsigned long compute_effective_address(struct pt_regs *regs, | 166 | unsigned long compute_effective_address(struct pt_regs *regs, |
167 | unsigned int insn, unsigned int rd) | 167 | unsigned int insn, unsigned int rd) |
168 | { | 168 | { |
169 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | ||
169 | unsigned int rs1 = (insn >> 14) & 0x1f; | 170 | unsigned int rs1 = (insn >> 14) & 0x1f; |
170 | unsigned int rs2 = insn & 0x1f; | 171 | unsigned int rs2 = insn & 0x1f; |
171 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 172 | unsigned long addr; |
172 | 173 | ||
173 | if (insn & 0x2000) { | 174 | if (insn & 0x2000) { |
174 | maybe_flush_windows(rs1, 0, rd, from_kernel); | 175 | maybe_flush_windows(rs1, 0, rd, from_kernel); |
175 | return (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); | 176 | addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); |
176 | } else { | 177 | } else { |
177 | maybe_flush_windows(rs1, rs2, rd, from_kernel); | 178 | maybe_flush_windows(rs1, rs2, rd, from_kernel); |
178 | return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); | 179 | addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); |
179 | } | 180 | } |
181 | |||
182 | if (!from_kernel && test_thread_flag(TIF_32BIT)) | ||
183 | addr &= 0xffffffff; | ||
184 | |||
185 | return addr; | ||
180 | } | 186 | } |
181 | 187 | ||
182 | /* This is just to make gcc think die_if_kernel does return... */ | 188 | /* This is just to make gcc think die_if_kernel does return... */ |
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 69bb818fdd79..a8ff0d1a3b69 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
@@ -96,38 +96,51 @@ static unsigned int get_user_insn(unsigned long tpc) | |||
96 | pte_t *ptep, pte; | 96 | pte_t *ptep, pte; |
97 | unsigned long pa; | 97 | unsigned long pa; |
98 | u32 insn = 0; | 98 | u32 insn = 0; |
99 | unsigned long pstate; | ||
100 | 99 | ||
101 | if (pgd_none(*pgdp)) | 100 | if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp))) |
102 | goto outret; | 101 | goto out; |
103 | pudp = pud_offset(pgdp, tpc); | 102 | pudp = pud_offset(pgdp, tpc); |
104 | if (pud_none(*pudp)) | 103 | if (pud_none(*pudp) || unlikely(pud_bad(*pudp))) |
105 | goto outret; | 104 | goto out; |
106 | pmdp = pmd_offset(pudp, tpc); | ||
107 | if (pmd_none(*pmdp)) | ||
108 | goto outret; | ||
109 | 105 | ||
110 | /* This disables preemption for us as well. */ | 106 | /* This disables preemption for us as well. */ |
111 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | 107 | local_irq_disable(); |
112 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | ||
113 | : : "r" (pstate), "i" (PSTATE_IE)); | ||
114 | ptep = pte_offset_map(pmdp, tpc); | ||
115 | pte = *ptep; | ||
116 | if (!pte_present(pte)) | ||
117 | goto out; | ||
118 | 108 | ||
119 | pa = (pte_pfn(pte) << PAGE_SHIFT); | 109 | pmdp = pmd_offset(pudp, tpc); |
120 | pa += (tpc & ~PAGE_MASK); | 110 | if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp))) |
111 | goto out_irq_enable; | ||
112 | |||
113 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
114 | if (pmd_trans_huge(*pmdp)) { | ||
115 | if (pmd_trans_splitting(*pmdp)) | ||
116 | goto out_irq_enable; | ||
121 | 117 | ||
122 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | 118 | pa = pmd_pfn(*pmdp) << PAGE_SHIFT; |
123 | __asm__ __volatile__("lduwa [%1] %2, %0" | 119 | pa += tpc & ~HPAGE_MASK; |
124 | : "=r" (insn) | ||
125 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
126 | 120 | ||
121 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | ||
122 | __asm__ __volatile__("lduwa [%1] %2, %0" | ||
123 | : "=r" (insn) | ||
124 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
125 | } else | ||
126 | #endif | ||
127 | { | ||
128 | ptep = pte_offset_map(pmdp, tpc); | ||
129 | pte = *ptep; | ||
130 | if (pte_present(pte)) { | ||
131 | pa = (pte_pfn(pte) << PAGE_SHIFT); | ||
132 | pa += (tpc & ~PAGE_MASK); | ||
133 | |||
134 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | ||
135 | __asm__ __volatile__("lduwa [%1] %2, %0" | ||
136 | : "=r" (insn) | ||
137 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
138 | } | ||
139 | pte_unmap(ptep); | ||
140 | } | ||
141 | out_irq_enable: | ||
142 | local_irq_enable(); | ||
127 | out: | 143 | out: |
128 | pte_unmap(ptep); | ||
129 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | ||
130 | outret: | ||
131 | return insn; | 144 | return insn; |
132 | } | 145 | } |
133 | 146 | ||
@@ -153,7 +166,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, | |||
153 | } | 166 | } |
154 | 167 | ||
155 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | 168 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, |
156 | unsigned int insn, int fault_code) | 169 | unsigned long fault_addr, unsigned int insn, |
170 | int fault_code) | ||
157 | { | 171 | { |
158 | unsigned long addr; | 172 | unsigned long addr; |
159 | siginfo_t info; | 173 | siginfo_t info; |
@@ -161,10 +175,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |||
161 | info.si_code = code; | 175 | info.si_code = code; |
162 | info.si_signo = sig; | 176 | info.si_signo = sig; |
163 | info.si_errno = 0; | 177 | info.si_errno = 0; |
164 | if (fault_code & FAULT_CODE_ITLB) | 178 | if (fault_code & FAULT_CODE_ITLB) { |
165 | addr = regs->tpc; | 179 | addr = regs->tpc; |
166 | else | 180 | } else { |
167 | addr = compute_effective_address(regs, insn, 0); | 181 | /* If we were able to probe the faulting instruction, use it |
182 | * to compute a precise fault address. Otherwise use the fault | ||
183 | * time provided address which may only have page granularity. | ||
184 | */ | ||
185 | if (insn) | ||
186 | addr = compute_effective_address(regs, insn, 0); | ||
187 | else | ||
188 | addr = fault_addr; | ||
189 | } | ||
168 | info.si_addr = (void __user *) addr; | 190 | info.si_addr = (void __user *) addr; |
169 | info.si_trapno = 0; | 191 | info.si_trapno = 0; |
170 | 192 | ||
@@ -239,7 +261,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code, | |||
239 | /* The si_code was set to make clear whether | 261 | /* The si_code was set to make clear whether |
240 | * this was a SEGV_MAPERR or SEGV_ACCERR fault. | 262 | * this was a SEGV_MAPERR or SEGV_ACCERR fault. |
241 | */ | 263 | */ |
242 | do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code); | 264 | do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code); |
243 | return; | 265 | return; |
244 | } | 266 | } |
245 | 267 | ||
@@ -525,7 +547,7 @@ do_sigbus: | |||
525 | * Send a sigbus, regardless of whether we were in kernel | 547 | * Send a sigbus, regardless of whether we were in kernel |
526 | * or user mode. | 548 | * or user mode. |
527 | */ | 549 | */ |
528 | do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code); | 550 | do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code); |
529 | 551 | ||
530 | /* Kernel mode? Handle exceptions or die */ | 552 | /* Kernel mode? Handle exceptions or die */ |
531 | if (regs->tstate & TSTATE_PRIV) | 553 | if (regs->tstate & TSTATE_PRIV) |
diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index c4d3da68b800..1aed0432c64b 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c | |||
@@ -73,7 +73,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, | |||
73 | struct page *head, *page, *tail; | 73 | struct page *head, *page, *tail; |
74 | int refs; | 74 | int refs; |
75 | 75 | ||
76 | if (!pmd_large(pmd)) | 76 | if (!(pmd_val(pmd) & _PAGE_VALID)) |
77 | return 0; | 77 | return 0; |
78 | 78 | ||
79 | if (write && !pmd_write(pmd)) | 79 | if (write && !pmd_write(pmd)) |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index eafbc65c9c47..ed3c969a5f4c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -588,7 +588,7 @@ static void __init remap_kernel(void) | |||
588 | int i, tlb_ent = sparc64_highest_locked_tlbent(); | 588 | int i, tlb_ent = sparc64_highest_locked_tlbent(); |
589 | 589 | ||
590 | tte_vaddr = (unsigned long) KERNBASE; | 590 | tte_vaddr = (unsigned long) KERNBASE; |
591 | phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 591 | phys_page = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB; |
592 | tte_data = kern_large_tte(phys_page); | 592 | tte_data = kern_large_tte(phys_page); |
593 | 593 | ||
594 | kern_locked_tte_data = tte_data; | 594 | kern_locked_tte_data = tte_data; |
@@ -1881,7 +1881,7 @@ void __init paging_init(void) | |||
1881 | 1881 | ||
1882 | BUILD_BUG_ON(NR_CPUS > 4096); | 1882 | BUILD_BUG_ON(NR_CPUS > 4096); |
1883 | 1883 | ||
1884 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 1884 | kern_base = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB; |
1885 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 1885 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
1886 | 1886 | ||
1887 | /* Invalidate both kernel TSBs. */ | 1887 | /* Invalidate both kernel TSBs. */ |
@@ -1937,7 +1937,7 @@ void __init paging_init(void) | |||
1937 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); | 1937 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); |
1938 | 1938 | ||
1939 | real_end = (unsigned long)_end; | 1939 | real_end = (unsigned long)_end; |
1940 | num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << 22); | 1940 | num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << ILOG2_4MB); |
1941 | printk("Kernel: Using %d locked TLB entries for main kernel image.\n", | 1941 | printk("Kernel: Using %d locked TLB entries for main kernel image.\n", |
1942 | num_kernel_image_mappings); | 1942 | num_kernel_image_mappings); |
1943 | 1943 | ||
@@ -2094,7 +2094,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap) | |||
2094 | 2094 | ||
2095 | if (new_start <= old_start && | 2095 | if (new_start <= old_start && |
2096 | new_end >= (old_start + PAGE_SIZE)) { | 2096 | new_end >= (old_start + PAGE_SIZE)) { |
2097 | set_bit(old_start >> 22, bitmap); | 2097 | set_bit(old_start >> ILOG2_4MB, bitmap); |
2098 | goto do_next_page; | 2098 | goto do_next_page; |
2099 | } | 2099 | } |
2100 | } | 2100 | } |
@@ -2143,7 +2143,7 @@ void __init mem_init(void) | |||
2143 | addr = PAGE_OFFSET + kern_base; | 2143 | addr = PAGE_OFFSET + kern_base; |
2144 | last = PAGE_ALIGN(kern_size) + addr; | 2144 | last = PAGE_ALIGN(kern_size) + addr; |
2145 | while (addr < last) { | 2145 | while (addr < last) { |
2146 | set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap); | 2146 | set_bit(__pa(addr) >> ILOG2_4MB, sparc64_valid_addr_bitmap); |
2147 | addr += PAGE_SIZE; | 2147 | addr += PAGE_SIZE; |
2148 | } | 2148 | } |
2149 | 2149 | ||
@@ -2267,7 +2267,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, | |||
2267 | void *block; | 2267 | void *block; |
2268 | 2268 | ||
2269 | if (!(*vmem_pp & _PAGE_VALID)) { | 2269 | if (!(*vmem_pp & _PAGE_VALID)) { |
2270 | block = vmemmap_alloc_block(1UL << 22, node); | 2270 | block = vmemmap_alloc_block(1UL << ILOG2_4MB, node); |
2271 | if (!block) | 2271 | if (!block) |
2272 | return -ENOMEM; | 2272 | return -ENOMEM; |
2273 | 2273 | ||
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index b12cb5e72812..b89aba217e3b 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
@@ -134,7 +134,7 @@ no_cache_flush: | |||
134 | 134 | ||
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
136 | static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, | 136 | static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, |
137 | pmd_t pmd, bool exec) | 137 | pmd_t pmd) |
138 | { | 138 | { |
139 | unsigned long end; | 139 | unsigned long end; |
140 | pte_t *pte; | 140 | pte_t *pte; |
@@ -142,8 +142,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, | |||
142 | pte = pte_offset_map(&pmd, vaddr); | 142 | pte = pte_offset_map(&pmd, vaddr); |
143 | end = vaddr + HPAGE_SIZE; | 143 | end = vaddr + HPAGE_SIZE; |
144 | while (vaddr < end) { | 144 | while (vaddr < end) { |
145 | if (pte_val(*pte) & _PAGE_VALID) | 145 | if (pte_val(*pte) & _PAGE_VALID) { |
146 | bool exec = pte_exec(*pte); | ||
147 | |||
146 | tlb_batch_add_one(mm, vaddr, exec); | 148 | tlb_batch_add_one(mm, vaddr, exec); |
149 | } | ||
147 | pte++; | 150 | pte++; |
148 | vaddr += PAGE_SIZE; | 151 | vaddr += PAGE_SIZE; |
149 | } | 152 | } |
@@ -177,19 +180,30 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
177 | } | 180 | } |
178 | 181 | ||
179 | if (!pmd_none(orig)) { | 182 | if (!pmd_none(orig)) { |
180 | pte_t orig_pte = __pte(pmd_val(orig)); | ||
181 | bool exec = pte_exec(orig_pte); | ||
182 | |||
183 | addr &= HPAGE_MASK; | 183 | addr &= HPAGE_MASK; |
184 | if (pmd_trans_huge(orig)) { | 184 | if (pmd_trans_huge(orig)) { |
185 | pte_t orig_pte = __pte(pmd_val(orig)); | ||
186 | bool exec = pte_exec(orig_pte); | ||
187 | |||
185 | tlb_batch_add_one(mm, addr, exec); | 188 | tlb_batch_add_one(mm, addr, exec); |
186 | tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); | 189 | tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); |
187 | } else { | 190 | } else { |
188 | tlb_batch_pmd_scan(mm, addr, orig, exec); | 191 | tlb_batch_pmd_scan(mm, addr, orig); |
189 | } | 192 | } |
190 | } | 193 | } |
191 | } | 194 | } |
192 | 195 | ||
196 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
197 | pmd_t *pmdp) | ||
198 | { | ||
199 | pmd_t entry = *pmdp; | ||
200 | |||
201 | pmd_val(entry) &= ~_PAGE_VALID; | ||
202 | |||
203 | set_pmd_at(vma->vm_mm, address, pmdp, entry); | ||
204 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
205 | } | ||
206 | |||
193 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 207 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
194 | pgtable_t pgtable) | 208 | pgtable_t pgtable) |
195 | { | 209 | { |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index d1b7c377a234..33f71b01fd22 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -79,11 +79,14 @@ else | |||
79 | UTS_MACHINE := x86_64 | 79 | UTS_MACHINE := x86_64 |
80 | CHECKFLAGS += -D__x86_64__ -m64 | 80 | CHECKFLAGS += -D__x86_64__ -m64 |
81 | 81 | ||
82 | biarch := -m64 | ||
82 | KBUILD_AFLAGS += -m64 | 83 | KBUILD_AFLAGS += -m64 |
83 | KBUILD_CFLAGS += -m64 | 84 | KBUILD_CFLAGS += -m64 |
84 | 85 | ||
85 | # Don't autogenerate traditional x87, MMX or SSE instructions | 86 | # Don't autogenerate traditional x87, MMX or SSE instructions |
86 | KBUILD_CFLAGS += -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 | 87 | KBUILD_CFLAGS += -mno-mmx -mno-sse |
88 | KBUILD_CFLAGS += $(call cc-option,-mno-80387) | ||
89 | KBUILD_CFLAGS += $(call cc-option,-mno-fp-ret-in-387) | ||
87 | 90 | ||
88 | # Use -mpreferred-stack-boundary=3 if supported. | 91 | # Use -mpreferred-stack-boundary=3 if supported. |
89 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) | 92 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) |
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index abb9eba61b50..dbe8dd2fe247 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile | |||
@@ -71,7 +71,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE | |||
71 | 71 | ||
72 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) | 72 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) |
73 | 73 | ||
74 | sed-voffset := -e 's/^\([0-9a-fA-F]*\) . \(_text\|_end\)$$/\#define VO_\2 0x\1/p' | 74 | sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|_end\)$$/\#define VO_\2 0x\1/p' |
75 | 75 | ||
76 | quiet_cmd_voffset = VOFFSET $@ | 76 | quiet_cmd_voffset = VOFFSET $@ |
77 | cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ | 77 | cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ |
@@ -80,7 +80,7 @@ targets += voffset.h | |||
80 | $(obj)/voffset.h: vmlinux FORCE | 80 | $(obj)/voffset.h: vmlinux FORCE |
81 | $(call if_changed,voffset) | 81 | $(call if_changed,voffset) |
82 | 82 | ||
83 | sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' | 83 | sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' |
84 | 84 | ||
85 | quiet_cmd_zoffset = ZOFFSET $@ | 85 | quiet_cmd_zoffset = ZOFFSET $@ |
86 | cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ | 86 | cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 17684615374b..57ab74df7eea 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -354,7 +354,7 @@ static void parse_elf(void *output) | |||
354 | free(phdrs); | 354 | free(phdrs); |
355 | } | 355 | } |
356 | 356 | ||
357 | asmlinkage void *decompress_kernel(void *rmode, memptr heap, | 357 | asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, |
358 | unsigned char *input_data, | 358 | unsigned char *input_data, |
359 | unsigned long input_len, | 359 | unsigned long input_len, |
360 | unsigned char *output, | 360 | unsigned char *output, |
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index b18df579c0e9..36f7125945e3 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h | |||
@@ -63,6 +63,7 @@ | |||
63 | /* hpet memory map physical address */ | 63 | /* hpet memory map physical address */ |
64 | extern unsigned long hpet_address; | 64 | extern unsigned long hpet_address; |
65 | extern unsigned long force_hpet_address; | 65 | extern unsigned long force_hpet_address; |
66 | extern int boot_hpet_disable; | ||
66 | extern u8 hpet_blockid; | 67 | extern u8 hpet_blockid; |
67 | extern int hpet_force_user; | 68 | extern int hpet_force_user; |
68 | extern u8 hpet_msi_disable; | 69 | extern u8 hpet_msi_disable; |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index c827ace3121b..fcf2b3ae1bf0 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -384,7 +384,7 @@ | |||
384 | #define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18 | 384 | #define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18 |
385 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT) | 385 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT) |
386 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22 | 386 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22 |
387 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT); | 387 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) |
388 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23 | 388 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23 |
389 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT) | 389 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT) |
390 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34 | 390 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34 |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 3a2ae4c88948..31368207837c 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -31,7 +31,7 @@ static char temp_stack[4096]; | |||
31 | * | 31 | * |
32 | * Wrapper around acpi_enter_sleep_state() to be called by assmebly. | 32 | * Wrapper around acpi_enter_sleep_state() to be called by assmebly. |
33 | */ | 33 | */ |
34 | acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state) | 34 | acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state) |
35 | { | 35 | { |
36 | return acpi_enter_sleep_state(state); | 36 | return acpi_enter_sleep_state(state); |
37 | } | 37 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 6ad4658de705..992060e09897 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -2189,7 +2189,7 @@ void send_cleanup_vector(struct irq_cfg *cfg) | |||
2189 | cfg->move_in_progress = 0; | 2189 | cfg->move_in_progress = 0; |
2190 | } | 2190 | } |
2191 | 2191 | ||
2192 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2192 | asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) |
2193 | { | 2193 | { |
2194 | unsigned vector, me; | 2194 | unsigned vector, me; |
2195 | 2195 | ||
@@ -3425,6 +3425,11 @@ int get_nr_irqs_gsi(void) | |||
3425 | return nr_irqs_gsi; | 3425 | return nr_irqs_gsi; |
3426 | } | 3426 | } |
3427 | 3427 | ||
3428 | unsigned int arch_dynirq_lower_bound(unsigned int from) | ||
3429 | { | ||
3430 | return from < nr_irqs_gsi ? nr_irqs_gsi : from; | ||
3431 | } | ||
3432 | |||
3428 | int __init arch_probe_nr_irqs(void) | 3433 | int __init arch_probe_nr_irqs(void) |
3429 | { | 3434 | { |
3430 | int nr; | 3435 | int nr; |
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index d921b7ee6595..36a1bb6d1ee0 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -429,14 +429,14 @@ static inline void __smp_thermal_interrupt(void) | |||
429 | smp_thermal_vector(); | 429 | smp_thermal_vector(); |
430 | } | 430 | } |
431 | 431 | ||
432 | asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) | 432 | asmlinkage __visible void smp_thermal_interrupt(struct pt_regs *regs) |
433 | { | 433 | { |
434 | entering_irq(); | 434 | entering_irq(); |
435 | __smp_thermal_interrupt(); | 435 | __smp_thermal_interrupt(); |
436 | exiting_ack_irq(); | 436 | exiting_ack_irq(); |
437 | } | 437 | } |
438 | 438 | ||
439 | asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs) | 439 | asmlinkage __visible void smp_trace_thermal_interrupt(struct pt_regs *regs) |
440 | { | 440 | { |
441 | entering_irq(); | 441 | entering_irq(); |
442 | trace_thermal_apic_entry(THERMAL_APIC_VECTOR); | 442 | trace_thermal_apic_entry(THERMAL_APIC_VECTOR); |
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index fe6b1c86645b..7245980186ee 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c | |||
@@ -24,14 +24,14 @@ static inline void __smp_threshold_interrupt(void) | |||
24 | mce_threshold_vector(); | 24 | mce_threshold_vector(); |
25 | } | 25 | } |
26 | 26 | ||
27 | asmlinkage void smp_threshold_interrupt(void) | 27 | asmlinkage __visible void smp_threshold_interrupt(void) |
28 | { | 28 | { |
29 | entering_irq(); | 29 | entering_irq(); |
30 | __smp_threshold_interrupt(); | 30 | __smp_threshold_interrupt(); |
31 | exiting_ack_irq(); | 31 | exiting_ack_irq(); |
32 | } | 32 | } |
33 | 33 | ||
34 | asmlinkage void smp_trace_threshold_interrupt(void) | 34 | asmlinkage __visible void smp_trace_threshold_interrupt(void) |
35 | { | 35 | { |
36 | entering_irq(); | 36 | entering_irq(); |
37 | trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); | 37 | trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 7c87424d4140..619f7699487a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
@@ -543,7 +543,8 @@ static int rapl_cpu_prepare(int cpu) | |||
543 | if (phys_id < 0) | 543 | if (phys_id < 0) |
544 | return -1; | 544 | return -1; |
545 | 545 | ||
546 | if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) | 546 | /* protect rdmsrl() to handle virtualization */ |
547 | if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) | ||
547 | return -1; | 548 | return -1; |
548 | 549 | ||
549 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); | 550 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); |
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 6e2537c32190..6cda0baeac9d 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/dma.h> | 17 | #include <asm/dma.h> |
18 | #include <asm/io_apic.h> | 18 | #include <asm/io_apic.h> |
19 | #include <asm/apic.h> | 19 | #include <asm/apic.h> |
20 | #include <asm/hpet.h> | ||
20 | #include <asm/iommu.h> | 21 | #include <asm/iommu.h> |
21 | #include <asm/gart.h> | 22 | #include <asm/gart.h> |
22 | #include <asm/irq_remapping.h> | 23 | #include <asm/irq_remapping.h> |
@@ -530,6 +531,15 @@ static void __init intel_graphics_stolen(int num, int slot, int func) | |||
530 | } | 531 | } |
531 | } | 532 | } |
532 | 533 | ||
534 | static void __init force_disable_hpet(int num, int slot, int func) | ||
535 | { | ||
536 | #ifdef CONFIG_HPET_TIMER | ||
537 | boot_hpet_disable = 1; | ||
538 | pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n"); | ||
539 | #endif | ||
540 | } | ||
541 | |||
542 | |||
533 | #define QFLAG_APPLY_ONCE 0x1 | 543 | #define QFLAG_APPLY_ONCE 0x1 |
534 | #define QFLAG_APPLIED 0x2 | 544 | #define QFLAG_APPLIED 0x2 |
535 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) | 545 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) |
@@ -567,6 +577,12 @@ static struct chipset early_qrk[] __initdata = { | |||
567 | PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, | 577 | PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, |
568 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, | 578 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, |
569 | QFLAG_APPLY_ONCE, intel_graphics_stolen }, | 579 | QFLAG_APPLY_ONCE, intel_graphics_stolen }, |
580 | /* | ||
581 | * HPET on current version of Baytrail platform has accuracy | ||
582 | * problems, disable it for now: | ||
583 | */ | ||
584 | { PCI_VENDOR_ID_INTEL, 0x0f00, | ||
585 | PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, | ||
570 | {} | 586 | {} |
571 | }; | 587 | }; |
572 | 588 | ||
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index c61a14a4a310..d6c1b9836995 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void) | |||
29 | reserve_ebda_region(); | 29 | reserve_ebda_region(); |
30 | } | 30 | } |
31 | 31 | ||
32 | asmlinkage void __init i386_start_kernel(void) | 32 | asmlinkage __visible void __init i386_start_kernel(void) |
33 | { | 33 | { |
34 | sanitize_boot_params(&boot_params); | 34 | sanitize_boot_params(&boot_params); |
35 | 35 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 85126ccbdf6b..068054f4bf20 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -137,7 +137,7 @@ static void __init copy_bootdata(char *real_mode_data) | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | asmlinkage void __init x86_64_start_kernel(char * real_mode_data) | 140 | asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) |
141 | { | 141 | { |
142 | int i; | 142 | int i; |
143 | 143 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 8d80ae011603..4177bfbc80b0 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -88,7 +88,7 @@ static inline void hpet_clear_mapping(void) | |||
88 | /* | 88 | /* |
89 | * HPET command line enable / disable | 89 | * HPET command line enable / disable |
90 | */ | 90 | */ |
91 | static int boot_hpet_disable; | 91 | int boot_hpet_disable; |
92 | int hpet_force_user; | 92 | int hpet_force_user; |
93 | static int hpet_verbose; | 93 | static int hpet_verbose; |
94 | 94 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9c0280f93d05..898d077617a9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | asmlinkage extern void ret_from_fork(void); | 53 | asmlinkage extern void ret_from_fork(void); |
54 | 54 | ||
55 | asmlinkage DEFINE_PER_CPU(unsigned long, old_rsp); | 55 | __visible DEFINE_PER_CPU(unsigned long, old_rsp); |
56 | 56 | ||
57 | /* Prints also some state that isn't saved in the pt_regs */ | 57 | /* Prints also some state that isn't saved in the pt_regs */ |
58 | void __show_regs(struct pt_regs *regs, int all) | 58 | void __show_regs(struct pt_regs *regs, int all) |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 3399d3a99730..52b1157c53eb 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -191,6 +191,16 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
191 | }, | 191 | }, |
192 | }, | 192 | }, |
193 | 193 | ||
194 | /* Certec */ | ||
195 | { /* Handle problems with rebooting on Certec BPC600 */ | ||
196 | .callback = set_pci_reboot, | ||
197 | .ident = "Certec BPC600", | ||
198 | .matches = { | ||
199 | DMI_MATCH(DMI_SYS_VENDOR, "Certec"), | ||
200 | DMI_MATCH(DMI_PRODUCT_NAME, "BPC600"), | ||
201 | }, | ||
202 | }, | ||
203 | |||
194 | /* Dell */ | 204 | /* Dell */ |
195 | { /* Handle problems with rebooting on Dell DXP061 */ | 205 | { /* Handle problems with rebooting on Dell DXP061 */ |
196 | .callback = set_bios_reboot, | 206 | .callback = set_bios_reboot, |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 7c3a5a61f2e4..be8e1bde07aa 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -168,7 +168,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) | |||
168 | * this function calls the 'stop' function on all other CPUs in the system. | 168 | * this function calls the 'stop' function on all other CPUs in the system. |
169 | */ | 169 | */ |
170 | 170 | ||
171 | asmlinkage void smp_reboot_interrupt(void) | 171 | asmlinkage __visible void smp_reboot_interrupt(void) |
172 | { | 172 | { |
173 | ack_APIC_irq(); | 173 | ack_APIC_irq(); |
174 | irq_enter(); | 174 | irq_enter(); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 57409f6b8c62..f73b5d435bdc 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -357,7 +357,7 @@ exit: | |||
357 | * for scheduling or signal handling. The actual stack switch is done in | 357 | * for scheduling or signal handling. The actual stack switch is done in |
358 | * entry.S | 358 | * entry.S |
359 | */ | 359 | */ |
360 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | 360 | asmlinkage __visible __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) |
361 | { | 361 | { |
362 | struct pt_regs *regs = eregs; | 362 | struct pt_regs *regs = eregs; |
363 | /* Did already sync */ | 363 | /* Did already sync */ |
@@ -601,11 +601,11 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | |||
601 | #endif | 601 | #endif |
602 | } | 602 | } |
603 | 603 | ||
604 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) | 604 | asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void) |
605 | { | 605 | { |
606 | } | 606 | } |
607 | 607 | ||
608 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) | 608 | asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void) |
609 | { | 609 | { |
610 | } | 610 | } |
611 | 611 | ||
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index f6584a90aba3..b99b9ad8540c 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -26,6 +26,9 @@ | |||
26 | 26 | ||
27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 | 27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 |
28 | 28 | ||
29 | /* Flag below is initialized once during vSMP PCI initialization. */ | ||
30 | static int irq_routing_comply = 1; | ||
31 | |||
29 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT | 32 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT |
30 | /* | 33 | /* |
31 | * Interrupt control on vSMPowered systems: | 34 | * Interrupt control on vSMPowered systems: |
@@ -33,7 +36,7 @@ | |||
33 | * and vice versa. | 36 | * and vice versa. |
34 | */ | 37 | */ |
35 | 38 | ||
36 | asmlinkage unsigned long vsmp_save_fl(void) | 39 | asmlinkage __visible unsigned long vsmp_save_fl(void) |
37 | { | 40 | { |
38 | unsigned long flags = native_save_fl(); | 41 | unsigned long flags = native_save_fl(); |
39 | 42 | ||
@@ -53,7 +56,7 @@ __visible void vsmp_restore_fl(unsigned long flags) | |||
53 | } | 56 | } |
54 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl); | 57 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl); |
55 | 58 | ||
56 | asmlinkage void vsmp_irq_disable(void) | 59 | asmlinkage __visible void vsmp_irq_disable(void) |
57 | { | 60 | { |
58 | unsigned long flags = native_save_fl(); | 61 | unsigned long flags = native_save_fl(); |
59 | 62 | ||
@@ -61,7 +64,7 @@ asmlinkage void vsmp_irq_disable(void) | |||
61 | } | 64 | } |
62 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable); | 65 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable); |
63 | 66 | ||
64 | asmlinkage void vsmp_irq_enable(void) | 67 | asmlinkage __visible void vsmp_irq_enable(void) |
65 | { | 68 | { |
66 | unsigned long flags = native_save_fl(); | 69 | unsigned long flags = native_save_fl(); |
67 | 70 | ||
@@ -101,6 +104,10 @@ static void __init set_vsmp_pv_ops(void) | |||
101 | #ifdef CONFIG_SMP | 104 | #ifdef CONFIG_SMP |
102 | if (cap & ctl & BIT(8)) { | 105 | if (cap & ctl & BIT(8)) { |
103 | ctl &= ~BIT(8); | 106 | ctl &= ~BIT(8); |
107 | |||
108 | /* Interrupt routing set to ignore */ | ||
109 | irq_routing_comply = 0; | ||
110 | |||
104 | #ifdef CONFIG_PROC_FS | 111 | #ifdef CONFIG_PROC_FS |
105 | /* Don't let users change irq affinity via procfs */ | 112 | /* Don't let users change irq affinity via procfs */ |
106 | no_irq_affinity = 1; | 113 | no_irq_affinity = 1; |
@@ -218,7 +225,9 @@ static void vsmp_apic_post_init(void) | |||
218 | { | 225 | { |
219 | /* need to update phys_pkg_id */ | 226 | /* need to update phys_pkg_id */ |
220 | apic->phys_pkg_id = apicid_phys_pkg_id; | 227 | apic->phys_pkg_id = apicid_phys_pkg_id; |
221 | apic->vector_allocation_domain = fill_vector_allocation_domain; | 228 | |
229 | if (!irq_routing_comply) | ||
230 | apic->vector_allocation_domain = fill_vector_allocation_domain; | ||
222 | } | 231 | } |
223 | 232 | ||
224 | void __init vsmp_init(void) | 233 | void __init vsmp_init(void) |
diff --git a/arch/x86/kernel/vsyscall_gtod.c b/arch/x86/kernel/vsyscall_gtod.c index f9c6e56e14b5..9531fbb123ba 100644 --- a/arch/x86/kernel/vsyscall_gtod.c +++ b/arch/x86/kernel/vsyscall_gtod.c | |||
@@ -43,7 +43,7 @@ void update_vsyscall(struct timekeeper *tk) | |||
43 | vdata->monotonic_time_sec = tk->xtime_sec | 43 | vdata->monotonic_time_sec = tk->xtime_sec |
44 | + tk->wall_to_monotonic.tv_sec; | 44 | + tk->wall_to_monotonic.tv_sec; |
45 | vdata->monotonic_time_snsec = tk->xtime_nsec | 45 | vdata->monotonic_time_snsec = tk->xtime_nsec |
46 | + (tk->wall_to_monotonic.tv_nsec | 46 | + ((u64)tk->wall_to_monotonic.tv_nsec |
47 | << tk->shift); | 47 | << tk->shift); |
48 | while (vdata->monotonic_time_snsec >= | 48 | while (vdata->monotonic_time_snsec >= |
49 | (((u64)NSEC_PER_SEC) << tk->shift)) { | 49 | (((u64)NSEC_PER_SEC) << tk->shift)) { |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1f68c5831924..33e8c028842f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) | |||
503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 | 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 |
504 | 504 | ||
505 | 505 | ||
506 | static const unsigned long shadow_read_only_fields[] = { | 506 | static unsigned long shadow_read_only_fields[] = { |
507 | /* | 507 | /* |
508 | * We do NOT shadow fields that are modified when L0 | 508 | * We do NOT shadow fields that are modified when L0 |
509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, | 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, |
@@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = { | |||
526 | GUEST_LINEAR_ADDRESS, | 526 | GUEST_LINEAR_ADDRESS, |
527 | GUEST_PHYSICAL_ADDRESS | 527 | GUEST_PHYSICAL_ADDRESS |
528 | }; | 528 | }; |
529 | static const int max_shadow_read_only_fields = | 529 | static int max_shadow_read_only_fields = |
530 | ARRAY_SIZE(shadow_read_only_fields); | 530 | ARRAY_SIZE(shadow_read_only_fields); |
531 | 531 | ||
532 | static const unsigned long shadow_read_write_fields[] = { | 532 | static unsigned long shadow_read_write_fields[] = { |
533 | GUEST_RIP, | 533 | GUEST_RIP, |
534 | GUEST_RSP, | 534 | GUEST_RSP, |
535 | GUEST_CR0, | 535 | GUEST_CR0, |
@@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = { | |||
558 | HOST_FS_SELECTOR, | 558 | HOST_FS_SELECTOR, |
559 | HOST_GS_SELECTOR | 559 | HOST_GS_SELECTOR |
560 | }; | 560 | }; |
561 | static const int max_shadow_read_write_fields = | 561 | static int max_shadow_read_write_fields = |
562 | ARRAY_SIZE(shadow_read_write_fields); | 562 | ARRAY_SIZE(shadow_read_write_fields); |
563 | 563 | ||
564 | static const unsigned short vmcs_field_to_offset_table[] = { | 564 | static const unsigned short vmcs_field_to_offset_table[] = { |
@@ -3009,6 +3009,41 @@ static void free_kvm_area(void) | |||
3009 | } | 3009 | } |
3010 | } | 3010 | } |
3011 | 3011 | ||
3012 | static void init_vmcs_shadow_fields(void) | ||
3013 | { | ||
3014 | int i, j; | ||
3015 | |||
3016 | /* No checks for read only fields yet */ | ||
3017 | |||
3018 | for (i = j = 0; i < max_shadow_read_write_fields; i++) { | ||
3019 | switch (shadow_read_write_fields[i]) { | ||
3020 | case GUEST_BNDCFGS: | ||
3021 | if (!vmx_mpx_supported()) | ||
3022 | continue; | ||
3023 | break; | ||
3024 | default: | ||
3025 | break; | ||
3026 | } | ||
3027 | |||
3028 | if (j < i) | ||
3029 | shadow_read_write_fields[j] = | ||
3030 | shadow_read_write_fields[i]; | ||
3031 | j++; | ||
3032 | } | ||
3033 | max_shadow_read_write_fields = j; | ||
3034 | |||
3035 | /* shadowed fields guest access without vmexit */ | ||
3036 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
3037 | clear_bit(shadow_read_write_fields[i], | ||
3038 | vmx_vmwrite_bitmap); | ||
3039 | clear_bit(shadow_read_write_fields[i], | ||
3040 | vmx_vmread_bitmap); | ||
3041 | } | ||
3042 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
3043 | clear_bit(shadow_read_only_fields[i], | ||
3044 | vmx_vmread_bitmap); | ||
3045 | } | ||
3046 | |||
3012 | static __init int alloc_kvm_area(void) | 3047 | static __init int alloc_kvm_area(void) |
3013 | { | 3048 | { |
3014 | int cpu; | 3049 | int cpu; |
@@ -3039,6 +3074,8 @@ static __init int hardware_setup(void) | |||
3039 | enable_vpid = 0; | 3074 | enable_vpid = 0; |
3040 | if (!cpu_has_vmx_shadow_vmcs()) | 3075 | if (!cpu_has_vmx_shadow_vmcs()) |
3041 | enable_shadow_vmcs = 0; | 3076 | enable_shadow_vmcs = 0; |
3077 | if (enable_shadow_vmcs) | ||
3078 | init_vmcs_shadow_fields(); | ||
3042 | 3079 | ||
3043 | if (!cpu_has_vmx_ept() || | 3080 | if (!cpu_has_vmx_ept() || |
3044 | !cpu_has_vmx_ept_4levels()) { | 3081 | !cpu_has_vmx_ept_4levels()) { |
@@ -8803,14 +8840,6 @@ static int __init vmx_init(void) | |||
8803 | 8840 | ||
8804 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | 8841 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); |
8805 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | 8842 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); |
8806 | /* shadowed read/write fields */ | ||
8807 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
8808 | clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap); | ||
8809 | clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap); | ||
8810 | } | ||
8811 | /* shadowed read only fields */ | ||
8812 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
8813 | clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap); | ||
8814 | 8843 | ||
8815 | /* | 8844 | /* |
8816 | * Allow direct access to the PC debug port (it is often used for I/O | 8845 | * Allow direct access to the PC debug port (it is often used for I/O |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8b8fc0b792ba..b6c0bacca9bd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -280,7 +280,7 @@ int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
280 | } | 280 | } |
281 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); | 281 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); |
282 | 282 | ||
283 | asmlinkage void kvm_spurious_fault(void) | 283 | asmlinkage __visible void kvm_spurious_fault(void) |
284 | { | 284 | { |
285 | /* Fault while not rebooting. We want the trace. */ | 285 | /* Fault while not rebooting. We want the trace. */ |
286 | BUG(); | 286 | BUG(); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index ad1fb5f53925..aae94132bc24 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next) | |||
233 | * flags word contains all kind of stuff, but in practice Linux only cares | 233 | * flags word contains all kind of stuff, but in practice Linux only cares |
234 | * about the interrupt flag. Our "save_flags()" just returns that. | 234 | * about the interrupt flag. Our "save_flags()" just returns that. |
235 | */ | 235 | */ |
236 | asmlinkage unsigned long lguest_save_fl(void) | 236 | asmlinkage __visible unsigned long lguest_save_fl(void) |
237 | { | 237 | { |
238 | return lguest_data.irq_enabled; | 238 | return lguest_data.irq_enabled; |
239 | } | 239 | } |
240 | 240 | ||
241 | /* Interrupts go off... */ | 241 | /* Interrupts go off... */ |
242 | asmlinkage void lguest_irq_disable(void) | 242 | asmlinkage __visible void lguest_irq_disable(void) |
243 | { | 243 | { |
244 | lguest_data.irq_enabled = 0; | 244 | lguest_data.irq_enabled = 0; |
245 | } | 245 | } |
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index db9db446b71a..43623739c7cf 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c | |||
@@ -76,7 +76,7 @@ static inline int __flip_bit(u32 msr, u8 bit, bool set) | |||
76 | if (m1.q == m.q) | 76 | if (m1.q == m.q) |
77 | return 0; | 77 | return 0; |
78 | 78 | ||
79 | err = msr_write(msr, &m); | 79 | err = msr_write(msr, &m1); |
80 | if (err) | 80 | if (err) |
81 | return err; | 81 | return err; |
82 | 82 | ||
diff --git a/arch/x86/math-emu/errors.c b/arch/x86/math-emu/errors.c index a5449089cd9f..9e6545f269e5 100644 --- a/arch/x86/math-emu/errors.c +++ b/arch/x86/math-emu/errors.c | |||
@@ -302,7 +302,7 @@ static struct { | |||
302 | 0x242 in div_Xsig.S | 302 | 0x242 in div_Xsig.S |
303 | */ | 303 | */ |
304 | 304 | ||
305 | asmlinkage void FPU_exception(int n) | 305 | asmlinkage __visible void FPU_exception(int n) |
306 | { | 306 | { |
307 | int i, int_type; | 307 | int i, int_type; |
308 | 308 | ||
@@ -492,7 +492,7 @@ int real_2op_NaN(FPU_REG const *b, u_char tagb, | |||
492 | 492 | ||
493 | /* Invalid arith operation on Valid registers */ | 493 | /* Invalid arith operation on Valid registers */ |
494 | /* Returns < 0 if the exception is unmasked */ | 494 | /* Returns < 0 if the exception is unmasked */ |
495 | asmlinkage int arith_invalid(int deststnr) | 495 | asmlinkage __visible int arith_invalid(int deststnr) |
496 | { | 496 | { |
497 | 497 | ||
498 | EXCEPTION(EX_Invalid); | 498 | EXCEPTION(EX_Invalid); |
@@ -507,7 +507,7 @@ asmlinkage int arith_invalid(int deststnr) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | /* Divide a finite number by zero */ | 509 | /* Divide a finite number by zero */ |
510 | asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign) | 510 | asmlinkage __visible int FPU_divide_by_zero(int deststnr, u_char sign) |
511 | { | 511 | { |
512 | FPU_REG *dest = &st(deststnr); | 512 | FPU_REG *dest = &st(deststnr); |
513 | int tag = TAG_Valid; | 513 | int tag = TAG_Valid; |
@@ -539,7 +539,7 @@ int set_precision_flag(int flags) | |||
539 | } | 539 | } |
540 | 540 | ||
541 | /* This may be called often, so keep it lean */ | 541 | /* This may be called often, so keep it lean */ |
542 | asmlinkage void set_precision_flag_up(void) | 542 | asmlinkage __visible void set_precision_flag_up(void) |
543 | { | 543 | { |
544 | if (control_word & CW_Precision) | 544 | if (control_word & CW_Precision) |
545 | partial_status |= (SW_Precision | SW_C1); /* The masked response */ | 545 | partial_status |= (SW_Precision | SW_C1); /* The masked response */ |
@@ -548,7 +548,7 @@ asmlinkage void set_precision_flag_up(void) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | /* This may be called often, so keep it lean */ | 550 | /* This may be called often, so keep it lean */ |
551 | asmlinkage void set_precision_flag_down(void) | 551 | asmlinkage __visible void set_precision_flag_down(void) |
552 | { | 552 | { |
553 | if (control_word & CW_Precision) { /* The masked response */ | 553 | if (control_word & CW_Precision) { /* The masked response */ |
554 | partial_status &= ~SW_C1; | 554 | partial_status &= ~SW_C1; |
@@ -557,7 +557,7 @@ asmlinkage void set_precision_flag_down(void) | |||
557 | EXCEPTION(EX_Precision); | 557 | EXCEPTION(EX_Precision); |
558 | } | 558 | } |
559 | 559 | ||
560 | asmlinkage int denormal_operand(void) | 560 | asmlinkage __visible int denormal_operand(void) |
561 | { | 561 | { |
562 | if (control_word & CW_Denormal) { /* The masked response */ | 562 | if (control_word & CW_Denormal) { /* The masked response */ |
563 | partial_status |= SW_Denorm_Op; | 563 | partial_status |= SW_Denorm_Op; |
@@ -568,7 +568,7 @@ asmlinkage int denormal_operand(void) | |||
568 | } | 568 | } |
569 | } | 569 | } |
570 | 570 | ||
571 | asmlinkage int arith_overflow(FPU_REG *dest) | 571 | asmlinkage __visible int arith_overflow(FPU_REG *dest) |
572 | { | 572 | { |
573 | int tag = TAG_Valid; | 573 | int tag = TAG_Valid; |
574 | 574 | ||
@@ -596,7 +596,7 @@ asmlinkage int arith_overflow(FPU_REG *dest) | |||
596 | 596 | ||
597 | } | 597 | } |
598 | 598 | ||
599 | asmlinkage int arith_underflow(FPU_REG *dest) | 599 | asmlinkage __visible int arith_underflow(FPU_REG *dest) |
600 | { | 600 | { |
601 | int tag = TAG_Valid; | 601 | int tag = TAG_Valid; |
602 | 602 | ||
diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c index 81b506d5befd..524142117296 100644 --- a/arch/x86/platform/efi/early_printk.c +++ b/arch/x86/platform/efi/early_printk.c | |||
@@ -14,48 +14,92 @@ | |||
14 | 14 | ||
15 | static const struct font_desc *font; | 15 | static const struct font_desc *font; |
16 | static u32 efi_x, efi_y; | 16 | static u32 efi_x, efi_y; |
17 | static void *efi_fb; | ||
18 | static bool early_efi_keep; | ||
17 | 19 | ||
18 | static __init void early_efi_clear_scanline(unsigned int y) | 20 | /* |
21 | * efi earlyprintk need use early_ioremap to map the framebuffer. | ||
22 | * But early_ioremap is not usable for earlyprintk=efi,keep, ioremap should | ||
23 | * be used instead. ioremap will be available after paging_init() which is | ||
24 | * earlier than initcall callbacks. Thus adding this early initcall function | ||
25 | * early_efi_map_fb to map the whole efi framebuffer. | ||
26 | */ | ||
27 | static __init int early_efi_map_fb(void) | ||
19 | { | 28 | { |
20 | unsigned long base, *dst; | 29 | unsigned long base, size; |
21 | u16 len; | 30 | |
31 | if (!early_efi_keep) | ||
32 | return 0; | ||
22 | 33 | ||
23 | base = boot_params.screen_info.lfb_base; | 34 | base = boot_params.screen_info.lfb_base; |
24 | len = boot_params.screen_info.lfb_linelength; | 35 | size = boot_params.screen_info.lfb_size; |
36 | efi_fb = ioremap(base, size); | ||
37 | |||
38 | return efi_fb ? 0 : -ENOMEM; | ||
39 | } | ||
40 | early_initcall(early_efi_map_fb); | ||
41 | |||
42 | /* | ||
43 | * early_efi_map maps efi framebuffer region [start, start + len -1] | ||
44 | * In case earlyprintk=efi,keep we have the whole framebuffer mapped already | ||
45 | * so just return the offset efi_fb + start. | ||
46 | */ | ||
47 | static __init_refok void *early_efi_map(unsigned long start, unsigned long len) | ||
48 | { | ||
49 | unsigned long base; | ||
50 | |||
51 | base = boot_params.screen_info.lfb_base; | ||
52 | |||
53 | if (efi_fb) | ||
54 | return (efi_fb + start); | ||
55 | else | ||
56 | return early_ioremap(base + start, len); | ||
57 | } | ||
25 | 58 | ||
26 | dst = early_ioremap(base + y*len, len); | 59 | static __init_refok void early_efi_unmap(void *addr, unsigned long len) |
60 | { | ||
61 | if (!efi_fb) | ||
62 | early_iounmap(addr, len); | ||
63 | } | ||
64 | |||
65 | static void early_efi_clear_scanline(unsigned int y) | ||
66 | { | ||
67 | unsigned long *dst; | ||
68 | u16 len; | ||
69 | |||
70 | len = boot_params.screen_info.lfb_linelength; | ||
71 | dst = early_efi_map(y*len, len); | ||
27 | if (!dst) | 72 | if (!dst) |
28 | return; | 73 | return; |
29 | 74 | ||
30 | memset(dst, 0, len); | 75 | memset(dst, 0, len); |
31 | early_iounmap(dst, len); | 76 | early_efi_unmap(dst, len); |
32 | } | 77 | } |
33 | 78 | ||
34 | static __init void early_efi_scroll_up(void) | 79 | static void early_efi_scroll_up(void) |
35 | { | 80 | { |
36 | unsigned long base, *dst, *src; | 81 | unsigned long *dst, *src; |
37 | u16 len; | 82 | u16 len; |
38 | u32 i, height; | 83 | u32 i, height; |
39 | 84 | ||
40 | base = boot_params.screen_info.lfb_base; | ||
41 | len = boot_params.screen_info.lfb_linelength; | 85 | len = boot_params.screen_info.lfb_linelength; |
42 | height = boot_params.screen_info.lfb_height; | 86 | height = boot_params.screen_info.lfb_height; |
43 | 87 | ||
44 | for (i = 0; i < height - font->height; i++) { | 88 | for (i = 0; i < height - font->height; i++) { |
45 | dst = early_ioremap(base + i*len, len); | 89 | dst = early_efi_map(i*len, len); |
46 | if (!dst) | 90 | if (!dst) |
47 | return; | 91 | return; |
48 | 92 | ||
49 | src = early_ioremap(base + (i + font->height) * len, len); | 93 | src = early_efi_map((i + font->height) * len, len); |
50 | if (!src) { | 94 | if (!src) { |
51 | early_iounmap(dst, len); | 95 | early_efi_unmap(dst, len); |
52 | return; | 96 | return; |
53 | } | 97 | } |
54 | 98 | ||
55 | memmove(dst, src, len); | 99 | memmove(dst, src, len); |
56 | 100 | ||
57 | early_iounmap(src, len); | 101 | early_efi_unmap(src, len); |
58 | early_iounmap(dst, len); | 102 | early_efi_unmap(dst, len); |
59 | } | 103 | } |
60 | } | 104 | } |
61 | 105 | ||
@@ -79,16 +123,14 @@ static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h) | |||
79 | } | 123 | } |
80 | } | 124 | } |
81 | 125 | ||
82 | static __init void | 126 | static void |
83 | early_efi_write(struct console *con, const char *str, unsigned int num) | 127 | early_efi_write(struct console *con, const char *str, unsigned int num) |
84 | { | 128 | { |
85 | struct screen_info *si; | 129 | struct screen_info *si; |
86 | unsigned long base; | ||
87 | unsigned int len; | 130 | unsigned int len; |
88 | const char *s; | 131 | const char *s; |
89 | void *dst; | 132 | void *dst; |
90 | 133 | ||
91 | base = boot_params.screen_info.lfb_base; | ||
92 | si = &boot_params.screen_info; | 134 | si = &boot_params.screen_info; |
93 | len = si->lfb_linelength; | 135 | len = si->lfb_linelength; |
94 | 136 | ||
@@ -109,7 +151,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) | |||
109 | for (h = 0; h < font->height; h++) { | 151 | for (h = 0; h < font->height; h++) { |
110 | unsigned int n, x; | 152 | unsigned int n, x; |
111 | 153 | ||
112 | dst = early_ioremap(base + (efi_y + h) * len, len); | 154 | dst = early_efi_map((efi_y + h) * len, len); |
113 | if (!dst) | 155 | if (!dst) |
114 | return; | 156 | return; |
115 | 157 | ||
@@ -123,7 +165,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) | |||
123 | s++; | 165 | s++; |
124 | } | 166 | } |
125 | 167 | ||
126 | early_iounmap(dst, len); | 168 | early_efi_unmap(dst, len); |
127 | } | 169 | } |
128 | 170 | ||
129 | num -= count; | 171 | num -= count; |
@@ -179,6 +221,9 @@ static __init int early_efi_setup(struct console *con, char *options) | |||
179 | for (i = 0; i < (yres - efi_y) / font->height; i++) | 221 | for (i = 0; i < (yres - efi_y) / font->height; i++) |
180 | early_efi_scroll_up(); | 222 | early_efi_scroll_up(); |
181 | 223 | ||
224 | /* early_console_register will unset CON_BOOT in case ,keep */ | ||
225 | if (!(con->flags & CON_BOOT)) | ||
226 | early_efi_keep = true; | ||
182 | return 0; | 227 | return 0; |
183 | } | 228 | } |
184 | 229 | ||
diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c index ff0174dda810..a9acde72d4ed 100644 --- a/arch/x86/platform/olpc/olpc-xo1-pm.c +++ b/arch/x86/platform/olpc/olpc-xo1-pm.c | |||
@@ -75,7 +75,7 @@ static int xo1_power_state_enter(suspend_state_t pm_state) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | asmlinkage int xo1_do_sleep(u8 sleep_state) | 78 | asmlinkage __visible int xo1_do_sleep(u8 sleep_state) |
79 | { | 79 | { |
80 | void *pgd_addr = __va(read_cr3()); | 80 | void *pgd_addr = __va(read_cr3()); |
81 | 81 | ||
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index 304fca20d96e..35e2bb6c0f37 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c | |||
@@ -23,7 +23,7 @@ | |||
23 | extern __visible const void __nosave_begin, __nosave_end; | 23 | extern __visible const void __nosave_begin, __nosave_end; |
24 | 24 | ||
25 | /* Defined in hibernate_asm_64.S */ | 25 | /* Defined in hibernate_asm_64.S */ |
26 | extern asmlinkage int restore_image(void); | 26 | extern asmlinkage __visible int restore_image(void); |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Address to jump to in the last phase of restore in order to get to the image | 29 | * Address to jump to in the last phase of restore in order to get to the image |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 201d09a7c46b..c34bfc4bbe7f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1515,7 +1515,7 @@ static void __init xen_pvh_early_guest_init(void) | |||
1515 | } | 1515 | } |
1516 | 1516 | ||
1517 | /* First C function to be called on Xen boot */ | 1517 | /* First C function to be called on Xen boot */ |
1518 | asmlinkage void __init xen_start_kernel(void) | 1518 | asmlinkage __visible void __init xen_start_kernel(void) |
1519 | { | 1519 | { |
1520 | struct physdev_set_iopl set_iopl; | 1520 | struct physdev_set_iopl set_iopl; |
1521 | int rc; | 1521 | int rc; |
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 08f763de26fe..a1207cb6472a 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -23,7 +23,7 @@ void xen_force_evtchn_callback(void) | |||
23 | (void)HYPERVISOR_xen_version(0, NULL); | 23 | (void)HYPERVISOR_xen_version(0, NULL); |
24 | } | 24 | } |
25 | 25 | ||
26 | asmlinkage unsigned long xen_save_fl(void) | 26 | asmlinkage __visible unsigned long xen_save_fl(void) |
27 | { | 27 | { |
28 | struct vcpu_info *vcpu; | 28 | struct vcpu_info *vcpu; |
29 | unsigned long flags; | 29 | unsigned long flags; |
@@ -63,7 +63,7 @@ __visible void xen_restore_fl(unsigned long flags) | |||
63 | } | 63 | } |
64 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); | 64 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); |
65 | 65 | ||
66 | asmlinkage void xen_irq_disable(void) | 66 | asmlinkage __visible void xen_irq_disable(void) |
67 | { | 67 | { |
68 | /* There's a one instruction preempt window here. We need to | 68 | /* There's a one instruction preempt window here. We need to |
69 | make sure we're don't switch CPUs between getting the vcpu | 69 | make sure we're don't switch CPUs between getting the vcpu |
@@ -74,7 +74,7 @@ asmlinkage void xen_irq_disable(void) | |||
74 | } | 74 | } |
75 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); | 75 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); |
76 | 76 | ||
77 | asmlinkage void xen_irq_enable(void) | 77 | asmlinkage __visible void xen_irq_enable(void) |
78 | { | 78 | { |
79 | struct vcpu_info *vcpu; | 79 | struct vcpu_info *vcpu; |
80 | 80 | ||
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 02d6d29a63c1..3a617af60d46 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -14,6 +14,7 @@ config XTENSA | |||
14 | select GENERIC_PCI_IOMAP | 14 | select GENERIC_PCI_IOMAP |
15 | select ARCH_WANT_IPC_PARSE_VERSION | 15 | select ARCH_WANT_IPC_PARSE_VERSION |
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 16 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | select BUILDTIME_EXTABLE_SORT | ||
17 | select CLONE_BACKWARDS | 18 | select CLONE_BACKWARDS |
18 | select IRQ_DOMAIN | 19 | select IRQ_DOMAIN |
19 | select HAVE_OPROFILE | 20 | select HAVE_OPROFILE |
@@ -189,6 +190,24 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX | |||
189 | 190 | ||
190 | If in doubt, say Y. | 191 | If in doubt, say Y. |
191 | 192 | ||
193 | config HIGHMEM | ||
194 | bool "High Memory Support" | ||
195 | help | ||
196 | Linux can use the full amount of RAM in the system by | ||
197 | default. However, the default MMUv2 setup only maps the | ||
198 | lowermost 128 MB of memory linearly to the areas starting | ||
199 | at 0xd0000000 (cached) and 0xd8000000 (uncached). | ||
200 | When there are more than 128 MB memory in the system not | ||
201 | all of it can be "permanently mapped" by the kernel. | ||
202 | The physical memory that's not permanently mapped is called | ||
203 | "high memory". | ||
204 | |||
205 | If you are compiling a kernel which will never run on a | ||
206 | machine with more than 128 MB total physical RAM, answer | ||
207 | N here. | ||
208 | |||
209 | If unsure, say Y. | ||
210 | |||
192 | endmenu | 211 | endmenu |
193 | 212 | ||
194 | config XTENSA_CALIBRATE_CCOUNT | 213 | config XTENSA_CALIBRATE_CCOUNT |
@@ -224,7 +243,6 @@ choice | |||
224 | 243 | ||
225 | config XTENSA_PLATFORM_ISS | 244 | config XTENSA_PLATFORM_ISS |
226 | bool "ISS" | 245 | bool "ISS" |
227 | depends on TTY | ||
228 | select XTENSA_CALIBRATE_CCOUNT | 246 | select XTENSA_CALIBRATE_CCOUNT |
229 | select SERIAL_CONSOLE | 247 | select SERIAL_CONSOLE |
230 | help | 248 | help |
diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts new file mode 100644 index 000000000000..742a347be67a --- /dev/null +++ b/arch/xtensa/boot/dts/kc705.dts | |||
@@ -0,0 +1,11 @@ | |||
1 | /dts-v1/; | ||
2 | /include/ "xtfpga.dtsi" | ||
3 | /include/ "xtfpga-flash-128m.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "cdns,xtensa-kc705"; | ||
7 | memory@0 { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x08000000>; | ||
10 | }; | ||
11 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi new file mode 100644 index 000000000000..d3a88e029873 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi | |||
@@ -0,0 +1,28 @@ | |||
1 | / { | ||
2 | soc { | ||
3 | flash: flash@00000000 { | ||
4 | #address-cells = <1>; | ||
5 | #size-cells = <1>; | ||
6 | compatible = "cfi-flash"; | ||
7 | reg = <0x00000000 0x08000000>; | ||
8 | bank-width = <2>; | ||
9 | device-width = <2>; | ||
10 | partition@0x0 { | ||
11 | label = "data"; | ||
12 | reg = <0x00000000 0x06000000>; | ||
13 | }; | ||
14 | partition@0x6000000 { | ||
15 | label = "boot loader area"; | ||
16 | reg = <0x06000000 0x00800000>; | ||
17 | }; | ||
18 | partition@0x6800000 { | ||
19 | label = "kernel image"; | ||
20 | reg = <0x06800000 0x017e0000>; | ||
21 | }; | ||
22 | partition@0x7fe0000 { | ||
23 | label = "boot environment"; | ||
24 | reg = <0x07fe0000 0x00020000>; | ||
25 | }; | ||
26 | }; | ||
27 | }; | ||
28 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi index e5703c7beeb6..1d97203c18e7 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | |||
@@ -1,26 +1,28 @@ | |||
1 | / { | 1 | / { |
2 | flash: flash@f8000000 { | 2 | soc { |
3 | #address-cells = <1>; | 3 | flash: flash@08000000 { |
4 | #size-cells = <1>; | 4 | #address-cells = <1>; |
5 | compatible = "cfi-flash"; | 5 | #size-cells = <1>; |
6 | reg = <0xf8000000 0x01000000>; | 6 | compatible = "cfi-flash"; |
7 | bank-width = <2>; | 7 | reg = <0x08000000 0x01000000>; |
8 | device-width = <2>; | 8 | bank-width = <2>; |
9 | partition@0x0 { | 9 | device-width = <2>; |
10 | label = "boot loader area"; | 10 | partition@0x0 { |
11 | reg = <0x00000000 0x00400000>; | 11 | label = "boot loader area"; |
12 | reg = <0x00000000 0x00400000>; | ||
13 | }; | ||
14 | partition@0x400000 { | ||
15 | label = "kernel image"; | ||
16 | reg = <0x00400000 0x00600000>; | ||
17 | }; | ||
18 | partition@0xa00000 { | ||
19 | label = "data"; | ||
20 | reg = <0x00a00000 0x005e0000>; | ||
21 | }; | ||
22 | partition@0xfe0000 { | ||
23 | label = "boot environment"; | ||
24 | reg = <0x00fe0000 0x00020000>; | ||
25 | }; | ||
12 | }; | 26 | }; |
13 | partition@0x400000 { | 27 | }; |
14 | label = "kernel image"; | ||
15 | reg = <0x00400000 0x00600000>; | ||
16 | }; | ||
17 | partition@0xa00000 { | ||
18 | label = "data"; | ||
19 | reg = <0x00a00000 0x005e0000>; | ||
20 | }; | ||
21 | partition@0xfe0000 { | ||
22 | label = "boot environment"; | ||
23 | reg = <0x00fe0000 0x00020000>; | ||
24 | }; | ||
25 | }; | ||
26 | }; | 28 | }; |
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi index 6f9c10d6b689..d1c621ca8be1 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | |||
@@ -1,18 +1,20 @@ | |||
1 | / { | 1 | / { |
2 | flash: flash@f8000000 { | 2 | soc { |
3 | #address-cells = <1>; | 3 | flash: flash@08000000 { |
4 | #size-cells = <1>; | 4 | #address-cells = <1>; |
5 | compatible = "cfi-flash"; | 5 | #size-cells = <1>; |
6 | reg = <0xf8000000 0x00400000>; | 6 | compatible = "cfi-flash"; |
7 | bank-width = <2>; | 7 | reg = <0x08000000 0x00400000>; |
8 | device-width = <2>; | 8 | bank-width = <2>; |
9 | partition@0x0 { | 9 | device-width = <2>; |
10 | label = "boot loader area"; | 10 | partition@0x0 { |
11 | reg = <0x00000000 0x003f0000>; | 11 | label = "boot loader area"; |
12 | reg = <0x00000000 0x003f0000>; | ||
13 | }; | ||
14 | partition@0x3f0000 { | ||
15 | label = "boot environment"; | ||
16 | reg = <0x003f0000 0x00010000>; | ||
17 | }; | ||
12 | }; | 18 | }; |
13 | partition@0x3f0000 { | 19 | }; |
14 | label = "boot environment"; | ||
15 | reg = <0x003f0000 0x00010000>; | ||
16 | }; | ||
17 | }; | ||
18 | }; | 20 | }; |
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index e7370b11348e..dec9178840f6 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi | |||
@@ -42,21 +42,28 @@ | |||
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | serial0: serial@fd050020 { | 45 | soc { |
46 | device_type = "serial"; | 46 | #address-cells = <1>; |
47 | compatible = "ns16550a"; | 47 | #size-cells = <1>; |
48 | no-loopback-test; | 48 | compatible = "simple-bus"; |
49 | reg = <0xfd050020 0x20>; | 49 | ranges = <0x00000000 0xf0000000 0x10000000>; |
50 | reg-shift = <2>; | ||
51 | interrupts = <0 1>; /* external irq 0 */ | ||
52 | clocks = <&osc>; | ||
53 | }; | ||
54 | 50 | ||
55 | enet0: ethoc@fd030000 { | 51 | serial0: serial@0d050020 { |
56 | compatible = "opencores,ethoc"; | 52 | device_type = "serial"; |
57 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; | 53 | compatible = "ns16550a"; |
58 | interrupts = <1 1>; /* external irq 1 */ | 54 | no-loopback-test; |
59 | local-mac-address = [00 50 c2 13 6f 00]; | 55 | reg = <0x0d050020 0x20>; |
60 | clocks = <&osc>; | 56 | reg-shift = <2>; |
57 | interrupts = <0 1>; /* external irq 0 */ | ||
58 | clocks = <&osc>; | ||
59 | }; | ||
60 | |||
61 | enet0: ethoc@0d030000 { | ||
62 | compatible = "opencores,ethoc"; | ||
63 | reg = <0x0d030000 0x4000 0x0d800000 0x4000>; | ||
64 | interrupts = <1 1>; /* external irq 1 */ | ||
65 | local-mac-address = [00 50 c2 13 6f 00]; | ||
66 | clocks = <&osc>; | ||
67 | }; | ||
61 | }; | 68 | }; |
62 | }; | 69 | }; |
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 23392c5630ce..892aab399ac8 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h | |||
@@ -37,23 +37,14 @@ typedef struct bp_tag { | |||
37 | unsigned long data[0]; /* data */ | 37 | unsigned long data[0]; /* data */ |
38 | } bp_tag_t; | 38 | } bp_tag_t; |
39 | 39 | ||
40 | typedef struct meminfo { | 40 | struct bp_meminfo { |
41 | unsigned long type; | 41 | unsigned long type; |
42 | unsigned long start; | 42 | unsigned long start; |
43 | unsigned long end; | 43 | unsigned long end; |
44 | } meminfo_t; | 44 | }; |
45 | |||
46 | #define SYSMEM_BANKS_MAX 5 | ||
47 | 45 | ||
48 | #define MEMORY_TYPE_CONVENTIONAL 0x1000 | 46 | #define MEMORY_TYPE_CONVENTIONAL 0x1000 |
49 | #define MEMORY_TYPE_NONE 0x2000 | 47 | #define MEMORY_TYPE_NONE 0x2000 |
50 | 48 | ||
51 | typedef struct sysmem_info { | ||
52 | int nr_banks; | ||
53 | meminfo_t bank[SYSMEM_BANKS_MAX]; | ||
54 | } sysmem_info_t; | ||
55 | |||
56 | extern sysmem_info_t sysmem; | ||
57 | |||
58 | #endif | 49 | #endif |
59 | #endif | 50 | #endif |
diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h new file mode 100644 index 000000000000..9f6c33d0428a --- /dev/null +++ b/arch/xtensa/include/asm/fixmap.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * fixmap.h: compile-time virtual memory allocation | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 1998 Ingo Molnar | ||
9 | * | ||
10 | * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_FIXMAP_H | ||
14 | #define _ASM_FIXMAP_H | ||
15 | |||
16 | #include <asm/pgtable.h> | ||
17 | #ifdef CONFIG_HIGHMEM | ||
18 | #include <linux/threads.h> | ||
19 | #include <asm/kmap_types.h> | ||
20 | #endif | ||
21 | |||
22 | /* | ||
23 | * Here we define all the compile-time 'special' virtual | ||
24 | * addresses. The point is to have a constant address at | ||
25 | * compile time, but to set the physical address only | ||
26 | * in the boot process. We allocate these special addresses | ||
27 | * from the end of the consistent memory region backwards. | ||
28 | * Also this lets us do fail-safe vmalloc(), we | ||
29 | * can guarantee that these special addresses and | ||
30 | * vmalloc()-ed addresses never overlap. | ||
31 | * | ||
32 | * these 'compile-time allocated' memory buffers are | ||
33 | * fixed-size 4k pages. (or larger if used with an increment | ||
34 | * higher than 1) use fixmap_set(idx,phys) to associate | ||
35 | * physical memory with fixmap indices. | ||
36 | */ | ||
37 | enum fixed_addresses { | ||
38 | #ifdef CONFIG_HIGHMEM | ||
39 | /* reserved pte's for temporary kernel mappings */ | ||
40 | FIX_KMAP_BEGIN, | ||
41 | FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, | ||
42 | #endif | ||
43 | __end_of_fixed_addresses | ||
44 | }; | ||
45 | |||
46 | #define FIXADDR_TOP (VMALLOC_START - PAGE_SIZE) | ||
47 | #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) | ||
48 | #define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) | ||
49 | |||
50 | #include <asm-generic/fixmap.h> | ||
51 | |||
52 | #define kmap_get_fixmap_pte(vaddr) \ | ||
53 | pte_offset_kernel( \ | ||
54 | pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \ | ||
55 | (vaddr) \ | ||
56 | ) | ||
57 | |||
58 | #endif | ||
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 80be15124697..2653ef5d55f1 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h | |||
@@ -6,11 +6,54 @@ | |||
6 | * this archive for more details. | 6 | * this archive for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2003 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2003 - 2005 Tensilica Inc. |
9 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | 10 | */ |
10 | 11 | ||
11 | #ifndef _XTENSA_HIGHMEM_H | 12 | #ifndef _XTENSA_HIGHMEM_H |
12 | #define _XTENSA_HIGHMEM_H | 13 | #define _XTENSA_HIGHMEM_H |
13 | 14 | ||
14 | extern void flush_cache_kmaps(void); | 15 | #include <asm/cacheflush.h> |
16 | #include <asm/fixmap.h> | ||
17 | #include <asm/kmap_types.h> | ||
18 | #include <asm/pgtable.h> | ||
19 | |||
20 | #define PKMAP_BASE (FIXADDR_START - PMD_SIZE) | ||
21 | #define LAST_PKMAP PTRS_PER_PTE | ||
22 | #define LAST_PKMAP_MASK (LAST_PKMAP - 1) | ||
23 | #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) | ||
24 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | ||
25 | |||
26 | #define kmap_prot PAGE_KERNEL | ||
27 | |||
28 | extern pte_t *pkmap_page_table; | ||
29 | |||
30 | void *kmap_high(struct page *page); | ||
31 | void kunmap_high(struct page *page); | ||
32 | |||
33 | static inline void *kmap(struct page *page) | ||
34 | { | ||
35 | BUG_ON(in_interrupt()); | ||
36 | if (!PageHighMem(page)) | ||
37 | return page_address(page); | ||
38 | return kmap_high(page); | ||
39 | } | ||
40 | |||
41 | static inline void kunmap(struct page *page) | ||
42 | { | ||
43 | BUG_ON(in_interrupt()); | ||
44 | if (!PageHighMem(page)) | ||
45 | return; | ||
46 | kunmap_high(page); | ||
47 | } | ||
48 | |||
49 | static inline void flush_cache_kmaps(void) | ||
50 | { | ||
51 | flush_cache_all(); | ||
52 | } | ||
53 | |||
54 | void *kmap_atomic(struct page *page); | ||
55 | void __kunmap_atomic(void *kvaddr); | ||
56 | |||
57 | void kmap_init(void); | ||
15 | 58 | ||
16 | #endif | 59 | #endif |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 216446295ada..4b0ca35a93b1 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -310,6 +310,10 @@ set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) | |||
310 | update_pte(ptep, pteval); | 310 | update_pte(ptep, pteval); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void set_pte(pte_t *ptep, pte_t pteval) | ||
314 | { | ||
315 | update_pte(ptep, pteval); | ||
316 | } | ||
313 | 317 | ||
314 | static inline void | 318 | static inline void |
315 | set_pmd(pmd_t *pmdp, pmd_t pmdval) | 319 | set_pmd(pmd_t *pmdp, pmd_t pmdval) |
diff --git a/arch/xtensa/include/asm/sysmem.h b/arch/xtensa/include/asm/sysmem.h new file mode 100644 index 000000000000..c015c5c8e3f7 --- /dev/null +++ b/arch/xtensa/include/asm/sysmem.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * sysmem-related prototypes. | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_SYSMEM_H | ||
12 | #define _XTENSA_SYSMEM_H | ||
13 | |||
14 | #define SYSMEM_BANKS_MAX 31 | ||
15 | |||
16 | struct meminfo { | ||
17 | unsigned long start; | ||
18 | unsigned long end; | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * Bank array is sorted by .start. | ||
23 | * Banks don't overlap and there's at least one page gap | ||
24 | * between adjacent bank entries. | ||
25 | */ | ||
26 | struct sysmem_info { | ||
27 | int nr_banks; | ||
28 | struct meminfo bank[SYSMEM_BANKS_MAX]; | ||
29 | }; | ||
30 | |||
31 | extern struct sysmem_info sysmem; | ||
32 | |||
33 | int add_sysmem_bank(unsigned long start, unsigned long end); | ||
34 | int mem_reserve(unsigned long, unsigned long, int); | ||
35 | void bootmem_init(void); | ||
36 | void zones_init(void); | ||
37 | |||
38 | #endif /* _XTENSA_SYSMEM_H */ | ||
diff --git a/arch/xtensa/include/asm/tlbflush.h b/arch/xtensa/include/asm/tlbflush.h index fc34274ce41b..06875feb27c2 100644 --- a/arch/xtensa/include/asm/tlbflush.h +++ b/arch/xtensa/include/asm/tlbflush.h | |||
@@ -36,6 +36,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, | |||
36 | unsigned long page); | 36 | unsigned long page); |
37 | void local_flush_tlb_range(struct vm_area_struct *vma, | 37 | void local_flush_tlb_range(struct vm_area_struct *vma, |
38 | unsigned long start, unsigned long end); | 38 | unsigned long start, unsigned long end); |
39 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); | ||
39 | 40 | ||
40 | #ifdef CONFIG_SMP | 41 | #ifdef CONFIG_SMP |
41 | 42 | ||
@@ -44,12 +45,7 @@ void flush_tlb_mm(struct mm_struct *); | |||
44 | void flush_tlb_page(struct vm_area_struct *, unsigned long); | 45 | void flush_tlb_page(struct vm_area_struct *, unsigned long); |
45 | void flush_tlb_range(struct vm_area_struct *, unsigned long, | 46 | void flush_tlb_range(struct vm_area_struct *, unsigned long, |
46 | unsigned long); | 47 | unsigned long); |
47 | 48 | void flush_tlb_kernel_range(unsigned long start, unsigned long end); | |
48 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
49 | unsigned long end) | ||
50 | { | ||
51 | flush_tlb_all(); | ||
52 | } | ||
53 | 49 | ||
54 | #else /* !CONFIG_SMP */ | 50 | #else /* !CONFIG_SMP */ |
55 | 51 | ||
@@ -58,7 +54,8 @@ static inline void flush_tlb_kernel_range(unsigned long start, | |||
58 | #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) | 54 | #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) |
59 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \ | 55 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \ |
60 | end) | 56 | end) |
61 | #define flush_tlb_kernel_range(start, end) local_flush_tlb_all() | 57 | #define flush_tlb_kernel_range(start, end) local_flush_tlb_kernel_range(start, \ |
58 | end) | ||
62 | 59 | ||
63 | #endif /* CONFIG_SMP */ | 60 | #endif /* CONFIG_SMP */ |
64 | 61 | ||
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 84fe931bb60e..9757bb74e532 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/param.h> | 50 | #include <asm/param.h> |
51 | #include <asm/traps.h> | 51 | #include <asm/traps.h> |
52 | #include <asm/smp.h> | 52 | #include <asm/smp.h> |
53 | #include <asm/sysmem.h> | ||
53 | 54 | ||
54 | #include <platform/hardware.h> | 55 | #include <platform/hardware.h> |
55 | 56 | ||
@@ -88,12 +89,6 @@ static char __initdata command_line[COMMAND_LINE_SIZE]; | |||
88 | static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; | 89 | static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; |
89 | #endif | 90 | #endif |
90 | 91 | ||
91 | sysmem_info_t __initdata sysmem; | ||
92 | |||
93 | extern int mem_reserve(unsigned long, unsigned long, int); | ||
94 | extern void bootmem_init(void); | ||
95 | extern void zones_init(void); | ||
96 | |||
97 | /* | 92 | /* |
98 | * Boot parameter parsing. | 93 | * Boot parameter parsing. |
99 | * | 94 | * |
@@ -113,31 +108,14 @@ typedef struct tagtable { | |||
113 | 108 | ||
114 | /* parse current tag */ | 109 | /* parse current tag */ |
115 | 110 | ||
116 | static int __init add_sysmem_bank(unsigned long type, unsigned long start, | ||
117 | unsigned long end) | ||
118 | { | ||
119 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { | ||
120 | printk(KERN_WARNING | ||
121 | "Ignoring memory bank 0x%08lx size %ldKB\n", | ||
122 | start, end - start); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | sysmem.bank[sysmem.nr_banks].type = type; | ||
126 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); | ||
127 | sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; | ||
128 | sysmem.nr_banks++; | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int __init parse_tag_mem(const bp_tag_t *tag) | 111 | static int __init parse_tag_mem(const bp_tag_t *tag) |
134 | { | 112 | { |
135 | meminfo_t *mi = (meminfo_t *)(tag->data); | 113 | struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); |
136 | 114 | ||
137 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | 115 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) |
138 | return -1; | 116 | return -1; |
139 | 117 | ||
140 | return add_sysmem_bank(mi->type, mi->start, mi->end); | 118 | return add_sysmem_bank(mi->start, mi->end); |
141 | } | 119 | } |
142 | 120 | ||
143 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); | 121 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); |
@@ -146,8 +124,8 @@ __tagtable(BP_TAG_MEMORY, parse_tag_mem); | |||
146 | 124 | ||
147 | static int __init parse_tag_initrd(const bp_tag_t* tag) | 125 | static int __init parse_tag_initrd(const bp_tag_t* tag) |
148 | { | 126 | { |
149 | meminfo_t* mi; | 127 | struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); |
150 | mi = (meminfo_t*)(tag->data); | 128 | |
151 | initrd_start = (unsigned long)__va(mi->start); | 129 | initrd_start = (unsigned long)__va(mi->start); |
152 | initrd_end = (unsigned long)__va(mi->end); | 130 | initrd_end = (unsigned long)__va(mi->end); |
153 | 131 | ||
@@ -255,7 +233,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
255 | return; | 233 | return; |
256 | 234 | ||
257 | size &= PAGE_MASK; | 235 | size &= PAGE_MASK; |
258 | add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); | 236 | add_sysmem_bank(base, base + size); |
259 | } | 237 | } |
260 | 238 | ||
261 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 239 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) |
@@ -292,8 +270,6 @@ device_initcall(xtensa_device_probe); | |||
292 | 270 | ||
293 | void __init init_arch(bp_tag_t *bp_start) | 271 | void __init init_arch(bp_tag_t *bp_start) |
294 | { | 272 | { |
295 | sysmem.nr_banks = 0; | ||
296 | |||
297 | /* Parse boot parameters */ | 273 | /* Parse boot parameters */ |
298 | 274 | ||
299 | if (bp_start) | 275 | if (bp_start) |
@@ -304,10 +280,9 @@ void __init init_arch(bp_tag_t *bp_start) | |||
304 | #endif | 280 | #endif |
305 | 281 | ||
306 | if (sysmem.nr_banks == 0) { | 282 | if (sysmem.nr_banks == 0) { |
307 | sysmem.nr_banks = 1; | 283 | add_sysmem_bank(PLATFORM_DEFAULT_MEM_START, |
308 | sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; | 284 | PLATFORM_DEFAULT_MEM_START + |
309 | sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START | 285 | PLATFORM_DEFAULT_MEM_SIZE); |
310 | + PLATFORM_DEFAULT_MEM_SIZE; | ||
311 | } | 286 | } |
312 | 287 | ||
313 | #ifdef CONFIG_CMDLINE_BOOL | 288 | #ifdef CONFIG_CMDLINE_BOOL |
@@ -487,7 +462,7 @@ void __init setup_arch(char **cmdline_p) | |||
487 | #ifdef CONFIG_BLK_DEV_INITRD | 462 | #ifdef CONFIG_BLK_DEV_INITRD |
488 | if (initrd_start < initrd_end) { | 463 | if (initrd_start < initrd_end) { |
489 | initrd_is_mapped = mem_reserve(__pa(initrd_start), | 464 | initrd_is_mapped = mem_reserve(__pa(initrd_start), |
490 | __pa(initrd_end), 0); | 465 | __pa(initrd_end), 0) == 0; |
491 | initrd_below_start_ok = 1; | 466 | initrd_below_start_ok = 1; |
492 | } else { | 467 | } else { |
493 | initrd_start = 0; | 468 | initrd_start = 0; |
@@ -532,6 +507,7 @@ void __init setup_arch(char **cmdline_p) | |||
532 | __pa(&_Level6InterruptVector_text_end), 0); | 507 | __pa(&_Level6InterruptVector_text_end), 0); |
533 | #endif | 508 | #endif |
534 | 509 | ||
510 | parse_early_param(); | ||
535 | bootmem_init(); | 511 | bootmem_init(); |
536 | 512 | ||
537 | unflatten_and_copy_device_tree(); | 513 | unflatten_and_copy_device_tree(); |
diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index aa8bd8717927..40b5a3771fb0 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c | |||
@@ -496,6 +496,21 @@ void flush_tlb_range(struct vm_area_struct *vma, | |||
496 | on_each_cpu(ipi_flush_tlb_range, &fd, 1); | 496 | on_each_cpu(ipi_flush_tlb_range, &fd, 1); |
497 | } | 497 | } |
498 | 498 | ||
499 | static void ipi_flush_tlb_kernel_range(void *arg) | ||
500 | { | ||
501 | struct flush_data *fd = arg; | ||
502 | local_flush_tlb_kernel_range(fd->addr1, fd->addr2); | ||
503 | } | ||
504 | |||
505 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
506 | { | ||
507 | struct flush_data fd = { | ||
508 | .addr1 = start, | ||
509 | .addr2 = end, | ||
510 | }; | ||
511 | on_each_cpu(ipi_flush_tlb_kernel_range, &fd, 1); | ||
512 | } | ||
513 | |||
499 | /* Cache flush functions */ | 514 | /* Cache flush functions */ |
500 | 515 | ||
501 | static void ipi_flush_cache_all(void *arg) | 516 | static void ipi_flush_cache_all(void *arg) |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 80b33ed51f31..4d2872fd9bb5 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/in6.h> | 20 | #include <linux/in6.h> |
21 | 21 | ||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/cacheflush.h> | ||
23 | #include <asm/checksum.h> | 24 | #include <asm/checksum.h> |
24 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
@@ -105,6 +106,7 @@ EXPORT_SYMBOL(csum_partial_copy_generic); | |||
105 | * Architecture-specific symbols | 106 | * Architecture-specific symbols |
106 | */ | 107 | */ |
107 | EXPORT_SYMBOL(__xtensa_copy_user); | 108 | EXPORT_SYMBOL(__xtensa_copy_user); |
109 | EXPORT_SYMBOL(__invalidate_icache_range); | ||
108 | 110 | ||
109 | /* | 111 | /* |
110 | * Kernel hacking ... | 112 | * Kernel hacking ... |
@@ -127,3 +129,8 @@ EXPORT_SYMBOL(common_exception_return); | |||
127 | #ifdef CONFIG_FUNCTION_TRACER | 129 | #ifdef CONFIG_FUNCTION_TRACER |
128 | EXPORT_SYMBOL(_mcount); | 130 | EXPORT_SYMBOL(_mcount); |
129 | #endif | 131 | #endif |
132 | |||
133 | EXPORT_SYMBOL(__invalidate_dcache_range); | ||
134 | #if XCHAL_DCACHE_IS_WRITEBACK | ||
135 | EXPORT_SYMBOL(__flush_dcache_range); | ||
136 | #endif | ||
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index f0b646d2f843..f54f78e24d7b 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile | |||
@@ -4,3 +4,4 @@ | |||
4 | 4 | ||
5 | obj-y := init.o cache.o misc.o | 5 | obj-y := init.o cache.o misc.o |
6 | obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o | 6 | obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o |
7 | obj-$(CONFIG_HIGHMEM) += highmem.o | ||
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index ba4c47f291b1..63cbb867dadd 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c | |||
@@ -59,6 +59,10 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) | ||
63 | #error "HIGHMEM is not supported on cores with aliasing cache." | ||
64 | #endif | ||
65 | |||
62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 66 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
63 | 67 | ||
64 | /* | 68 | /* |
@@ -179,10 +183,11 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
179 | #else | 183 | #else |
180 | if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) | 184 | if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) |
181 | && (vma->vm_flags & VM_EXEC) != 0) { | 185 | && (vma->vm_flags & VM_EXEC) != 0) { |
182 | unsigned long paddr = (unsigned long) page_address(page); | 186 | unsigned long paddr = (unsigned long)kmap_atomic(page); |
183 | __flush_dcache_page(paddr); | 187 | __flush_dcache_page(paddr); |
184 | __invalidate_icache_page(paddr); | 188 | __invalidate_icache_page(paddr); |
185 | set_bit(PG_arch_1, &page->flags); | 189 | set_bit(PG_arch_1, &page->flags); |
190 | kunmap_atomic((void *)paddr); | ||
186 | } | 191 | } |
187 | #endif | 192 | #endif |
188 | } | 193 | } |
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c new file mode 100644 index 000000000000..17a8c0d6fd17 --- /dev/null +++ b/arch/xtensa/mm/highmem.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * High memory support for Xtensa architecture | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General | ||
5 | * Public License. See the file "COPYING" in the main directory of | ||
6 | * this archive for more details. | ||
7 | * | ||
8 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | ||
10 | |||
11 | #include <linux/export.h> | ||
12 | #include <linux/highmem.h> | ||
13 | #include <asm/tlbflush.h> | ||
14 | |||
15 | static pte_t *kmap_pte; | ||
16 | |||
17 | void *kmap_atomic(struct page *page) | ||
18 | { | ||
19 | enum fixed_addresses idx; | ||
20 | unsigned long vaddr; | ||
21 | int type; | ||
22 | |||
23 | pagefault_disable(); | ||
24 | if (!PageHighMem(page)) | ||
25 | return page_address(page); | ||
26 | |||
27 | type = kmap_atomic_idx_push(); | ||
28 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
29 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
30 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
31 | BUG_ON(!pte_none(*(kmap_pte - idx))); | ||
32 | #endif | ||
33 | set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); | ||
34 | |||
35 | return (void *)vaddr; | ||
36 | } | ||
37 | EXPORT_SYMBOL(kmap_atomic); | ||
38 | |||
39 | void __kunmap_atomic(void *kvaddr) | ||
40 | { | ||
41 | int idx, type; | ||
42 | |||
43 | if (kvaddr >= (void *)FIXADDR_START && | ||
44 | kvaddr < (void *)FIXADDR_TOP) { | ||
45 | type = kmap_atomic_idx(); | ||
46 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
47 | |||
48 | /* | ||
49 | * Force other mappings to Oops if they'll try to access this | ||
50 | * pte without first remap it. Keeping stale mappings around | ||
51 | * is a bad idea also, in case the page changes cacheability | ||
52 | * attributes or becomes a protected page in a hypervisor. | ||
53 | */ | ||
54 | pte_clear(&init_mm, kvaddr, kmap_pte - idx); | ||
55 | local_flush_tlb_kernel_range((unsigned long)kvaddr, | ||
56 | (unsigned long)kvaddr + PAGE_SIZE); | ||
57 | |||
58 | kmap_atomic_idx_pop(); | ||
59 | } | ||
60 | |||
61 | pagefault_enable(); | ||
62 | } | ||
63 | EXPORT_SYMBOL(__kunmap_atomic); | ||
64 | |||
65 | void __init kmap_init(void) | ||
66 | { | ||
67 | unsigned long kmap_vstart; | ||
68 | |||
69 | /* cache the first kmap pte */ | ||
70 | kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); | ||
71 | kmap_pte = kmap_get_fixmap_pte(kmap_vstart); | ||
72 | } | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index aff108df92d3..4224256bb215 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2005 Tensilica Inc. |
11 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
11 | * | 12 | * |
12 | * Chris Zankel <chris@zankel.net> | 13 | * Chris Zankel <chris@zankel.net> |
13 | * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> | 14 | * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> |
@@ -19,6 +20,7 @@ | |||
19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
20 | #include <linux/bootmem.h> | 21 | #include <linux/bootmem.h> |
21 | #include <linux/gfp.h> | 22 | #include <linux/gfp.h> |
23 | #include <linux/highmem.h> | ||
22 | #include <linux/swap.h> | 24 | #include <linux/swap.h> |
23 | #include <linux/mman.h> | 25 | #include <linux/mman.h> |
24 | #include <linux/nodemask.h> | 26 | #include <linux/nodemask.h> |
@@ -27,11 +29,133 @@ | |||
27 | #include <asm/bootparam.h> | 29 | #include <asm/bootparam.h> |
28 | #include <asm/page.h> | 30 | #include <asm/page.h> |
29 | #include <asm/sections.h> | 31 | #include <asm/sections.h> |
32 | #include <asm/sysmem.h> | ||
33 | |||
34 | struct sysmem_info sysmem __initdata; | ||
35 | |||
36 | static void __init sysmem_dump(void) | ||
37 | { | ||
38 | unsigned i; | ||
39 | |||
40 | pr_debug("Sysmem:\n"); | ||
41 | for (i = 0; i < sysmem.nr_banks; ++i) | ||
42 | pr_debug(" 0x%08lx - 0x%08lx (%ldK)\n", | ||
43 | sysmem.bank[i].start, sysmem.bank[i].end, | ||
44 | (sysmem.bank[i].end - sysmem.bank[i].start) >> 10); | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Find bank with maximal .start such that bank.start <= start | ||
49 | */ | ||
50 | static inline struct meminfo * __init find_bank(unsigned long start) | ||
51 | { | ||
52 | unsigned i; | ||
53 | struct meminfo *it = NULL; | ||
54 | |||
55 | for (i = 0; i < sysmem.nr_banks; ++i) | ||
56 | if (sysmem.bank[i].start <= start) | ||
57 | it = sysmem.bank + i; | ||
58 | else | ||
59 | break; | ||
60 | return it; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Move all memory banks starting at 'from' to a new place at 'to', | ||
65 | * adjust nr_banks accordingly. | ||
66 | * Both 'from' and 'to' must be inside the sysmem.bank. | ||
67 | * | ||
68 | * Returns: 0 (success), -ENOMEM (not enough space in the sysmem.bank). | ||
69 | */ | ||
70 | static int __init move_banks(struct meminfo *to, struct meminfo *from) | ||
71 | { | ||
72 | unsigned n = sysmem.nr_banks - (from - sysmem.bank); | ||
73 | |||
74 | if (to > from && to - from + sysmem.nr_banks > SYSMEM_BANKS_MAX) | ||
75 | return -ENOMEM; | ||
76 | if (to != from) | ||
77 | memmove(to, from, n * sizeof(struct meminfo)); | ||
78 | sysmem.nr_banks += to - from; | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Add new bank to sysmem. Resulting sysmem is the union of bytes of the | ||
84 | * original sysmem and the new bank. | ||
85 | * | ||
86 | * Returns: 0 (success), < 0 (error) | ||
87 | */ | ||
88 | int __init add_sysmem_bank(unsigned long start, unsigned long end) | ||
89 | { | ||
90 | unsigned i; | ||
91 | struct meminfo *it = NULL; | ||
92 | unsigned long sz; | ||
93 | unsigned long bank_sz = 0; | ||
94 | |||
95 | if (start == end || | ||
96 | (start < end) != (PAGE_ALIGN(start) < (end & PAGE_MASK))) { | ||
97 | pr_warn("Ignoring small memory bank 0x%08lx size: %ld bytes\n", | ||
98 | start, end - start); | ||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | start = PAGE_ALIGN(start); | ||
103 | end &= PAGE_MASK; | ||
104 | sz = end - start; | ||
105 | |||
106 | it = find_bank(start); | ||
107 | |||
108 | if (it) | ||
109 | bank_sz = it->end - it->start; | ||
110 | |||
111 | if (it && bank_sz >= start - it->start) { | ||
112 | if (end - it->start > bank_sz) | ||
113 | it->end = end; | ||
114 | else | ||
115 | return 0; | ||
116 | } else { | ||
117 | if (!it) | ||
118 | it = sysmem.bank; | ||
119 | else | ||
120 | ++it; | ||
121 | |||
122 | if (it - sysmem.bank < sysmem.nr_banks && | ||
123 | it->start - start <= sz) { | ||
124 | it->start = start; | ||
125 | if (it->end - it->start < sz) | ||
126 | it->end = end; | ||
127 | else | ||
128 | return 0; | ||
129 | } else { | ||
130 | if (move_banks(it + 1, it) < 0) { | ||
131 | pr_warn("Ignoring memory bank 0x%08lx size %ld bytes\n", | ||
132 | start, end - start); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | it->start = start; | ||
136 | it->end = end; | ||
137 | return 0; | ||
138 | } | ||
139 | } | ||
140 | sz = it->end - it->start; | ||
141 | for (i = it + 1 - sysmem.bank; i < sysmem.nr_banks; ++i) | ||
142 | if (sysmem.bank[i].start - it->start <= sz) { | ||
143 | if (sz < sysmem.bank[i].end - it->start) | ||
144 | it->end = sysmem.bank[i].end; | ||
145 | } else { | ||
146 | break; | ||
147 | } | ||
148 | |||
149 | move_banks(it + 1, sysmem.bank + i); | ||
150 | return 0; | ||
151 | } | ||
30 | 152 | ||
31 | /* | 153 | /* |
32 | * mem_reserve(start, end, must_exist) | 154 | * mem_reserve(start, end, must_exist) |
33 | * | 155 | * |
34 | * Reserve some memory from the memory pool. | 156 | * Reserve some memory from the memory pool. |
157 | * If must_exist is set and a part of the region being reserved does not exist | ||
158 | * memory map is not altered. | ||
35 | * | 159 | * |
36 | * Parameters: | 160 | * Parameters: |
37 | * start Start of region, | 161 | * start Start of region, |
@@ -39,53 +163,69 @@ | |||
39 | * must_exist Must exist in memory pool. | 163 | * must_exist Must exist in memory pool. |
40 | * | 164 | * |
41 | * Returns: | 165 | * Returns: |
42 | * 0 (memory area couldn't be mapped) | 166 | * 0 (success) |
43 | * -1 (success) | 167 | * < 0 (error) |
44 | */ | 168 | */ |
45 | 169 | ||
46 | int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) | 170 | int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) |
47 | { | 171 | { |
48 | int i; | 172 | struct meminfo *it; |
49 | 173 | struct meminfo *rm = NULL; | |
50 | if (start == end) | 174 | unsigned long sz; |
51 | return 0; | 175 | unsigned long bank_sz = 0; |
52 | 176 | ||
53 | start = start & PAGE_MASK; | 177 | start = start & PAGE_MASK; |
54 | end = PAGE_ALIGN(end); | 178 | end = PAGE_ALIGN(end); |
179 | sz = end - start; | ||
180 | if (!sz) | ||
181 | return -EINVAL; | ||
55 | 182 | ||
56 | for (i = 0; i < sysmem.nr_banks; i++) | 183 | it = find_bank(start); |
57 | if (start < sysmem.bank[i].end | 184 | |
58 | && end >= sysmem.bank[i].start) | 185 | if (it) |
59 | break; | 186 | bank_sz = it->end - it->start; |
60 | 187 | ||
61 | if (i == sysmem.nr_banks) { | 188 | if ((!it || end - it->start > bank_sz) && must_exist) { |
62 | if (must_exist) | 189 | pr_warn("mem_reserve: [0x%0lx, 0x%0lx) not in any region!\n", |
63 | printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) " | 190 | start, end); |
64 | "not in any region!\n", start, end); | 191 | return -EINVAL; |
65 | return 0; | ||
66 | } | 192 | } |
67 | 193 | ||
68 | if (start > sysmem.bank[i].start) { | 194 | if (it && start - it->start < bank_sz) { |
69 | if (end < sysmem.bank[i].end) { | 195 | if (start == it->start) { |
70 | /* split entry */ | 196 | if (end - it->start < bank_sz) { |
71 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) | 197 | it->start = end; |
72 | panic("meminfo overflow\n"); | 198 | return 0; |
73 | sysmem.bank[sysmem.nr_banks].start = end; | 199 | } else { |
74 | sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end; | 200 | rm = it; |
75 | sysmem.nr_banks++; | 201 | } |
202 | } else { | ||
203 | it->end = start; | ||
204 | if (end - it->start < bank_sz) | ||
205 | return add_sysmem_bank(end, | ||
206 | it->start + bank_sz); | ||
207 | ++it; | ||
76 | } | 208 | } |
77 | sysmem.bank[i].end = start; | 209 | } |
78 | 210 | ||
79 | } else if (end < sysmem.bank[i].end) { | 211 | if (!it) |
80 | sysmem.bank[i].start = end; | 212 | it = sysmem.bank; |
81 | 213 | ||
82 | } else { | 214 | for (; it < sysmem.bank + sysmem.nr_banks; ++it) { |
83 | /* remove entry */ | 215 | if (it->end - start <= sz) { |
84 | sysmem.nr_banks--; | 216 | if (!rm) |
85 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; | 217 | rm = it; |
86 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; | 218 | } else { |
219 | if (it->start - start < sz) | ||
220 | it->start = end; | ||
221 | break; | ||
222 | } | ||
87 | } | 223 | } |
88 | return -1; | 224 | |
225 | if (rm) | ||
226 | move_banks(rm, it); | ||
227 | |||
228 | return 0; | ||
89 | } | 229 | } |
90 | 230 | ||
91 | 231 | ||
@@ -99,6 +239,7 @@ void __init bootmem_init(void) | |||
99 | unsigned long bootmap_start, bootmap_size; | 239 | unsigned long bootmap_start, bootmap_size; |
100 | int i; | 240 | int i; |
101 | 241 | ||
242 | sysmem_dump(); | ||
102 | max_low_pfn = max_pfn = 0; | 243 | max_low_pfn = max_pfn = 0; |
103 | min_low_pfn = ~0; | 244 | min_low_pfn = ~0; |
104 | 245 | ||
@@ -156,19 +297,13 @@ void __init bootmem_init(void) | |||
156 | 297 | ||
157 | void __init zones_init(void) | 298 | void __init zones_init(void) |
158 | { | 299 | { |
159 | unsigned long zones_size[MAX_NR_ZONES]; | ||
160 | int i; | ||
161 | |||
162 | /* All pages are DMA-able, so we put them all in the DMA zone. */ | 300 | /* All pages are DMA-able, so we put them all in the DMA zone. */ |
163 | 301 | unsigned long zones_size[MAX_NR_ZONES] = { | |
164 | zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET; | 302 | [ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET, |
165 | for (i = 1; i < MAX_NR_ZONES; i++) | ||
166 | zones_size[i] = 0; | ||
167 | |||
168 | #ifdef CONFIG_HIGHMEM | 303 | #ifdef CONFIG_HIGHMEM |
169 | zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; | 304 | [ZONE_HIGHMEM] = max_pfn - max_low_pfn, |
170 | #endif | 305 | #endif |
171 | 306 | }; | |
172 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); | 307 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); |
173 | } | 308 | } |
174 | 309 | ||
@@ -178,16 +313,38 @@ void __init zones_init(void) | |||
178 | 313 | ||
179 | void __init mem_init(void) | 314 | void __init mem_init(void) |
180 | { | 315 | { |
181 | max_mapnr = max_low_pfn - ARCH_PFN_OFFSET; | ||
182 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | ||
183 | |||
184 | #ifdef CONFIG_HIGHMEM | 316 | #ifdef CONFIG_HIGHMEM |
185 | #error HIGHGMEM not implemented in init.c | 317 | unsigned long tmp; |
318 | |||
319 | reset_all_zones_managed_pages(); | ||
320 | for (tmp = max_low_pfn; tmp < max_pfn; tmp++) | ||
321 | free_highmem_page(pfn_to_page(tmp)); | ||
186 | #endif | 322 | #endif |
187 | 323 | ||
324 | max_mapnr = max_pfn - ARCH_PFN_OFFSET; | ||
325 | high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT); | ||
326 | |||
188 | free_all_bootmem(); | 327 | free_all_bootmem(); |
189 | 328 | ||
190 | mem_init_print_info(NULL); | 329 | mem_init_print_info(NULL); |
330 | pr_info("virtual kernel memory layout:\n" | ||
331 | #ifdef CONFIG_HIGHMEM | ||
332 | " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n" | ||
333 | " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" | ||
334 | #endif | ||
335 | " vmalloc : 0x%08x - 0x%08x (%5u MB)\n" | ||
336 | " lowmem : 0x%08x - 0x%08lx (%5lu MB)\n", | ||
337 | #ifdef CONFIG_HIGHMEM | ||
338 | PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, | ||
339 | (LAST_PKMAP*PAGE_SIZE) >> 10, | ||
340 | FIXADDR_START, FIXADDR_TOP, | ||
341 | (FIXADDR_TOP - FIXADDR_START) >> 10, | ||
342 | #endif | ||
343 | VMALLOC_START, VMALLOC_END, | ||
344 | (VMALLOC_END - VMALLOC_START) >> 20, | ||
345 | PAGE_OFFSET, PAGE_OFFSET + | ||
346 | (max_low_pfn - min_low_pfn) * PAGE_SIZE, | ||
347 | ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20); | ||
191 | } | 348 | } |
192 | 349 | ||
193 | #ifdef CONFIG_BLK_DEV_INITRD | 350 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -204,3 +361,53 @@ void free_initmem(void) | |||
204 | { | 361 | { |
205 | free_initmem_default(-1); | 362 | free_initmem_default(-1); |
206 | } | 363 | } |
364 | |||
365 | static void __init parse_memmap_one(char *p) | ||
366 | { | ||
367 | char *oldp; | ||
368 | unsigned long start_at, mem_size; | ||
369 | |||
370 | if (!p) | ||
371 | return; | ||
372 | |||
373 | oldp = p; | ||
374 | mem_size = memparse(p, &p); | ||
375 | if (p == oldp) | ||
376 | return; | ||
377 | |||
378 | switch (*p) { | ||
379 | case '@': | ||
380 | start_at = memparse(p + 1, &p); | ||
381 | add_sysmem_bank(start_at, start_at + mem_size); | ||
382 | break; | ||
383 | |||
384 | case '$': | ||
385 | start_at = memparse(p + 1, &p); | ||
386 | mem_reserve(start_at, start_at + mem_size, 0); | ||
387 | break; | ||
388 | |||
389 | case 0: | ||
390 | mem_reserve(mem_size, 0, 0); | ||
391 | break; | ||
392 | |||
393 | default: | ||
394 | pr_warn("Unrecognized memmap syntax: %s\n", p); | ||
395 | break; | ||
396 | } | ||
397 | } | ||
398 | |||
399 | static int __init parse_memmap_opt(char *str) | ||
400 | { | ||
401 | while (str) { | ||
402 | char *k = strchr(str, ','); | ||
403 | |||
404 | if (k) | ||
405 | *k++ = 0; | ||
406 | |||
407 | parse_memmap_one(str); | ||
408 | str = k; | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | early_param("memmap", parse_memmap_opt); | ||
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 861203e958da..3429b483d9f8 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Extracted from init.c | 4 | * Extracted from init.c |
5 | */ | 5 | */ |
6 | #include <linux/bootmem.h> | ||
6 | #include <linux/percpu.h> | 7 | #include <linux/percpu.h> |
7 | #include <linux/init.h> | 8 | #include <linux/init.h> |
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
@@ -16,9 +17,44 @@ | |||
16 | #include <asm/initialize_mmu.h> | 17 | #include <asm/initialize_mmu.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
18 | 19 | ||
20 | #if defined(CONFIG_HIGHMEM) | ||
21 | static void * __init init_pmd(unsigned long vaddr) | ||
22 | { | ||
23 | pgd_t *pgd = pgd_offset_k(vaddr); | ||
24 | pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
25 | |||
26 | if (pmd_none(*pmd)) { | ||
27 | unsigned i; | ||
28 | pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); | ||
29 | |||
30 | for (i = 0; i < 1024; i++) | ||
31 | pte_clear(NULL, 0, pte + i); | ||
32 | |||
33 | set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); | ||
34 | BUG_ON(pte != pte_offset_kernel(pmd, 0)); | ||
35 | pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", | ||
36 | __func__, vaddr, pmd, pte); | ||
37 | return pte; | ||
38 | } else { | ||
39 | return pte_offset_kernel(pmd, 0); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static void __init fixedrange_init(void) | ||
44 | { | ||
45 | BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); | ||
46 | init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); | ||
47 | } | ||
48 | #endif | ||
49 | |||
19 | void __init paging_init(void) | 50 | void __init paging_init(void) |
20 | { | 51 | { |
21 | memset(swapper_pg_dir, 0, PAGE_SIZE); | 52 | memset(swapper_pg_dir, 0, PAGE_SIZE); |
53 | #ifdef CONFIG_HIGHMEM | ||
54 | fixedrange_init(); | ||
55 | pkmap_page_table = init_pmd(PKMAP_BASE); | ||
56 | kmap_init(); | ||
57 | #endif | ||
22 | } | 58 | } |
23 | 59 | ||
24 | /* | 60 | /* |
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index ade623826788..5ece856c5725 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c | |||
@@ -149,6 +149,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
149 | local_irq_restore(flags); | 149 | local_irq_restore(flags); |
150 | } | 150 | } |
151 | 151 | ||
152 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
153 | { | ||
154 | if (end > start && start >= TASK_SIZE && end <= PAGE_OFFSET && | ||
155 | end - start < _TLB_ENTRIES << PAGE_SHIFT) { | ||
156 | start &= PAGE_MASK; | ||
157 | while (start < end) { | ||
158 | invalidate_itlb_mapping(start); | ||
159 | invalidate_dtlb_mapping(start); | ||
160 | start += PAGE_SIZE; | ||
161 | } | ||
162 | } else { | ||
163 | local_flush_tlb_all(); | ||
164 | } | ||
165 | } | ||
166 | |||
152 | #ifdef CONFIG_DEBUG_TLB_SANITY | 167 | #ifdef CONFIG_DEBUG_TLB_SANITY |
153 | 168 | ||
154 | static unsigned get_pte_for_vaddr(unsigned vaddr) | 169 | static unsigned get_pte_for_vaddr(unsigned vaddr) |
diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile index d2369b799c50..b3e89291cfba 100644 --- a/arch/xtensa/platforms/iss/Makefile +++ b/arch/xtensa/platforms/iss/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # "prom monitor" library routines under Linux. | 4 | # "prom monitor" library routines under Linux. |
5 | # | 5 | # |
6 | 6 | ||
7 | obj-y = console.o setup.o | 7 | obj-y = setup.o |
8 | obj-$(CONFIG_TTY) += console.o | ||
8 | obj-$(CONFIG_NET) += network.o | 9 | obj-$(CONFIG_NET) += network.o |
9 | obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o | 10 | obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o |
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c index f9bc87966290..b90555cb8089 100644 --- a/arch/xtensa/platforms/xt2000/setup.c +++ b/arch/xtensa/platforms/xt2000/setup.c | |||
@@ -92,18 +92,8 @@ void __init platform_setup(char** cmdline) | |||
92 | 92 | ||
93 | /* early initialization */ | 93 | /* early initialization */ |
94 | 94 | ||
95 | extern sysmem_info_t __initdata sysmem; | 95 | void __init platform_init(bp_tag_t *first) |
96 | |||
97 | void platform_init(bp_tag_t* first) | ||
98 | { | 96 | { |
99 | /* Set default memory block if not provided by the bootloader. */ | ||
100 | |||
101 | if (sysmem.nr_banks == 0) { | ||
102 | sysmem.nr_banks = 1; | ||
103 | sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; | ||
104 | sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START | ||
105 | + PLATFORM_DEFAULT_MEM_SIZE; | ||
106 | } | ||
107 | } | 97 | } |
108 | 98 | ||
109 | /* Heartbeat. Let the LED blink. */ | 99 | /* Heartbeat. Let the LED blink. */ |