mirror of https://github.com/torvalds/linux.git
powerpc updates for 6.19
- Restore clearing of MSR[RI] at interrupt/syscall exit on 32-bit. - Fix unpaired stwcx on interrupt exit on 32-bit. - Fix race condition leading to double list-add in mac_hid_toggle_emumouse(). - Fix mprotect on book3s 32-bit. - Fix SLB multihit issue during SLB preload with 64-bit hash MMU. - Add support for crashkernel CMA reservation. - Add die_id and die_cpumask for Power10 & later to expose chip hemispheres. - A series of minor fixes and improvements to the hash SLB code. Thanks to: Antonio Alvarez Feijoo, Ben Collins, Bhaskar Chowdhury, Christophe Leroy, Daniel Thompson, Dave Vasilevsky, Donet Tom, J. Neuschäfer, Kunwu Chan, Long Li, Naresh Kamboju, Nathan Chancellor, Ritesh Harjani (IBM), Shirisha G, Shrikanth Hegde, Sourabh Jain, Srikar Dronamraju, Stephen Rothwell, Thomas Zimmermann, Venkat Rao Bagalkote, Vishal Chourasia. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRjvi15rv0TSTaE+SIF0oADX8seIQUCaTFrpQAKCRAF0oADX8se IaVSAPwJazU+gxYwIe9mB7Mt9w1N04voW7LmX4tcj83i/Xd5QgEAsXfdpYeo3Tvb VPIOXVGVxOxAccyQ7Yw5QF4BPv+8FAc= =h6Ed -----END PGP SIGNATURE----- Merge tag 'powerpc-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc updates from Michael Ellerman: - Restore clearing of MSR[RI] at interrupt/syscall exit on 32-bit - Fix unpaired stwcx on interrupt exit on 32-bit - Fix race condition leading to double list-add in mac_hid_toggle_emumouse() - Fix mprotect on book3s 32-bit - Fix SLB multihit issue during SLB preload with 64-bit hash MMU - Add support for crashkernel CMA reservation - Add die_id and die_cpumask for Power10 & later to expose chip hemispheres - A series of minor fixes and improvements to the hash SLB code Thanks to Antonio Alvarez Feijoo, Ben Collins, Bhaskar Chowdhury, Christophe Leroy, Daniel Thompson, Dave Vasilevsky, Donet Tom, J. Neuschäfer, Kunwu Chan, Long Li, Naresh Kamboju, Nathan Chancellor, Ritesh Harjani (IBM), Shirisha G, Shrikanth Hegde, Sourabh Jain, Srikar Dronamraju, Stephen Rothwell, Thomas Zimmermann, Venkat Rao Bagalkote, and Vishal Chourasia. * tag 'powerpc-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (32 commits) macintosh/via-pmu-backlight: Include <linux/fb.h> and <linux/of.h> powerpc/powermac: backlight: Include <linux/of.h> powerpc/64s/slb: Add no_slb_preload early cmdline param powerpc/64s/slb: Make preload_add return type as void powerpc/ptdump: Dump PXX level info for kernel_page_tables powerpc/64s/pgtable: Enable directMap counters in meminfo for Hash powerpc/64s/hash: Update directMap page counters for Hash powerpc/64s/hash: Hash hpt_order should be only available with Hash MMU powerpc/64s/hash: Improve hash mmu printk messages powerpc/64s/hash: Fix phys_addr_t printf format in htab_initialize() powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE format powerpc/64s/hash: Restrict stress_hpt_struct memblock region to within RMA limit powerpc/64s/slb: Fix SLB multihit issue during SLB preload powerpc, mm: Fix mprotect on book3s 32-bit powerpc/smp: Expose die_id and die_cpumask powerpc/83xx: Add a null pointer check to mcu_gpiochip_add arch:powerpc:tools This file was missing shebang line, so added it kexec: Include kernel-end even without crashkernel powerpc: p2020: Rename wdt@ nodes to watchdog@ powerpc: 86xx: Rename wdt@ nodes to watchdog@ ...
This commit is contained in:
commit
ad952db4a8
|
|
@ -1111,7 +1111,7 @@ Kernel parameters
|
|||
It will be ignored when crashkernel=X,high is not used
|
||||
or memory reserved is below 4G.
|
||||
crashkernel=size[KMG],cma
|
||||
[KNL, X86] Reserve additional crash kernel memory from
|
||||
[KNL, X86, ppc] Reserve additional crash kernel memory from
|
||||
CMA. This reservation is usable by the first system's
|
||||
userspace memory and kernel movable allocations (memory
|
||||
balloon, zswap). Pages allocated from this memory range
|
||||
|
|
@ -7304,6 +7304,9 @@ Kernel parameters
|
|||
them frequently to increase the rate of SLB faults
|
||||
on kernel addresses.
|
||||
|
||||
no_slb_preload [PPC,EARLY]
|
||||
Disables slb preloading for userspace.
|
||||
|
||||
sunrpc.min_resvport=
|
||||
sunrpc.max_resvport=
|
||||
[NFS,SUNRPC]
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ static int e_class = ELFCLASS32;
|
|||
#define PUT_16BE(off, v)(buf[off] = ((v) >> 8) & 0xff, \
|
||||
buf[(off) + 1] = (v) & 0xff)
|
||||
#define PUT_32BE(off, v)(PUT_16BE((off), (v) >> 16L), PUT_16BE((off) + 2, (v)))
|
||||
#define PUT_64BE(off, v)((PUT_32BE((off), (v) >> 32L), \
|
||||
PUT_32BE((off) + 4, (v))))
|
||||
#define PUT_64BE(off, v)((PUT_32BE((off), (unsigned long long)(v) >> 32L), \
|
||||
PUT_32BE((off) + 4, (unsigned long long)(v))))
|
||||
|
||||
#define GET_16LE(off) ((buf[off]) + (buf[(off)+1] << 8))
|
||||
#define GET_32LE(off) (GET_16LE(off) + (GET_16LE((off)+2U) << 16U))
|
||||
|
|
@ -78,7 +78,8 @@ static int e_class = ELFCLASS32;
|
|||
#define PUT_16LE(off, v) (buf[off] = (v) & 0xff, \
|
||||
buf[(off) + 1] = ((v) >> 8) & 0xff)
|
||||
#define PUT_32LE(off, v) (PUT_16LE((off), (v)), PUT_16LE((off) + 2, (v) >> 16L))
|
||||
#define PUT_64LE(off, v) (PUT_32LE((off), (v)), PUT_32LE((off) + 4, (v) >> 32L))
|
||||
#define PUT_64LE(off, v) (PUT_32LE((off), (unsigned long long)(v)), \
|
||||
PUT_32LE((off) + 4, (unsigned long long)(v) >> 32L))
|
||||
|
||||
#define GET_16(off) (e_data == ELFDATA2MSB ? GET_16BE(off) : GET_16LE(off))
|
||||
#define GET_32(off) (e_data == ELFDATA2MSB ? GET_32BE(off) : GET_32LE(off))
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ soc8349@ff000000 {
|
|||
reg = <0xff000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ gef_gpio: gpio@4,400 {
|
|||
gpio-controller;
|
||||
};
|
||||
|
||||
wdt@4,800 {
|
||||
watchdog@4,800 {
|
||||
compatible = "ge,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x800 0x8>;
|
||||
|
|
@ -103,7 +103,7 @@ wdt@4,800 {
|
|||
};
|
||||
|
||||
/* Second watchdog available, driver currently supports one.
|
||||
wdt@4,808 {
|
||||
watchdog@4,808 {
|
||||
compatible = "gef,imp3a-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x808 0x8>;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fpga@4,0 {
|
|||
reg = <0x4 0x0 0x40>;
|
||||
};
|
||||
|
||||
wdt@4,2000 {
|
||||
watchdog@4,2000 {
|
||||
compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x2000 0x8>;
|
||||
|
|
@ -90,7 +90,7 @@ wdt@4,2000 {
|
|||
interrupt-parent = <&gef_pic>;
|
||||
};
|
||||
/* Second watchdog available, driver currently supports one.
|
||||
wdt@4,2010 {
|
||||
watchdog@4,2010 {
|
||||
compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x2010 0x8>;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ fpga@4,0 {
|
|||
reg = <0x4 0x0 0x40>;
|
||||
};
|
||||
|
||||
wdt@4,2000 {
|
||||
watchdog@4,2000 {
|
||||
compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x2000 0x8>;
|
||||
|
|
@ -87,7 +87,7 @@ wdt@4,2000 {
|
|||
interrupt-parent = <&gef_pic>;
|
||||
};
|
||||
/*
|
||||
wdt@4,2010 {
|
||||
watchdog@4,2010 {
|
||||
compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
|
||||
"gef,fpga-wdt";
|
||||
reg = <0x4 0x2010 0x8>;
|
||||
|
|
|
|||
|
|
@ -82,14 +82,14 @@ fpga@4,0 {
|
|||
reg = <0x4 0x0 0x40>;
|
||||
};
|
||||
|
||||
wdt@4,2000 {
|
||||
watchdog@4,2000 {
|
||||
compatible = "gef,fpga-wdt";
|
||||
reg = <0x4 0x2000 0x8>;
|
||||
interrupts = <0x1a 0x4>;
|
||||
interrupt-parent = <&gef_pic>;
|
||||
};
|
||||
/* Second watchdog available, driver currently supports one.
|
||||
wdt@4,2010 {
|
||||
watchdog@4,2010 {
|
||||
compatible = "gef,fpga-wdt";
|
||||
reg = <0x4 0x2010 0x8>;
|
||||
interrupts = <0x1b 0x4>;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ ipic: interrupt-controller@c00 {
|
|||
};
|
||||
|
||||
/* Watchdog timer */
|
||||
wdt@900 {
|
||||
watchdog@900 {
|
||||
compatible = "fsl,mpc5121-wdt";
|
||||
reg = <0x900 0x100>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ soc8313@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ immr@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ soc8323@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ soc8349@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>; // from bootloader
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ soc8349@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>; // from bootloader
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ soc@e0000000 {
|
|||
/* filled by u-boot */
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ immr@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ immr@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ immr@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ immr@e0000000 {
|
|||
reg = <0xe0000000 0x00000200>;
|
||||
bus-frequency = <0>;
|
||||
|
||||
wdt@200 {
|
||||
watchdog@200 {
|
||||
device_type = "watchdog";
|
||||
compatible = "mpc83xx_wdt";
|
||||
reg = <0x200 0x100>;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
# (default ./arch/powerpc/boot)
|
||||
# -W dir specify working directory for temporary files (default .)
|
||||
# -z use gzip (legacy)
|
||||
# -Z zsuffix compression to use (gz, xz or none)
|
||||
# -Z zsuffix compression to use (gz, xz, lzma, lzo or none)
|
||||
|
||||
# Stop execution if any command fails
|
||||
set -e
|
||||
|
|
@ -69,7 +69,7 @@ usage() {
|
|||
echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
|
||||
echo ' [-d devtree] [-s tree.dts] [-e esm_blob]' >&2
|
||||
echo ' [-c] [-C cross-prefix] [-D datadir] [-W workingdir]' >&2
|
||||
echo ' [-Z (gz|xz|none)] [--no-compression] [vmlinux]' >&2
|
||||
echo ' [-Z (gz|xz|lzma|lzo|none)] [--no-compression] [vmlinux]' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
void hash__flush_tlb_mm(struct mm_struct *mm);
|
||||
void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
|
||||
void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end);
|
||||
void hash__flush_gather(struct mmu_gather *tlb);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void _tlbie(unsigned long address);
|
||||
|
|
@ -29,7 +30,9 @@ void _tlbia(void);
|
|||
static inline void tlb_flush(struct mmu_gather *tlb)
|
||||
{
|
||||
/* 603 needs to flush the whole TLB here since it doesn't use a hash table. */
|
||||
if (!mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
hash__flush_gather(tlb);
|
||||
else
|
||||
_tlbia();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -524,7 +524,6 @@ void slb_save_contents(struct slb_entry *slb_ptr);
|
|||
void slb_dump_contents(struct slb_entry *slb_ptr);
|
||||
|
||||
extern void slb_vmalloc_update(void);
|
||||
void preload_new_slb_context(unsigned long start, unsigned long sp);
|
||||
|
||||
#ifdef CONFIG_PPC_64S_HASH_MMU
|
||||
void slb_set_size(u16 size);
|
||||
|
|
|
|||
|
|
@ -115,9 +115,11 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, struct crash_mem
|
|||
#ifdef CONFIG_CRASH_RESERVE
|
||||
int __init overlaps_crashkernel(unsigned long start, unsigned long size);
|
||||
extern void arch_reserve_crashkernel(void);
|
||||
extern void kdump_cma_reserve(void);
|
||||
#else
|
||||
static inline void arch_reserve_crashkernel(void) {}
|
||||
static inline int overlaps_crashkernel(unsigned long start, unsigned long size) { return 0; }
|
||||
static inline void kdump_cma_reserve(void) { }
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CRASH_DUMP)
|
||||
|
|
|
|||
|
|
@ -132,15 +132,18 @@ static inline int cpu_to_coregroup_id(int cpu)
|
|||
#include <asm/cputable.h>
|
||||
|
||||
struct cpumask *cpu_coregroup_mask(int cpu);
|
||||
const struct cpumask *cpu_die_mask(int cpu);
|
||||
int cpu_die_id(int cpu);
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define topology_physical_package_id(cpu) (cpu_to_chip_id(cpu))
|
||||
|
||||
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
|
||||
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
|
||||
#define topology_core_id(cpu) (cpu_to_core_id(cpu))
|
||||
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
|
||||
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
|
||||
#define topology_core_id(cpu) (cpu_to_core_id(cpu))
|
||||
#define topology_die_id(cpu) (cpu_die_id(cpu))
|
||||
#define topology_die_cpumask(cpu) (cpu_die_mask(cpu))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ SYM_FUNC_END(__kuep_unlock)
|
|||
.endm
|
||||
#endif
|
||||
|
||||
.macro clr_ri trash
|
||||
#ifndef CONFIG_BOOKE
|
||||
#ifdef CONFIG_PPC_8xx
|
||||
mtspr SPRN_NRI, \trash
|
||||
#else
|
||||
li \trash, MSR_KERNEL & ~MSR_RI
|
||||
mtmsr \trash
|
||||
#endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.globl transfer_to_syscall
|
||||
transfer_to_syscall:
|
||||
stw r3, ORIG_GPR3(r1)
|
||||
|
|
@ -149,6 +160,7 @@ ret_from_syscall:
|
|||
cmpwi r3,0
|
||||
REST_GPR(3, r1)
|
||||
syscall_exit_finish:
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r7
|
||||
mtspr SPRN_SRR1,r8
|
||||
|
||||
|
|
@ -168,6 +180,7 @@ syscall_exit_finish:
|
|||
REST_GPR(0, r1)
|
||||
REST_GPRS(3, 12, r1)
|
||||
b 1b
|
||||
_ASM_NOKPROBE_SYMBOL(syscall_exit_finish)
|
||||
|
||||
#ifdef CONFIG_44x
|
||||
.L44x_icache_flush:
|
||||
|
|
@ -216,7 +229,7 @@ fast_exception_return:
|
|||
beq 3f /* if not, we've got problems */
|
||||
#endif
|
||||
|
||||
2: lwz r10,_CCR(r11)
|
||||
lwz r10,_CCR(r11)
|
||||
REST_GPRS(1, 6, r11)
|
||||
mtcr r10
|
||||
lwz r10,_LINK(r11)
|
||||
|
|
@ -224,13 +237,11 @@ fast_exception_return:
|
|||
/* Clear the exception marker on the stack to avoid confusing stacktrace */
|
||||
li r10, 0
|
||||
stw r10, 8(r11)
|
||||
REST_GPR(10, r11)
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
|
||||
mtspr SPRN_NRI, r0
|
||||
#endif
|
||||
clr_ri r10
|
||||
mtspr SPRN_SRR1,r9
|
||||
mtspr SPRN_SRR0,r12
|
||||
REST_GPR(9, r11)
|
||||
REST_GPR(10, r11)
|
||||
REST_GPR(12, r11)
|
||||
REST_GPR(11, r11)
|
||||
rfi
|
||||
|
|
@ -259,14 +270,14 @@ interrupt_return:
|
|||
.Lfast_user_interrupt_return:
|
||||
lwz r11,_NIP(r1)
|
||||
lwz r12,_MSR(r1)
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r11
|
||||
mtspr SPRN_SRR1,r12
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
lwarx r0,0,r1
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
stwcx. r0,0,r1 /* to clear the reservation */
|
||||
FTR_SECTION_ELSE
|
||||
lwarx r0,0,r1
|
||||
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
|
||||
|
||||
lwz r3,_CCR(r1)
|
||||
lwz r4,_LINK(r1)
|
||||
|
|
@ -302,14 +313,14 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
|
|||
cmpwi cr1,r3,0
|
||||
lwz r11,_NIP(r1)
|
||||
lwz r12,_MSR(r1)
|
||||
clr_ri r4
|
||||
mtspr SPRN_SRR0,r11
|
||||
mtspr SPRN_SRR1,r12
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
lwarx r0,0,r1
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
stwcx. r0,0,r1 /* to clear the reservation */
|
||||
FTR_SECTION_ELSE
|
||||
lwarx r0,0,r1
|
||||
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
|
||||
|
||||
lwz r3,_LINK(r1)
|
||||
lwz r4,_CTR(r1)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static inline bool exit_must_hard_disable(void)
|
|||
#else
|
||||
static inline bool exit_must_hard_disable(void)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1897,8 +1897,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void preload_new_slb_context(unsigned long start, unsigned long sp);
|
||||
|
||||
/*
|
||||
* Set up a thread for executing a new program
|
||||
*/
|
||||
|
|
@ -1906,9 +1904,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
|||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled())
|
||||
preload_new_slb_context(start, sp);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/of_irq.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <asm/kexec.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/paca.h>
|
||||
#include <asm/processor.h>
|
||||
|
|
@ -995,11 +996,12 @@ void __init setup_arch(char **cmdline_p)
|
|||
initmem_init();
|
||||
|
||||
/*
|
||||
* Reserve large chunks of memory for use by CMA for fadump, KVM and
|
||||
* Reserve large chunks of memory for use by CMA for kdump, fadump, KVM and
|
||||
* hugetlb. These must be called after initmem_init(), so that
|
||||
* pageblock_order is initialised.
|
||||
*/
|
||||
fadump_cma_init();
|
||||
kdump_cma_reserve();
|
||||
kvm_cma_reserve();
|
||||
gigantic_hugetlb_cma_reserve();
|
||||
|
||||
|
|
|
|||
|
|
@ -1085,6 +1085,29 @@ static int __init init_big_cores(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* die_mask and die_id are only available on systems which support
|
||||
* multiple coregroups within a same package. On all other systems, die_mask
|
||||
* would be same as package mask and die_id would be set to -1.
|
||||
*/
|
||||
const struct cpumask *cpu_die_mask(int cpu)
|
||||
{
|
||||
if (has_coregroup_support())
|
||||
return per_cpu(cpu_coregroup_map, cpu);
|
||||
else
|
||||
return cpu_node_mask(cpu);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_die_mask);
|
||||
|
||||
int cpu_die_id(int cpu)
|
||||
{
|
||||
if (has_coregroup_support())
|
||||
return cpu_to_coregroup_id(cpu);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_die_id);
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
unsigned int cpu, num_threads;
|
||||
|
|
|
|||
|
|
@ -330,7 +330,6 @@ SECTIONS
|
|||
}
|
||||
.hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
|
||||
.gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) }
|
||||
.interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
|
||||
.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
|
||||
{
|
||||
__rela_dyn_start = .;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include <asm/setup.h>
|
||||
#include <asm/firmware.h>
|
||||
|
||||
#define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG)
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
void machine_crash_shutdown(struct pt_regs *regs)
|
||||
{
|
||||
|
|
@ -59,6 +61,8 @@ void machine_kexec(struct kimage *image)
|
|||
|
||||
#ifdef CONFIG_CRASH_RESERVE
|
||||
|
||||
static unsigned long long crashk_cma_size;
|
||||
|
||||
static unsigned long long __init get_crash_base(unsigned long long crash_base)
|
||||
{
|
||||
|
||||
|
|
@ -110,7 +114,7 @@ void __init arch_reserve_crashkernel(void)
|
|||
|
||||
/* use common parsing */
|
||||
ret = parse_crashkernel(boot_command_line, total_mem_sz, &crash_size,
|
||||
&crash_base, NULL, NULL, NULL);
|
||||
&crash_base, NULL, &crashk_cma_size, NULL);
|
||||
|
||||
if (ret)
|
||||
return;
|
||||
|
|
@ -130,23 +134,22 @@ void __init arch_reserve_crashkernel(void)
|
|||
reserve_crashkernel_generic(crash_size, crash_base, 0, false);
|
||||
}
|
||||
|
||||
void __init kdump_cma_reserve(void)
|
||||
{
|
||||
if (crashk_cma_size)
|
||||
reserve_crashkernel_cma(crashk_cma_size);
|
||||
}
|
||||
|
||||
int __init overlaps_crashkernel(unsigned long start, unsigned long size)
|
||||
{
|
||||
return (start + size) > crashk_res.start && start <= crashk_res.end;
|
||||
}
|
||||
|
||||
/* Values we need to export to the second kernel via the device tree. */
|
||||
static phys_addr_t kernel_end;
|
||||
static phys_addr_t crashk_base;
|
||||
static phys_addr_t crashk_size;
|
||||
static unsigned long long mem_limit;
|
||||
|
||||
static struct property kernel_end_prop = {
|
||||
.name = "linux,kernel-end",
|
||||
.length = sizeof(phys_addr_t),
|
||||
.value = &kernel_end,
|
||||
};
|
||||
|
||||
static struct property crashk_base_prop = {
|
||||
.name = "linux,crashkernel-base",
|
||||
.length = sizeof(phys_addr_t),
|
||||
|
|
@ -165,8 +168,6 @@ static struct property memory_limit_prop = {
|
|||
.value = &mem_limit,
|
||||
};
|
||||
|
||||
#define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG)
|
||||
|
||||
static void __init export_crashk_values(struct device_node *node)
|
||||
{
|
||||
/* There might be existing crash kernel properties, but we can't
|
||||
|
|
@ -190,6 +191,15 @@ static void __init export_crashk_values(struct device_node *node)
|
|||
mem_limit = cpu_to_be_ulong(memory_limit);
|
||||
of_update_property(node, &memory_limit_prop);
|
||||
}
|
||||
#endif /* CONFIG_CRASH_RESERVE */
|
||||
|
||||
static phys_addr_t kernel_end;
|
||||
|
||||
static struct property kernel_end_prop = {
|
||||
.name = "linux,kernel-end",
|
||||
.length = sizeof(phys_addr_t),
|
||||
.value = &kernel_end,
|
||||
};
|
||||
|
||||
static int __init kexec_setup(void)
|
||||
{
|
||||
|
|
@ -200,16 +210,17 @@ static int __init kexec_setup(void)
|
|||
return -ENOENT;
|
||||
|
||||
/* remove any stale properties so ours can be found */
|
||||
of_remove_property(node, of_find_property(node, kernel_end_prop.name, NULL));
|
||||
of_remove_property(node, of_find_property(node, kernel_end_prop.name,
|
||||
NULL));
|
||||
|
||||
/* information needed by userspace when using default_machine_kexec */
|
||||
kernel_end = cpu_to_be_ulong(__pa(_end));
|
||||
of_add_property(node, &kernel_end_prop);
|
||||
|
||||
#ifdef CONFIG_CRASH_RESERVE
|
||||
export_crashk_values(node);
|
||||
|
||||
#endif
|
||||
of_node_put(node);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(kexec_setup);
|
||||
#endif /* CONFIG_CRASH_RESERVE */
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ int get_exclude_memory_ranges(struct crash_mem **mem_ranges)
|
|||
*/
|
||||
int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
||||
{
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* Early boot failure observed on guests when low memory (first memory
|
||||
|
|
@ -528,6 +528,13 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < crashk_cma_cnt; i++) {
|
||||
ret = add_mem_range(mem_ranges, crashk_cma_ranges[i].start,
|
||||
crashk_cma_ranges[i].end - crashk_cma_ranges[i].start + 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = add_rtas_mem_range(mem_ranges);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -546,6 +553,22 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
|||
#endif /* CONFIG_KEXEC_FILE */
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
static int crash_exclude_mem_range_guarded(struct crash_mem **mem_ranges,
|
||||
unsigned long long mstart,
|
||||
unsigned long long mend)
|
||||
{
|
||||
struct crash_mem *tmem = *mem_ranges;
|
||||
|
||||
/* Reallocate memory ranges if there is no space to split ranges */
|
||||
if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
|
||||
tmem = realloc_mem_ranges(mem_ranges);
|
||||
if (!tmem)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return crash_exclude_mem_range(tmem, mstart, mend);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_crash_memory_ranges - Get crash memory ranges. This list includes
|
||||
* first/crashing kernel's memory regions that
|
||||
|
|
@ -557,7 +580,6 @@ int get_usable_memory_ranges(struct crash_mem **mem_ranges)
|
|||
int get_crash_memory_ranges(struct crash_mem **mem_ranges)
|
||||
{
|
||||
phys_addr_t base, end;
|
||||
struct crash_mem *tmem;
|
||||
u64 i;
|
||||
int ret;
|
||||
|
||||
|
|
@ -582,19 +604,18 @@ int get_crash_memory_ranges(struct crash_mem **mem_ranges)
|
|||
sort_memory_ranges(*mem_ranges, true);
|
||||
}
|
||||
|
||||
/* Reallocate memory ranges if there is no space to split ranges */
|
||||
tmem = *mem_ranges;
|
||||
if (tmem && (tmem->nr_ranges == tmem->max_nr_ranges)) {
|
||||
tmem = realloc_mem_ranges(mem_ranges);
|
||||
if (!tmem)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Exclude crashkernel region */
|
||||
ret = crash_exclude_mem_range(tmem, crashk_res.start, crashk_res.end);
|
||||
ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_res.start, crashk_res.end);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < crashk_cma_cnt; ++i) {
|
||||
ret = crash_exclude_mem_range_guarded(mem_ranges, crashk_cma_ranges[i].start,
|
||||
crashk_cma_ranges[i].end);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: For now, stay in parity with kexec-tools but if RTAS/OPAL
|
||||
* regions are exported to save their context at the time of
|
||||
|
|
@ -697,8 +718,8 @@ int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size)
|
|||
* two half.
|
||||
*/
|
||||
else {
|
||||
size = mem_rngs->ranges[i].end - end + 1;
|
||||
mem_rngs->ranges[i].end = base - 1;
|
||||
size = mem_rngs->ranges[i].end - end;
|
||||
ret = add_mem_range(mem_ranges, end + 1, size);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
|
|||
flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1);
|
||||
}
|
||||
EXPORT_SYMBOL(hash__flush_tlb_page);
|
||||
|
||||
void hash__flush_gather(struct mmu_gather *tlb)
|
||||
{
|
||||
if (tlb->fullmm || tlb->need_flush_all)
|
||||
hash__flush_tlb_mm(tlb->mm);
|
||||
else
|
||||
hash__flush_range(tlb->mm, tlb->start, tlb->end);
|
||||
}
|
||||
EXPORT_SYMBOL(hash__flush_gather);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <asm/mmu.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/machdep.h>
|
||||
|
|
@ -449,6 +450,7 @@ static __init void hash_kfence_map_pool(void)
|
|||
{
|
||||
unsigned long kfence_pool_start, kfence_pool_end;
|
||||
unsigned long prot = pgprot_val(PAGE_KERNEL);
|
||||
unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift;
|
||||
|
||||
if (!kfence_pool)
|
||||
return;
|
||||
|
|
@ -459,6 +461,7 @@ static __init void hash_kfence_map_pool(void)
|
|||
BUG_ON(htab_bolt_mapping(kfence_pool_start, kfence_pool_end,
|
||||
kfence_pool, prot, mmu_linear_psize,
|
||||
mmu_kernel_ssize));
|
||||
update_page_count(mmu_linear_psize, KFENCE_POOL_SIZE >> pshift);
|
||||
memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
|
||||
}
|
||||
|
||||
|
|
@ -952,7 +955,7 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
|
|||
block_size = be64_to_cpu(addr_prop[1]);
|
||||
if (block_size != (16 * GB))
|
||||
return 0;
|
||||
printk(KERN_INFO "Huge page(16GB) memory: "
|
||||
pr_info("Huge page(16GB) memory: "
|
||||
"addr = 0x%lX size = 0x%lX pages = %d\n",
|
||||
phys_addr, block_size, expected_pages);
|
||||
if (phys_addr + block_size * expected_pages <= memblock_end_of_DRAM()) {
|
||||
|
|
@ -1135,7 +1138,7 @@ static void __init htab_init_page_sizes(void)
|
|||
mmu_vmemmap_psize = mmu_virtual_psize;
|
||||
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
|
||||
|
||||
printk(KERN_DEBUG "Page orders: linear mapping = %d, "
|
||||
pr_info("Page orders: linear mapping = %d, "
|
||||
"virtual = %d, io = %d"
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
", vmemmap = %d"
|
||||
|
|
@ -1234,6 +1237,7 @@ int hash__create_section_mapping(unsigned long start, unsigned long end,
|
|||
int nid, pgprot_t prot)
|
||||
{
|
||||
int rc;
|
||||
unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift;
|
||||
|
||||
if (end >= H_VMALLOC_START) {
|
||||
pr_warn("Outside the supported range\n");
|
||||
|
|
@ -1251,17 +1255,22 @@ int hash__create_section_mapping(unsigned long start, unsigned long end,
|
|||
mmu_kernel_ssize);
|
||||
BUG_ON(rc2 && (rc2 != -ENOENT));
|
||||
}
|
||||
update_page_count(mmu_linear_psize, (end - start) >> pshift);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hash__remove_section_mapping(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift;
|
||||
|
||||
int rc = htab_remove_mapping(start, end, mmu_linear_psize,
|
||||
mmu_kernel_ssize);
|
||||
|
||||
if (resize_hpt_for_hotplug(memblock_phys_mem_size()) == -ENOSPC)
|
||||
pr_warn("Hash collision while resizing HPT\n");
|
||||
|
||||
if (!rc)
|
||||
update_page_count(mmu_linear_psize, -((end - start) >> pshift));
|
||||
return rc;
|
||||
}
|
||||
#endif /* CONFIG_MEMORY_HOTPLUG */
|
||||
|
|
@ -1302,27 +1311,34 @@ static void __init htab_initialize(void)
|
|||
unsigned long table;
|
||||
unsigned long pteg_count;
|
||||
unsigned long prot;
|
||||
phys_addr_t base = 0, size = 0, end;
|
||||
phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE;
|
||||
u64 i;
|
||||
unsigned int pshift = mmu_psize_defs[mmu_linear_psize].shift;
|
||||
|
||||
DBG(" -> htab_initialize()\n");
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||
limit = ppc64_rma_size;
|
||||
|
||||
if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) {
|
||||
mmu_kernel_ssize = MMU_SEGSIZE_1T;
|
||||
mmu_highuser_ssize = MMU_SEGSIZE_1T;
|
||||
printk(KERN_INFO "Using 1TB segments\n");
|
||||
pr_info("Using 1TB segments\n");
|
||||
}
|
||||
|
||||
if (stress_slb_enabled)
|
||||
static_branch_enable(&stress_slb_key);
|
||||
|
||||
if (no_slb_preload)
|
||||
static_branch_enable(&no_slb_preload_key);
|
||||
|
||||
if (stress_hpt_enabled) {
|
||||
unsigned long tmp;
|
||||
static_branch_enable(&stress_hpt_key);
|
||||
// Too early to use nr_cpu_ids, so use NR_CPUS
|
||||
tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS,
|
||||
__alignof__(struct stress_hpt_struct),
|
||||
0, MEMBLOCK_ALLOC_ANYWHERE);
|
||||
MEMBLOCK_LOW_LIMIT, limit);
|
||||
memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS);
|
||||
stress_hpt_struct = __va(tmp);
|
||||
|
||||
|
|
@ -1356,11 +1372,10 @@ static void __init htab_initialize(void)
|
|||
mmu_hash_ops.hpte_clear_all();
|
||||
#endif
|
||||
} else {
|
||||
unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE;
|
||||
|
||||
table = memblock_phys_alloc_range(htab_size_bytes,
|
||||
htab_size_bytes,
|
||||
0, limit);
|
||||
MEMBLOCK_LOW_LIMIT, limit);
|
||||
if (!table)
|
||||
panic("ERROR: Failed to allocate %pa bytes below %pa\n",
|
||||
&htab_size_bytes, &limit);
|
||||
|
|
@ -1392,8 +1407,8 @@ static void __init htab_initialize(void)
|
|||
size = end - base;
|
||||
base = (unsigned long)__va(base);
|
||||
|
||||
DBG("creating mapping for region: %lx..%lx (prot: %lx)\n",
|
||||
base, size, prot);
|
||||
pr_debug("creating mapping for region: 0x%pa..0x%pa (prot: %lx)\n",
|
||||
&base, &size, prot);
|
||||
|
||||
if ((base + size) >= H_VMALLOC_START) {
|
||||
pr_warn("Outside the supported range\n");
|
||||
|
|
@ -1402,6 +1417,8 @@ static void __init htab_initialize(void)
|
|||
|
||||
BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
|
||||
prot, mmu_linear_psize, mmu_kernel_ssize));
|
||||
|
||||
update_page_count(mmu_linear_psize, size >> pshift);
|
||||
}
|
||||
hash_kfence_map_pool();
|
||||
memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
|
||||
|
|
@ -1423,6 +1440,8 @@ static void __init htab_initialize(void)
|
|||
BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
|
||||
__pa(tce_alloc_start), prot,
|
||||
mmu_linear_psize, mmu_kernel_ssize));
|
||||
update_page_count(mmu_linear_psize,
|
||||
(tce_alloc_end - tce_alloc_start) >> pshift);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1867,7 +1886,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,
|
|||
* in vmalloc space, so switch vmalloc
|
||||
* to 4k pages
|
||||
*/
|
||||
printk(KERN_ALERT "Reducing vmalloc segment "
|
||||
pr_alert("Reducing vmalloc segment "
|
||||
"to 4kB pages because of "
|
||||
"non-cacheable mapping\n");
|
||||
psize = mmu_vmalloc_psize = MMU_PAGE_4K;
|
||||
|
|
@ -2432,6 +2451,8 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n")
|
|||
|
||||
static int __init hash64_debugfs(void)
|
||||
{
|
||||
if (radix_enabled())
|
||||
return 0;
|
||||
debugfs_create_file("hpt_order", 0600, arch_debugfs_dir, NULL,
|
||||
&fops_hpt_order);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@ static inline bool stress_hpt(void)
|
|||
return static_branch_unlikely(&stress_hpt_key);
|
||||
}
|
||||
|
||||
void hpt_do_stress(unsigned long ea, unsigned long hpte_group);
|
||||
extern bool no_slb_preload;
|
||||
DECLARE_STATIC_KEY_FALSE(no_slb_preload_key);
|
||||
static inline bool slb_preload_disabled(void)
|
||||
{
|
||||
return static_branch_unlikely(&no_slb_preload_key);
|
||||
}
|
||||
|
||||
void slb_setup_new_exec(void);
|
||||
void hpt_do_stress(unsigned long ea, unsigned long hpte_group);
|
||||
|
||||
void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush);
|
||||
|
||||
|
|
|
|||
|
|
@ -150,8 +150,6 @@ static int hash__init_new_context(struct mm_struct *mm)
|
|||
void hash__setup_new_exec(void)
|
||||
{
|
||||
slice_setup_new_exec();
|
||||
|
||||
slb_setup_new_exec();
|
||||
}
|
||||
#else
|
||||
static inline int hash__init_new_context(struct mm_struct *mm)
|
||||
|
|
|
|||
|
|
@ -510,20 +510,21 @@ atomic_long_t direct_pages_count[MMU_PAGE_COUNT];
|
|||
|
||||
void arch_report_meminfo(struct seq_file *m)
|
||||
{
|
||||
/*
|
||||
* Hash maps the memory with one size mmu_linear_psize.
|
||||
* So don't bother to print these on hash
|
||||
*/
|
||||
if (!radix_enabled())
|
||||
return;
|
||||
seq_printf(m, "DirectMap4k: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_4K]) << 2);
|
||||
seq_printf(m, "DirectMap64k: %8lu kB\n",
|
||||
seq_printf(m, "DirectMap64k: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_64K]) << 6);
|
||||
seq_printf(m, "DirectMap2M: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_2M]) << 11);
|
||||
seq_printf(m, "DirectMap1G: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20);
|
||||
if (radix_enabled()) {
|
||||
seq_printf(m, "DirectMap2M: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_2M]) << 11);
|
||||
seq_printf(m, "DirectMap1G: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20);
|
||||
} else {
|
||||
seq_printf(m, "DirectMap16M: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_16M]) << 14);
|
||||
seq_printf(m, "DirectMap16G: %8lu kB\n",
|
||||
atomic_long_read(&direct_pages_count[MMU_PAGE_16G]) << 24);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,15 @@ early_param("stress_slb", parse_stress_slb);
|
|||
|
||||
__ro_after_init DEFINE_STATIC_KEY_FALSE(stress_slb_key);
|
||||
|
||||
bool no_slb_preload __initdata;
|
||||
static int __init parse_no_slb_preload(char *p)
|
||||
{
|
||||
no_slb_preload = true;
|
||||
return 0;
|
||||
}
|
||||
early_param("no_slb_preload", parse_no_slb_preload);
|
||||
__ro_after_init DEFINE_STATIC_KEY_FALSE(no_slb_preload_key);
|
||||
|
||||
static void assert_slb_presence(bool present, unsigned long ea)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_VM
|
||||
|
|
@ -294,11 +303,14 @@ static bool preload_hit(struct thread_info *ti, unsigned long esid)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool preload_add(struct thread_info *ti, unsigned long ea)
|
||||
static void preload_add(struct thread_info *ti, unsigned long ea)
|
||||
{
|
||||
unsigned char idx;
|
||||
unsigned long esid;
|
||||
|
||||
if (slb_preload_disabled())
|
||||
return;
|
||||
|
||||
if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) {
|
||||
/* EAs are stored >> 28 so 256MB segments don't need clearing */
|
||||
if (ea & ESID_MASK_1T)
|
||||
|
|
@ -308,7 +320,7 @@ static bool preload_add(struct thread_info *ti, unsigned long ea)
|
|||
esid = ea >> SID_SHIFT;
|
||||
|
||||
if (preload_hit(ti, esid))
|
||||
return false;
|
||||
return;
|
||||
|
||||
idx = (ti->slb_preload_tail + ti->slb_preload_nr) % SLB_PRELOAD_NR;
|
||||
ti->slb_preload_esid[idx] = esid;
|
||||
|
|
@ -316,8 +328,6 @@ static bool preload_add(struct thread_info *ti, unsigned long ea)
|
|||
ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR;
|
||||
else
|
||||
ti->slb_preload_nr++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void preload_age(struct thread_info *ti)
|
||||
|
|
@ -328,94 +338,6 @@ static void preload_age(struct thread_info *ti)
|
|||
ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR;
|
||||
}
|
||||
|
||||
void slb_setup_new_exec(void)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long exec = 0x10000000;
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
/*
|
||||
* preload cache can only be used to determine whether a SLB
|
||||
* entry exists if it does not start to overflow.
|
||||
*/
|
||||
if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR)
|
||||
return;
|
||||
|
||||
hard_irq_disable();
|
||||
|
||||
/*
|
||||
* We have no good place to clear the slb preload cache on exec,
|
||||
* flush_thread is about the earliest arch hook but that happens
|
||||
* after we switch to the mm and have already preloaded the SLBEs.
|
||||
*
|
||||
* For the most part that's probably okay to use entries from the
|
||||
* previous exec, they will age out if unused. It may turn out to
|
||||
* be an advantage to clear the cache before switching to it,
|
||||
* however.
|
||||
*/
|
||||
|
||||
/*
|
||||
* preload some userspace segments into the SLB.
|
||||
* Almost all 32 and 64bit PowerPC executables are linked at
|
||||
* 0x10000000 so it makes sense to preload this segment.
|
||||
*/
|
||||
if (!is_kernel_addr(exec)) {
|
||||
if (preload_add(ti, exec))
|
||||
slb_allocate_user(mm, exec);
|
||||
}
|
||||
|
||||
/* Libraries and mmaps. */
|
||||
if (!is_kernel_addr(mm->mmap_base)) {
|
||||
if (preload_add(ti, mm->mmap_base))
|
||||
slb_allocate_user(mm, mm->mmap_base);
|
||||
}
|
||||
|
||||
/* see switch_slb */
|
||||
asm volatile("isync" : : : "memory");
|
||||
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
void preload_new_slb_context(unsigned long start, unsigned long sp)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long heap = mm->start_brk;
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
/* see above */
|
||||
if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR)
|
||||
return;
|
||||
|
||||
hard_irq_disable();
|
||||
|
||||
/* Userspace entry address. */
|
||||
if (!is_kernel_addr(start)) {
|
||||
if (preload_add(ti, start))
|
||||
slb_allocate_user(mm, start);
|
||||
}
|
||||
|
||||
/* Top of stack, grows down. */
|
||||
if (!is_kernel_addr(sp)) {
|
||||
if (preload_add(ti, sp))
|
||||
slb_allocate_user(mm, sp);
|
||||
}
|
||||
|
||||
/* Bottom of heap, grows up. */
|
||||
if (heap && !is_kernel_addr(heap)) {
|
||||
if (preload_add(ti, heap))
|
||||
slb_allocate_user(mm, heap);
|
||||
}
|
||||
|
||||
/* see switch_slb */
|
||||
asm volatile("isync" : : : "memory");
|
||||
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void slb_cache_slbie_kernel(unsigned int index)
|
||||
{
|
||||
unsigned long slbie_data = get_paca()->slb_cache[index];
|
||||
|
|
@ -502,6 +424,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
|
|||
|
||||
copy_mm_to_paca(mm);
|
||||
|
||||
if (slb_preload_disabled())
|
||||
return;
|
||||
|
||||
/*
|
||||
* We gradually age out SLBs after a number of context switches to
|
||||
* reduce reload overhead of unused entries (like we do with FP/VEC
|
||||
|
|
|
|||
|
|
@ -71,18 +71,23 @@ static const struct flag_info flag_array[] = {
|
|||
|
||||
struct ptdump_pg_level pg_level[5] = {
|
||||
{ /* pgd */
|
||||
.name = "PGD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* p4d */
|
||||
.name = "P4D",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pud */
|
||||
.name = "PUD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pmd */
|
||||
.name = "PMD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pte */
|
||||
.name = "PTE",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -104,18 +104,23 @@ static const struct flag_info flag_array[] = {
|
|||
|
||||
struct ptdump_pg_level pg_level[5] = {
|
||||
{ /* pgd */
|
||||
.name = "PGD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* p4d */
|
||||
.name = "P4D",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pud */
|
||||
.name = "PUD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pmd */
|
||||
.name = "PMD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pte */
|
||||
.name = "PTE",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64
|
|||
vpn = hpt_vpn(ea, vsid, ssize);
|
||||
hash = hpt_hash(vpn, shift, ssize);
|
||||
want_v = hpte_encode_avpn(vpn, psize, ssize);
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_300))
|
||||
want_v = hpte_old_to_new_v(want_v);
|
||||
|
||||
/* to check in the secondary hash table, we invert the hash */
|
||||
if (!primary)
|
||||
|
|
@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64
|
|||
/* HPTE matches */
|
||||
*v = be64_to_cpu(hptep->v);
|
||||
*r = be64_to_cpu(hptep->r);
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
|
||||
*v = hpte_new_to_old_v(*v, *r);
|
||||
*r = hpte_new_to_old_r(*r);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
++hpte_group;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ static void dump_addr(struct pg_state *st, unsigned long addr)
|
|||
pt_dump_seq_printf(st->seq, REG "-" REG " ", st->start_address, addr - 1);
|
||||
pt_dump_seq_printf(st->seq, " " REG " ", st->start_pa);
|
||||
pt_dump_size(st->seq, addr - st->start_address);
|
||||
pt_dump_seq_printf(st->seq, "%s ", pg_level[st->level].name);
|
||||
}
|
||||
|
||||
static void note_prot_wx(struct pg_state *st, unsigned long addr)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ struct flag_info {
|
|||
|
||||
struct ptdump_pg_level {
|
||||
const struct flag_info *flag;
|
||||
char name[4];
|
||||
size_t num;
|
||||
u64 mask;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,18 +69,23 @@ static const struct flag_info flag_array[] = {
|
|||
|
||||
struct ptdump_pg_level pg_level[5] = {
|
||||
{ /* pgd */
|
||||
.name = "PGD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* p4d */
|
||||
.name = "P4D",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pud */
|
||||
.name = "PUD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pmd */
|
||||
.name = "PMD",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
}, { /* pte */
|
||||
.name = "PTE",
|
||||
.flag = flag_array,
|
||||
.num = ARRAY_SIZE(flag_array),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ static int mcu_gpiochip_add(struct mcu *mcu)
|
|||
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->label = kasprintf(GFP_KERNEL, "%pfw", dev_fwnode(dev));
|
||||
if (!gc->label)
|
||||
return -ENOMEM;
|
||||
gc->can_sleep = 1;
|
||||
gc->ngpio = MCU_NUM_GPIO;
|
||||
gc->base = -1;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/adb.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pmu.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/export.h>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ struct hvcall_ppp_data {
|
|||
u8 capped;
|
||||
u8 weight;
|
||||
u8 unallocated_weight;
|
||||
u8 resource_group_index;
|
||||
u16 active_procs_in_resource_group;
|
||||
u16 active_procs_in_pool;
|
||||
u16 active_system_procs;
|
||||
u16 phys_platform_procs;
|
||||
|
|
@ -86,7 +88,7 @@ struct hvcall_ppp_data {
|
|||
};
|
||||
|
||||
/*
|
||||
* H_GET_PPP hcall returns info in 4 parms.
|
||||
* H_GET_PPP hcall returns info in 5 parms.
|
||||
* entitled_capacity,unallocated_capacity,
|
||||
* aggregation, resource_capability).
|
||||
*
|
||||
|
|
@ -94,11 +96,11 @@ struct hvcall_ppp_data {
|
|||
* R5 = Unallocated Processor Capacity Percentage.
|
||||
* R6 (AABBCCDDEEFFGGHH).
|
||||
* XXXX - reserved (0)
|
||||
* XXXX - reserved (0)
|
||||
* XXXX - Active Cores in Resource Group
|
||||
* XXXX - Group Number
|
||||
* XXXX - Pool Number.
|
||||
* R7 (IIJJKKLLMMNNOOPP).
|
||||
* XX - reserved. (0)
|
||||
* XX - Resource group Number
|
||||
* XX - bit 0-6 reserved (0). bit 7 is Capped indicator.
|
||||
* XX - variable processor Capacity Weight
|
||||
* XX - Unallocated Variable Processor Capacity Weight.
|
||||
|
|
@ -120,9 +122,11 @@ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
|
|||
ppp_data->entitlement = retbuf[0];
|
||||
ppp_data->unallocated_entitlement = retbuf[1];
|
||||
|
||||
ppp_data->active_procs_in_resource_group = (retbuf[2] >> 4 * 8) & 0xffff;
|
||||
ppp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
|
||||
ppp_data->pool_num = retbuf[2] & 0xffff;
|
||||
|
||||
ppp_data->resource_group_index = (retbuf[3] >> 7 * 8) & 0xff;
|
||||
ppp_data->capped = (retbuf[3] >> 6 * 8) & 0x01;
|
||||
ppp_data->weight = (retbuf[3] >> 5 * 8) & 0xff;
|
||||
ppp_data->unallocated_weight = (retbuf[3] >> 4 * 8) & 0xff;
|
||||
|
|
@ -236,6 +240,13 @@ static void parse_ppp_data(struct seq_file *m)
|
|||
seq_printf(m, "unallocated_capacity=%lld\n",
|
||||
ppp_data.unallocated_entitlement);
|
||||
|
||||
if (ppp_data.active_procs_in_resource_group) {
|
||||
seq_printf(m, "resource_group_number=%d\n",
|
||||
ppp_data.resource_group_index);
|
||||
seq_printf(m, "resource_group_active_processors=%d\n",
|
||||
ppp_data.active_procs_in_resource_group);
|
||||
}
|
||||
|
||||
/* The last bits of information returned from h_get_ppp are only
|
||||
* valid if the ibm,partition-performance-parameters-level
|
||||
* property is >= 1.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#!/bin/sh
|
||||
# Copyright © 2016 IBM Corporation
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
|
|
|
|||
|
|
@ -187,13 +187,14 @@ static int mac_hid_toggle_emumouse(const struct ctl_table *table, int write,
|
|||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int *valp = table->data;
|
||||
int old_val = *valp;
|
||||
int old_val;
|
||||
int rc;
|
||||
|
||||
rc = mutex_lock_killable(&mac_hid_emumouse_mutex);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
old_val = *valp;
|
||||
rc = proc_dointvec(table, write, buffer, lenp, ppos);
|
||||
|
||||
if (rc == 0 && write && *valp != old_val) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include <asm/ptrace.h>
|
||||
#include <linux/adb.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pmu.h>
|
||||
#include <asm/backlight.h>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue