* [Bug 204479] KASAN hit at modprobe zram
From: bugzilla-daemon @ 2019-08-13 11:12 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204479-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204479
--- Comment #19 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284355
--> https://bugzilla.kernel.org/attachment.cgi?id=284355&action=edit
dmesg (kernel 5.3-rc4 + shadow patch + parallel patch, PowerMac G4 DP)
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [Bug 204479] KASAN hit at modprobe zram
From: bugzilla-daemon @ 2019-08-13 11:21 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204479-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204479
--- Comment #20 from Erhard F. (erhard_f@mailbox.org) ---
(In reply to Christophe Leroy from comment #18)
> Two possibilities, either the value in .rodata.cst16 is wrong or the stack
> gets corrupted.
>
> Maybe you could try disabling KASAN in lib/raid6/Makefile for altivec8.o ?
> Or maybe for the entire lib/raid6/ directory, just to see what happens ?
Disabled KASAN with KASAN_SANITIZE := n in lib/raid6/Makefile. As you can see
in my latest dmesg, the G4 continues booting without further issues.
If btrfs gets loaded it still fails with KASAN (will update bug #204397).
Another funny issue. Mounting my nfs share works via:
modprobe nfs
mount /media/distanthome
If I mount it without modprobing nfs beforehand I get:
[...]
[ 66.271748]
==================================================================
[ 66.272076] BUG: KASAN: global-out-of-bounds in _copy_to_iter+0x3d4/0x5a8
[ 66.272331] Write of size 4096 at addr f1c27000 by task modprobe/312
[ 66.272598] CPU: 0 PID: 312 Comm: modprobe Tainted: G W
5.3.0-rc4+ #1
[ 66.272883] Call Trace:
[ 66.272964] [e100b848] [c075026c] dump_stack+0xb0/0x10c (unreliable)
[ 66.273211] [e100b878] [c02334a8] print_address_description+0x80/0x45c
[ 66.273456] [e100b908] [c0233128] __kasan_report+0x140/0x188
[ 66.273667] [e100b948] [c0233fbc] check_memory_region+0x28/0x184
[ 66.273889] [e100b958] [c023206c] memcpy+0x48/0x74
[ 66.274061] [e100b978] [c044342c] _copy_to_iter+0x3d4/0x5a8
[ 66.274265] [e100baa8] [c04437a8] copy_page_to_iter+0x90/0x550
[ 66.274482] [e100bb08] [c01b6898] generic_file_read_iter+0x5c8/0x7bc
[ 66.274720] [e100bb78] [c0249034] __vfs_read+0x1b0/0x1f4
[ 66.274912] [e100bca8] [c0249134] vfs_read+0xbc/0x124
[ 66.275094] [e100bcd8] [c02491f0] kernel_read+0x54/0x70
[ 66.275284] [e100bd08] [c02535c8] kernel_read_file+0x240/0x358
[ 66.275499] [e100bdb8] [c02537cc] kernel_read_file_from_fd+0x54/0x74
[ 66.275737] [e100bdf8] [c01068ac] sys_finit_module+0xd8/0x140
[ 66.275949] [e100bf38] [c001a274] ret_from_syscall+0x0/0x34
[ 66.276152] --- interrupt: c01 at 0xa602c4
LR = 0xbe87c4
[ 66.276417] Memory state around the buggy address:
[ 66.276588] f1c27a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 66.276824] f1c27a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 66.277060] >f1c27b00: 00 00 00 00 00 00 00 00 05 fa fa fa fa fa fa fa
[ 66.277293] ^
[ 66.277453] f1c27b80: 07 fa fa fa fa fa fa fa 00 03 fa fa fa fa fa fa
[ 66.277688] f1c27c00: 04 fa fa fa fa fa fa fa 00 06 fa fa fa fa fa fa
[ 66.277920]
==================================================================
[ 66.428224] RPC: Registered named UNIX socket transport module.
[ 66.428484] RPC: Registered udp transport module.
[ 66.428647] RPC: Registered tcp transport module.
[ 66.428809] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 66.741275] Key type dns_resolver registered
[ 67.974192] NFS: Registering the id_resolver key type
[ 67.974534] Key type id_resolver registered
[ 67.974681] Key type id_legacy registered
But maybe it's better to not open too many ppc32 KASAN related bugs for now. ;)
It probably can wait until you patches are in some later 5.3-rc I guess.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [Bug 204479] KASAN hit at modprobe zram
From: bugzilla-daemon @ 2019-08-13 11:49 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204479-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204479
Erhard F. (erhard_f@mailbox.org) changed:
What |Removed |Added
----------------------------------------------------------------------------
Attachment #284271|0 |1
is obsolete| |
--- Comment #21 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284361
--> https://bugzilla.kernel.org/attachment.cgi?id=284361&action=edit
kernel .config (5.3-rc4, PowerMac G4 DP)
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* Re: [PATCH v2 2/3] KVM: PPC: Book3S HV: Don't push XIVE context when not using XIVE device
From: Cédric Le Goater @ 2019-08-13 12:18 UTC (permalink / raw)
To: Paul Mackerras, linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190813100100.GC9567@blackberry>
On 13/08/2019 12:01, Paul Mackerras wrote:
> At present, when running a guest on POWER9 using HV KVM but not using
> an in-kernel interrupt controller (XICS or XIVE), for example if QEMU
> is run with the kernel_irqchip=off option, the guest entry code goes
> ahead and tries to load the guest context into the XIVE hardware, even
> though no context has been set up.
>
> To fix this, we check that the "CAM word" is non-zero before pushing
> it to the hardware. The CAM word is initialized to a non-zero value
> in kvmppc_xive_connect_vcpu() and kvmppc_xive_native_connect_vcpu(),
> and is now cleared in kvmppc_xive_{,native_}cleanup_vcpu.
If a "CAM word" is defined, it means the vCPU (VP) was enabled at the
XIVE HW level. So this is the criteria to consider that a vCPU needs
to update (push) its XIVE thread interrupt context when scheduled
to run.
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Thanks,
C.
>
> Cc: stable@vger.kernel.org # v4.11+
> Reported-by: Cédric Le Goater <clg@kaod.org>
> Fixes: 5af50993850a ("KVM: PPC: Book3S HV: Native usage of the XIVE interrupt controller")
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
> ---
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 ++
> arch/powerpc/kvm/book3s_xive.c | 11 ++++++++++-
> arch/powerpc/kvm/book3s_xive_native.c | 3 +++
> 3 files changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index 2e7e788..07181d0 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -942,6 +942,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
> ld r11, VCPU_XIVE_SAVED_STATE(r4)
> li r9, TM_QW1_OS
> lwz r8, VCPU_XIVE_CAM_WORD(r4)
> + cmpwi r8, 0
> + beq no_xive
> li r7, TM_QW1_OS + TM_WORD2
> mfmsr r0
> andi. r0, r0, MSR_DR /* in real mode? */
> diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
> index 09f838a..586867e 100644
> --- a/arch/powerpc/kvm/book3s_xive.c
> +++ b/arch/powerpc/kvm/book3s_xive.c
> @@ -67,8 +67,14 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu)
> void __iomem *tima = local_paca->kvm_hstate.xive_tima_virt;
> u64 pq;
>
> - if (!tima)
> + /*
> + * Nothing to do if the platform doesn't have a XIVE
> + * or this vCPU doesn't have its own XIVE context
> + * (e.g. because it's not using an in-kernel interrupt controller).
> + */
> + if (!tima || !vcpu->arch.xive_cam_word)
> return;
> +
> eieio();
> __raw_writeq(vcpu->arch.xive_saved_state.w01, tima + TM_QW1_OS);
> __raw_writel(vcpu->arch.xive_cam_word, tima + TM_QW1_OS + TM_WORD2);
> @@ -1146,6 +1152,9 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
> /* Disable the VP */
> xive_native_disable_vp(xc->vp_id);
>
> + /* Clear the cam word so guest entry won't try to push context */
> + vcpu->arch.xive_cam_word = 0;
> +
> /* Free the queues */
> for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
> struct xive_q *q = &xc->queues[i];
> diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
> index 368427f..11b91b4 100644
> --- a/arch/powerpc/kvm/book3s_xive_native.c
> +++ b/arch/powerpc/kvm/book3s_xive_native.c
> @@ -81,6 +81,9 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
> /* Disable the VP */
> xive_native_disable_vp(xc->vp_id);
>
> + /* Clear the cam word so guest entry won't try to push context */
> + vcpu->arch.xive_cam_word = 0;
> +
> /* Free the queues */
> for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
> kvmppc_xive_native_cleanup_queue(vcpu, i);
>
^ permalink raw reply
* Re: [PATCH v4 12/25] powernv/fadump: define register/un-register callback functions
From: Mahesh J Salgaonkar @ 2019-08-13 14:34 UTC (permalink / raw)
To: Hari Bathini
Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Nicholas Piggin,
linuxppc-dev, Oliver, Vasant Hegde, Stewart Smith, Daniel Axtens
In-Reply-To: <156327680307.27462.16414477591782848444.stgit@hbathini.in.ibm.com>
On 2019-07-16 17:03:23 Tue, Hari Bathini wrote:
> Make OPAL calls to register and un-register with firmware for MPIPL.
>
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
> arch/powerpc/platforms/powernv/opal-fadump.c | 71 +++++++++++++++++++++++++-
> 1 file changed, 69 insertions(+), 2 deletions(-)
>
[...]
> @@ -88,12 +104,63 @@ static int opal_fadump_setup_kernel_metadata(struct fw_dump *fadump_conf)
>
> static int opal_fadump_register_fadump(struct fw_dump *fadump_conf)
> {
> - return -EIO;
> + int i, err = -EIO;
> + s64 rc;
> +
> + for (i = 0; i < opal_fdm->region_cnt; i++) {
> + rc = opal_mpipl_update(OPAL_MPIPL_ADD_RANGE,
> + opal_fdm->rgn[i].src,
> + opal_fdm->rgn[i].dest,
> + opal_fdm->rgn[i].size);
> + if (rc != OPAL_SUCCESS)
You may want to remove ranges which has been added so far on error and reset
opal_fdm->registered_regions.
> + break;
> +
> + opal_fdm->registered_regions++;
> + }
> +
> + switch (rc) {
> + case OPAL_SUCCESS:
> + pr_info("Registration is successful!\n");
> + fadump_conf->dump_registered = 1;
> + err = 0;
> + break;
> + case OPAL_UNSUPPORTED:
> + pr_err("Support not available.\n");
> + fadump_conf->fadump_supported = 0;
> + fadump_conf->fadump_enabled = 0;
> + break;
> + case OPAL_INTERNAL_ERROR:
> + pr_err("Failed to register. Hardware Error(%lld).\n", rc);
> + break;
> + case OPAL_PARAMETER:
> + pr_err("Failed to register. Parameter Error(%lld).\n", rc);
> + break;
> + case OPAL_PERMISSION:
You may want to remove this check. With latest opal mpipl patches
opal_mpipl_update() no more returns OPAL_PERMISSION.
Even if opal does, we can not say fadump already registered just by
looking at return status of single entry addition.
Thanks,
-Mahesh.
> + pr_err("Already registered!\n");
> + fadump_conf->dump_registered = 1;
> + err = -EEXIST;
> + break;
> + default:
> + pr_err("Failed to register. Unknown Error(%lld).\n", rc);
> + break;
> + }
> +
> + return err;
> }
^ permalink raw reply
* Re: [PATCH v4 13/25] powernv/fadump: support copying multiple kernel memory regions
From: Mahesh J Salgaonkar @ 2019-08-13 15:03 UTC (permalink / raw)
To: Hari Bathini
Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Nicholas Piggin,
linuxppc-dev, Oliver, Vasant Hegde, Stewart Smith, Daniel Axtens
In-Reply-To: <156327681058.27462.16887222537196117647.stgit@hbathini.in.ibm.com>
On 2019-07-16 17:03:30 Tue, Hari Bathini wrote:
> Firmware uses 32-bit field for region size while copying/backing-up
> memory during MPIPL. So, the maximum copy size for a region would
> be a page less than 4GB (aligned to pagesize) but FADump capture
> kernel usually needs more memory than that to be preserved to avoid
> running into out of memory errors.
>
> So, request firmware to copy multiple kernel memory regions instead
> of just one (which worked fine for pseries as 64-bit field was used
> for size there). With support to copy multiple kernel memory regions,
> also handle holes in the memory area to be preserved. Support as many
> as 128 kernel memory regions. This allows having an adequate FADump
> capture kernel size for different scenarios.
Can you split this patch into 2 ? One for handling holes in boot memory
and other for handling 4Gb region size ? So that it will be easy to
review changes.
Thanks,
-Mahesh.
>
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
> arch/powerpc/kernel/fadump-common.c | 15 ++
> arch/powerpc/kernel/fadump-common.h | 16 ++
> arch/powerpc/kernel/fadump.c | 173 ++++++++++++++++++++++----
> arch/powerpc/platforms/powernv/opal-fadump.c | 25 +++-
> arch/powerpc/platforms/powernv/opal-fadump.h | 5 -
> arch/powerpc/platforms/pseries/rtas-fadump.c | 12 ++
> arch/powerpc/platforms/pseries/rtas-fadump.h | 5 +
> 7 files changed, 211 insertions(+), 40 deletions(-)
>
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-13 15:38 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
Christophe Leroy (christophe.leroy@c-s.fr) changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |christophe.leroy@c-s.fr
--- Comment #16 from Christophe Leroy (christophe.leroy@c-s.fr) ---
Interesting.
I see in that commit that in fs/btrfs/free-space-cache.c, copy_page() is done
using entry->bitmap.
entry->bitmap is allocated with kmalloc() so there is a possibility that
entry->bitmap is not page aligned.
copy_page() in arch/powerpc/kernel/misc_32.S assumes that source and
destination are aligned on cache lines at least.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [REGRESSION] Boot failure with DEBUG_PAGEALLOC on Wii, after PPC32 KASAN patches
From: Jonathan Neuschäfer @ 2019-08-13 15:51 UTC (permalink / raw)
To: linuxppc-dev, Christophe Leroy
[-- Attachment #1: Type: text/plain, Size: 3112 bytes --]
Hi,
I noticed that my Nintendo Wii doesn't boot with wii_defconfig plus
CONFIG_DEBUG_PAGEALLOC=y and CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
on recent kernels. I get a splash like this one:
[ 0.022245] BUG: Unable to handle kernel data access at 0x00006601
[ 0.025172] Faulting instruction address: 0xc01afa48
[ 0.027522] Oops: Kernel access of bad area, sig: 11 [#1]
[ 0.030076] BE PAGE_SIZE=4K MMU=Hash PREEMPT DEBUG_PAGEALLOC wii
[ 0.032917] Modules linked in:
[ 0.034368] CPU: 0 PID: 0 Comm: swapper Not tainted 5.1.0-rc3-wii-00151-g9a634f40158a #1337
[ 0.038318] NIP: c01afa48 LR: c0195fd0 CTR: 00000000
[ 0.040707] REGS: c0c15e78 TRAP: 0300 Not tainted (5.1.0-rc3-wii-00151-g9a634f40158a)
[ 0.044531] MSR: 00009032 <EE,ME,IR,DR,RI> CR: 84000844 XER: 00000000
[ 0.047708] DAR: 00006601 DSISR: 40000000
[ 0.047708] GPR00: c0919998 c0c15f30 c0bad460 c0bad434 00000000 00000000 00000000 01010101
[ 0.047708] GPR08: 00000002 00000001 00000002 00000110 44000842 7b67efdb b3a9f2fa 7763f327
[ 0.047708] GPR16: f5bff97f 797ebc55 3aafa378 e76bacd3 af931fb0 00000000 013de444 00d009b0
[ 0.047708] GPR24: c0951504 c0c30000 d3efdcc0 c0951504 c0951500 00000000 c0878fe0 c0878fe0
[ 0.065470] NIP [c01afa48] fs_context_for_mount+0x8/0x1c
[ 0.067988] LR [c0195fd0] vfs_kern_mount.part.6+0x24/0xb0
[ 0.070540] Call Trace:
[ 0.071699] [c0c15f40] [c019404c] get_fs_type+0x98/0x14c
[ 0.074214] [c0c15f60] [c0919998] mnt_init+0x16c/0x264
[ 0.076645] [c0c15f90] [c0919594] vfs_caches_init+0x7c/0x94
[ 0.079283] [c0c15fb0] [c0900c34] start_kernel+0x41c/0x480
[ 0.081878] [c0c15ff0] [0000346c] 0x346c
[ 0.083731] Instruction dump:
[ 0.085135] 7d005028 31080001 7d00512d 40a2fff4 2f9a0000 419e000c 387a0054 48195e99
[ 0.088805] 935f000c 4bfffef4 9421fff0 7c852378 <80066601> 00725100 38800000 38210010
[ 0.092568] ---[ end trace 7373e1c0f977bdb3 ]---
[ 0.094750]
[ 1.083137] Kernel panic - not syncing: Attempted to kill the idle task!
(Without CONFIG_DEBUG_PAGEALLOC I haven't noticed any problems.)
'git bisect' says:
72f208c6a8f7bc78ef5248babd9e6ed6302bd2a0 is the first bad commit
commit 72f208c6a8f7bc78ef5248babd9e6ed6302bd2a0
Author: Christophe Leroy <christophe.leroy@c-s.fr>
Date: Fri Apr 26 16:23:35 2019 +0000
powerpc/32s: move hash code patching out of MMU_init_hw()
For KASAN, hash table handling will be activated early for
accessing to KASAN shadow areas.
In order to avoid any modification of the hash functions while
they are still used with the early hash table, the code patching
is moved out of MMU_init_hw() and put close to the big-bang switch
to the final hash table.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
I can revert this commit, and then 5.3-rc2 (plus a patchset adding a
serial driver) boot again.
Christophe, is there anything I should test in order to figure out how
to fix this properly?
Thanks,
Jonathan Neuschäfer
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [RFC PATCH] bpf: handle 32-bit zext during constant blinding
From: Naveen N. Rao @ 2019-08-13 17:10 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Jiong Wang
Cc: bpf, linuxppc-dev, linux-kernel, netdev
Since BPF constant blinding is performed after the verifier pass, there
are certain ALU32 instructions inserted which don't have a corresponding
zext instruction inserted after. This is causing a kernel oops on
powerpc and can be reproduced by running 'test_cgroup_storage' with
bpf_jit_harden=2.
Fix this by emitting BPF_ZEXT during constant blinding if
prog->aux->verifier_zext is set.
Fixes: a4b1d3c1ddf6cb ("bpf: verifier: insert zero extension according to analysis result")
Reported-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
This approach (the location where zext is being introduced below, in
particular) works for powerpc, but I am not entirely sure if this is
sufficient for other architectures as well. This is broken on v5.3-rc4.
- Naveen
kernel/bpf/core.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 8191a7db2777..d84146e6fd9e 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -890,7 +890,8 @@ int bpf_jit_get_func_addr(const struct bpf_prog *prog,
static int bpf_jit_blind_insn(const struct bpf_insn *from,
const struct bpf_insn *aux,
- struct bpf_insn *to_buff)
+ struct bpf_insn *to_buff,
+ bool emit_zext)
{
struct bpf_insn *to = to_buff;
u32 imm_rnd = get_random_int();
@@ -939,6 +940,8 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
*to++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ from->imm);
*to++ = BPF_ALU32_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
*to++ = BPF_ALU32_REG(from->code, from->dst_reg, BPF_REG_AX);
+ if (emit_zext)
+ *to++ = BPF_ZEXT_REG(from->dst_reg);
break;
case BPF_ALU64 | BPF_ADD | BPF_K:
@@ -992,6 +995,10 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
off -= 2;
*to++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ from->imm);
*to++ = BPF_ALU32_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
+ if (emit_zext) {
+ *to++ = BPF_ZEXT_REG(BPF_REG_AX);
+ off--;
+ }
*to++ = BPF_JMP32_REG(from->code, from->dst_reg, BPF_REG_AX,
off);
break;
@@ -1005,6 +1012,8 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
case 0: /* Part 2 of BPF_LD | BPF_IMM | BPF_DW. */
*to++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ aux[0].imm);
*to++ = BPF_ALU32_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
+ if (emit_zext)
+ *to++ = BPF_ZEXT_REG(BPF_REG_AX);
*to++ = BPF_ALU64_REG(BPF_OR, aux[0].dst_reg, BPF_REG_AX);
break;
@@ -1088,7 +1097,8 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
insn[1].code == 0)
memcpy(aux, insn, sizeof(aux));
- rewritten = bpf_jit_blind_insn(insn, aux, insn_buff);
+ rewritten = bpf_jit_blind_insn(insn, aux, insn_buff,
+ clone->aux->verifier_zext);
if (!rewritten)
continue;
--
2.22.0
^ permalink raw reply related
* Re: [PATCH v2 2/3] powerpc/rtas: allow rescheduling while changing cpu states
From: Gautham R Shenoy @ 2019-08-13 17:17 UTC (permalink / raw)
To: Nathan Lynch; +Cc: ego, linuxppc-dev
In-Reply-To: <20190802192926.19277-3-nathanl@linux.ibm.com>
On Sat, Aug 3, 2019 at 1:03 AM Nathan Lynch <nathanl@linux.ibm.com> wrote:
>
> rtas_cpu_state_change_mask() potentially operates on scores of cpus,
> so explicitly allow rescheduling in the loop body.
>
Are we seeing softlockups/rcu stalls while running this ?
> Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
> ---
> arch/powerpc/kernel/rtas.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 05824eb4323b..b7ca2fde68a9 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -16,6 +16,7 @@
> #include <linux/capability.h>
> #include <linux/delay.h>
> #include <linux/cpu.h>
> +#include <linux/sched.h>
> #include <linux/smp.h>
> #include <linux/completion.h>
> #include <linux/cpumask.h>
> @@ -898,6 +899,7 @@ static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> cpumask_clear_cpu(cpu, cpus);
> }
> }
> + cond_resched();
> }
>
> return ret;
> --
> 2.20.1
>
--
Thanks and Regards
gautham.
^ permalink raw reply
* Re: [PATCH v2 1/3] powerpc/rtas: use device model APIs and serialization during LPM
From: Gautham R Shenoy @ 2019-08-13 17:20 UTC (permalink / raw)
To: Nathan Lynch; +Cc: ego, linuxppc-dev
In-Reply-To: <20190802192926.19277-2-nathanl@linux.ibm.com>
Hello Nathan,
On Sat, Aug 3, 2019 at 1:06 AM Nathan Lynch <nathanl@linux.ibm.com> wrote:
>
> The LPAR migration implementation and userspace-initiated cpu hotplug
> can interleave their executions like so:
>
> 1. Set cpu 7 offline via sysfs.
>
> 2. Begin a partition migration, whose implementation requires the OS
> to ensure all present cpus are online; cpu 7 is onlined:
>
> rtas_ibm_suspend_me -> rtas_online_cpus_mask -> cpu_up
>
> This sets cpu 7 online in all respects except for the cpu's
> corresponding struct device; dev->offline remains true.
>
> 3. Set cpu 7 online via sysfs. _cpu_up() determines that cpu 7 is
> already online and returns success. The driver core (device_online)
> sets dev->offline = false.
>
> 4. The migration completes and restores cpu 7 to offline state:
>
> rtas_ibm_suspend_me -> rtas_offline_cpus_mask -> cpu_down
>
> This leaves cpu7 in a state where the driver core considers the cpu
> device online, but in all other respects it is offline and
> unused. Attempts to online the cpu via sysfs appear to succeed but the
> driver core actually does not pass the request to the lower-level
> cpuhp support code. This makes the cpu unusable until the cpu device
> is manually set offline and then online again via sysfs.
>
> Instead of directly calling cpu_up/cpu_down, the migration code should
> use the higher-level device core APIs to maintain consistent state and
> serialize operations.
>
> Fixes: 120496ac2d2d ("powerpc: Bring all threads online prior to migration/hibernation")
> Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
Looks good to me. This locking scheme makes the code consistent with
dlpar_cpu() which also uses the high-level device APIs.
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
> ---
> arch/powerpc/kernel/rtas.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 5faf0a64c92b..05824eb4323b 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -871,15 +871,17 @@ static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
> return 0;
>
> for_each_cpu(cpu, cpus) {
> + struct device *dev = get_cpu_device(cpu);
> +
> switch (state) {
> case DOWN:
> - cpuret = cpu_down(cpu);
> + cpuret = device_offline(dev);
> break;
> case UP:
> - cpuret = cpu_up(cpu);
> + cpuret = device_online(dev);
> break;
> }
> - if (cpuret) {
> + if (cpuret < 0) {
> pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
> __func__,
> ((state == UP) ? "up" : "down"),
> @@ -968,6 +970,8 @@ int rtas_ibm_suspend_me(u64 handle)
> data.token = rtas_token("ibm,suspend-me");
> data.complete = &done;
>
> + lock_device_hotplug();
> +
> /* All present CPUs must be online */
> cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
> cpuret = rtas_online_cpus_mask(offline_mask);
> @@ -1006,6 +1010,7 @@ int rtas_ibm_suspend_me(u64 handle)
> __func__);
>
> out:
> + unlock_device_hotplug();
> free_cpumask_var(offline_mask);
> return atomic_read(&data.error);
> }
> --
> 2.20.1
>
--
Thanks and Regards
gautham.
^ permalink raw reply
* Re: [PATCH v2 2/3] powerpc/rtas: allow rescheduling while changing cpu states
From: Nathan Lynch @ 2019-08-13 18:14 UTC (permalink / raw)
To: Gautham R Shenoy; +Cc: ego, linuxppc-dev
In-Reply-To: <CAHZ_5WyBjss+C2rY_zhr_BDFHEDNOq7-3T6um38uVj-Tj6jHtA@mail.gmail.com>
Gautham R Shenoy <ego.lkml@gmail.com> writes:
> On Sat, Aug 3, 2019 at 1:03 AM Nathan Lynch <nathanl@linux.ibm.com> wrote:
>>
>> rtas_cpu_state_change_mask() potentially operates on scores of cpus,
>> so explicitly allow rescheduling in the loop body.
>>
>
> Are we seeing softlockups/rcu stalls while running this ?
I have not seen a report yet, but since the loop is bound only by the
number of processors in the LPAR I suspect it's only a matter of time.
> Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Thanks!
^ permalink raw reply
* [PATCH v1 04/10] powerpc/mm: move ioremap_prot() into ioremap.c
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
Both ioremap_prot() are idenfical, move them into ioremap.c
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/ioremap.c | 19 +++++++++++++++++++
arch/powerpc/mm/pgtable_32.c | 17 -----------------
arch/powerpc/mm/pgtable_64.c | 24 ------------------------
3 files changed, 19 insertions(+), 41 deletions(-)
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 89479ee88344..a44d9e4c948a 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -50,3 +50,22 @@ void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
return iowa_ioremap(addr, size, prot, caller);
return __ioremap_caller(addr, size, prot, caller);
}
+
+void __iomem *ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+ pte_t pte = __pte(flags);
+ void *caller = __builtin_return_address(0);
+
+ /* writeable implies dirty for kernel addresses */
+ if (pte_write(pte))
+ pte = pte_mkdirty(pte);
+
+ /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
+ pte = pte_exprotect(pte);
+ pte = pte_mkprivileged(pte);
+
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, pte_pgprot(pte), caller);
+ return __ioremap_caller(addr, size, pte_pgprot(pte), caller);
+}
+EXPORT_SYMBOL(ioremap_prot);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 1999ec11706d..8126c2d1afbf 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -39,23 +39,6 @@ EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
extern char etext[], _stext[], _sinittext[], _einittext[];
void __iomem *
-ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
-{
- pte_t pte = __pte(flags);
-
- /* writeable implies dirty for kernel addresses */
- if (pte_write(pte))
- pte = pte_mkdirty(pte);
-
- /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
- pte = pte_exprotect(pte);
- pte = pte_mkprivileged(pte);
-
- return __ioremap_caller(addr, size, pte_pgprot(pte), __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap_prot);
-
-void __iomem *
__ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *caller)
{
unsigned long v, i;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 3ad921ac4862..6fa2e969bf0e 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -204,29 +204,6 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
return ret;
}
-void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
- unsigned long flags)
-{
- pte_t pte = __pte(flags);
- void *caller = __builtin_return_address(0);
-
- /* writeable implies dirty for kernel addresses */
- if (pte_write(pte))
- pte = pte_mkdirty(pte);
-
- /* we don't want to let _PAGE_EXEC leak out */
- pte = pte_exprotect(pte);
- /*
- * Force kernel mapping.
- */
- pte = pte_mkprivileged(pte);
-
- if (iowa_is_active())
- return iowa_ioremap(addr, size, pte_pgprot(pte), caller);
- return __ioremap_caller(addr, size, pte_pgprot(pte), caller);
-}
-
-
/*
* Unmap an IO region and remove it from imalloc'd list.
* Access to IO memory should be serialized by driver.
@@ -253,7 +230,6 @@ void iounmap(volatile void __iomem *token)
__iounmap(token);
}
-EXPORT_SYMBOL(ioremap_prot);
EXPORT_SYMBOL(__ioremap_at);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(__iounmap);
--
2.13.3
^ permalink raw reply related
* [PATCH v1 03/10] powerpc/mm: move common 32/64 bits ioremap functions into ioremap.c
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
ioremap(), __ioremap(), ioremap_wc() and ioremap_coherent() are
now identical on PPC32 and PPC64 as iowa_is_active() will always
return false on PPC32. Move them into a new common location called
ioremap.c
Allthough ioremap_wt() only exists on PPC32, move it into ioremap.c
as well. As it is the only one specific to PPC32, it is not worth
creating an ioremap_32.c file and leaving it in pgtable_32.c would
make it the only ioremap function in that file at the end of the
series.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/Makefile | 2 +-
arch/powerpc/mm/ioremap.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/pgtable_32.c | 43 ------------------------------------
arch/powerpc/mm/pgtable_64.c | 39 ---------------------------------
4 files changed, 53 insertions(+), 83 deletions(-)
create mode 100644 arch/powerpc/mm/ioremap.c
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 0f499db315d6..29c682fe9144 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -7,7 +7,7 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
obj-y := fault.o mem.o pgtable.o mmap.o \
init_$(BITS).o pgtable_$(BITS).o \
- pgtable-frag.o \
+ pgtable-frag.o ioremap.o \
init-common.o mmu_context.o drmem.o
obj-$(CONFIG_PPC_MMU_NOHASH) += nohash/
obj-$(CONFIG_PPC_BOOK3S_32) += book3s32/
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
new file mode 100644
index 000000000000..89479ee88344
--- /dev/null
+++ b/arch/powerpc/mm/ioremap.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/io.h>
+#include <asm/io-workarounds.h>
+
+void __iomem *__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+ return __ioremap_caller(addr, size, __pgprot(flags), __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__ioremap);
+
+void __iomem *ioremap(phys_addr_t addr, unsigned long size)
+{
+ pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
+ void *caller = __builtin_return_address(0);
+
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
+ return __ioremap_caller(addr, size, prot, caller);
+}
+EXPORT_SYMBOL(ioremap);
+
+void __iomem *ioremap_wc(phys_addr_t addr, unsigned long size)
+{
+ pgprot_t prot = pgprot_noncached_wc(PAGE_KERNEL);
+ void *caller = __builtin_return_address(0);
+
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
+ return __ioremap_caller(addr, size, prot, caller);
+}
+EXPORT_SYMBOL(ioremap_wc);
+
+#ifdef CONFIG_PPC32
+void __iomem *ioremap_wt(phys_addr_t addr, unsigned long size)
+{
+ pgprot_t prot = pgprot_cached_wthru(PAGE_KERNEL);
+
+ return __ioremap_caller(addr, size, prot, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_wt);
+#endif
+
+void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
+{
+ pgprot_t prot = pgprot_cached(PAGE_KERNEL);
+ void *caller = __builtin_return_address(0);
+
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
+ return __ioremap_caller(addr, size, prot, caller);
+}
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 35cb96cfc258..1999ec11706d 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -39,42 +39,6 @@ EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
extern char etext[], _stext[], _sinittext[], _einittext[];
void __iomem *
-ioremap(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
-
- return __ioremap_caller(addr, size, prot, __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap);
-
-void __iomem *
-ioremap_wc(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_noncached_wc(PAGE_KERNEL);
-
- return __ioremap_caller(addr, size, prot, __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap_wc);
-
-void __iomem *
-ioremap_wt(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_cached_wthru(PAGE_KERNEL);
-
- return __ioremap_caller(addr, size, prot, __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap_wt);
-
-void __iomem *
-ioremap_coherent(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_cached(PAGE_KERNEL);
-
- return __ioremap_caller(addr, size, prot, __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap_coherent);
-
-void __iomem *
ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
{
pte_t pte = __pte(flags);
@@ -92,12 +56,6 @@ ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
EXPORT_SYMBOL(ioremap_prot);
void __iomem *
-__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
-{
- return __ioremap_caller(addr, size, __pgprot(flags), __builtin_return_address(0));
-}
-
-void __iomem *
__ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *caller)
{
unsigned long v, i;
@@ -171,7 +129,6 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *call
out:
return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
}
-EXPORT_SYMBOL(__ioremap);
void iounmap(volatile void __iomem *addr)
{
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 194efc6f39fb..3ad921ac4862 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -204,42 +204,6 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
return ret;
}
-void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
- unsigned long flags)
-{
- return __ioremap_caller(addr, size, __pgprot(flags), __builtin_return_address(0));
-}
-
-void __iomem * ioremap(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
- void *caller = __builtin_return_address(0);
-
- if (iowa_is_active())
- return iowa_ioremap(addr, size, prot, caller);
- return __ioremap_caller(addr, size, prot, caller);
-}
-
-void __iomem * ioremap_wc(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_noncached_wc(PAGE_KERNEL);
- void *caller = __builtin_return_address(0);
-
- if (iowa_is_active())
- return iowa_ioremap(addr, size, prot, caller);
- return __ioremap_caller(addr, size, prot, caller);
-}
-
-void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
-{
- pgprot_t prot = pgprot_cached(PAGE_KERNEL);
- void *caller = __builtin_return_address(0);
-
- if (iowa_is_active())
- return iowa_ioremap(addr, size, prot, caller);
- return __ioremap_caller(addr, size, prot, caller);
-}
-
void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
unsigned long flags)
{
@@ -289,10 +253,7 @@ void iounmap(volatile void __iomem *token)
__iounmap(token);
}
-EXPORT_SYMBOL(ioremap);
-EXPORT_SYMBOL(ioremap_wc);
EXPORT_SYMBOL(ioremap_prot);
-EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(__ioremap_at);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(__iounmap);
--
2.13.3
^ permalink raw reply related
* [PATCH v1 01/10] powerpc/mm: drop ppc_md.iounmap()
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
ppc_md.iounmap() is never set, drop it.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/machdep.h | 2 --
arch/powerpc/mm/pgtable_64.c | 5 +----
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index c43d6eca9edd..3370df4bdaa0 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -33,8 +33,6 @@ struct machdep_calls {
#ifdef CONFIG_PPC64
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller);
- void (*iounmap)(volatile void __iomem *token);
-
#ifdef CONFIG_PM
void (*iommu_save)(void);
void (*iommu_restore)(void);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 9ad59b733984..11eb90ea2d4f 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -285,10 +285,7 @@ void __iounmap(volatile void __iomem *token)
void iounmap(volatile void __iomem *token)
{
- if (ppc_md.iounmap)
- ppc_md.iounmap(token);
- else
- __iounmap(token);
+ __iounmap(token);
}
EXPORT_SYMBOL(ioremap);
--
2.13.3
^ permalink raw reply related
* [PATCH v1 02/10] powerpc/mm: rework io-workaround invocation.
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
ppc_md.ioremap() is only used for I/O workaround on CELL platform,
so indirect function call can be avoided.
This patch reworks the io-workaround and ioremap() functions to
use static keys for the activation of io-workaround.
When CONFIG_PPC_IO_WORKAROUNDS or CONFIG_PPC_INDIRECT_MMIO are not
selected, the I/O workaround ioremap() voids and the static key is
not used at all.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/io-workarounds.h | 19 +++++++++++++++++++
arch/powerpc/include/asm/machdep.h | 2 --
arch/powerpc/kernel/io-workarounds.c | 11 ++++++-----
arch/powerpc/mm/pgtable_64.c | 17 +++++++++--------
4 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/io-workarounds.h b/arch/powerpc/include/asm/io-workarounds.h
index 01567ea4ceaf..ce337d17ac40 100644
--- a/arch/powerpc/include/asm/io-workarounds.h
+++ b/arch/powerpc/include/asm/io-workarounds.h
@@ -8,6 +8,7 @@
#ifndef _IO_WORKAROUNDS_H
#define _IO_WORKAROUNDS_H
+#ifdef CONFIG_PPC_IO_WORKAROUNDS
#include <linux/io.h>
#include <asm/pci-bridge.h>
@@ -32,4 +33,22 @@ extern int spiderpci_iowa_init(struct iowa_bus *, void *);
#define SPIDER_PCI_DUMMY_READ 0x0810
#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
+#endif
+
+#if defined(CONFIG_PPC_IO_WORKAROUNDS) && defined(CONFIG_PPC_INDIRECT_MMIO)
+DECLARE_STATIC_KEY_FALSE(iowa_key);
+static inline bool iowa_is_active(void)
+{
+ return static_branch_unlikely(&iowa_key);
+}
+#else
+static inline bool iowa_is_active(void)
+{
+ return false;
+}
+#endif
+
+void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
+ pgprot_t prot, void *caller);
+
#endif /* _IO_WORKAROUNDS_H */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 3370df4bdaa0..657ec893bdcb 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -31,8 +31,6 @@ struct pci_host_bridge;
struct machdep_calls {
char *name;
#ifdef CONFIG_PPC64
- void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
- pgprot_t prot, void *caller);
#ifdef CONFIG_PM
void (*iommu_save)(void);
void (*iommu_restore)(void);
diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c
index fbd2d0007c52..8b5b2aa70840 100644
--- a/arch/powerpc/kernel/io-workarounds.c
+++ b/arch/powerpc/kernel/io-workarounds.c
@@ -18,6 +18,7 @@
#include <asm/io-workarounds.h>
#include <asm/pte-walk.h>
+DEFINE_STATIC_KEY_FALSE(iowa_key);
#define IOWA_MAX_BUS 8
@@ -149,8 +150,8 @@ static const struct ppc_pci_io iowa_pci_io = {
};
#ifdef CONFIG_PPC_INDIRECT_MMIO
-static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
- pgprot_t prot, void *caller)
+void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
+ pgprot_t prot, void *caller)
{
struct iowa_bus *bus;
void __iomem *res = __ioremap_caller(addr, size, prot, caller);
@@ -163,8 +164,6 @@ static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
}
return res;
}
-#else /* CONFIG_PPC_INDIRECT_MMIO */
-#define iowa_ioremap NULL
#endif /* !CONFIG_PPC_INDIRECT_MMIO */
/* Enable IO workaround */
@@ -175,7 +174,9 @@ static void io_workaround_init(void)
if (io_workaround_inited)
return;
ppc_pci_io = iowa_pci_io;
- ppc_md.ioremap = iowa_ioremap;
+#ifdef CONFIG_PPC_INDIRECT_MMIO
+ static_branch_enable(&iowa_key);
+#endif
io_workaround_inited = 1;
}
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 11eb90ea2d4f..194efc6f39fb 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -35,6 +35,7 @@
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/io.h>
+#include <asm/io-workarounds.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
@@ -214,8 +215,8 @@ void __iomem * ioremap(phys_addr_t addr, unsigned long size)
pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
void *caller = __builtin_return_address(0);
- if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, prot, caller);
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
return __ioremap_caller(addr, size, prot, caller);
}
@@ -224,8 +225,8 @@ void __iomem * ioremap_wc(phys_addr_t addr, unsigned long size)
pgprot_t prot = pgprot_noncached_wc(PAGE_KERNEL);
void *caller = __builtin_return_address(0);
- if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, prot, caller);
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
return __ioremap_caller(addr, size, prot, caller);
}
@@ -234,8 +235,8 @@ void __iomem *ioremap_coherent(phys_addr_t addr, unsigned long size)
pgprot_t prot = pgprot_cached(PAGE_KERNEL);
void *caller = __builtin_return_address(0);
- if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, prot, caller);
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, prot, caller);
return __ioremap_caller(addr, size, prot, caller);
}
@@ -256,8 +257,8 @@ void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
*/
pte = pte_mkprivileged(pte);
- if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, pte_pgprot(pte), caller);
+ if (iowa_is_active())
+ return iowa_ioremap(addr, size, pte_pgprot(pte), caller);
return __ioremap_caller(addr, size, pte_pgprot(pte), caller);
}
--
2.13.3
^ permalink raw reply related
* [PATCH v1 05/10] powerpc/mm: Do early ioremaps from top to bottom on PPC64 too.
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
Until vmalloc system is up and running, ioremap basically
allocates addresses at the border of the IOREMAP area.
On PPC32, addresses are allocated down from the top of the area
while on PPC64, addresses are allocated up from the base of the
area.
On PPC32, the base of vmalloc area is not known yet when ioremap()
starts to be used, while the end of it is fixed. On PPC64, both the
start and the end are already fixed when ioremap() starts to being
used.
Changing PPC64 behaviour is the lighest change, so change PPC64
ioremap() to allocate addresses from the top as PPC32 does.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/book3s64/hash_utils.c | 2 +-
arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
arch/powerpc/mm/pgtable_64.c | 18 +++++++++---------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index e6d471058597..0f954dc40346 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1030,7 +1030,7 @@ void __init hash__early_init_mmu(void)
__kernel_io_start = H_KERN_IO_START;
__kernel_io_end = H_KERN_IO_END;
vmemmap = (struct page *)H_VMEMMAP_START;
- ioremap_bot = IOREMAP_BASE;
+ ioremap_bot = IOREMAP_END;
#ifdef CONFIG_PCI
pci_io_base = ISA_IO_BASE;
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index b4ca9e95e678..11303e2fffb1 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -611,7 +611,7 @@ void __init radix__early_init_mmu(void)
__kernel_io_start = RADIX_KERN_IO_START;
__kernel_io_end = RADIX_KERN_IO_END;
vmemmap = (struct page *)RADIX_VMEMMAP_START;
- ioremap_bot = IOREMAP_BASE;
+ ioremap_bot = IOREMAP_END;
#ifdef CONFIG_PCI
pci_io_base = ISA_IO_BASE;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 6fa2e969bf0e..0f0b1e1ea5ab 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -101,7 +101,7 @@ unsigned long __pte_frag_size_shift;
EXPORT_SYMBOL(__pte_frag_size_shift);
unsigned long ioremap_bot;
#else /* !CONFIG_PPC_BOOK3S_64 */
-unsigned long ioremap_bot = IOREMAP_BASE;
+unsigned long ioremap_bot = IOREMAP_END;
#endif
int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
@@ -169,11 +169,11 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
/*
* Choose an address to map it to.
- * Once the imalloc system is running, we use it.
+ * Once the vmalloc system is running, we use it.
* Before that, we map using addresses going
- * up from ioremap_bot. imalloc will use
- * the addresses from ioremap_bot through
- * IMALLOC_END
+ * down from ioremap_bot. vmalloc will use
+ * the addresses from IOREMAP_BASE through
+ * ioremap_bot
*
*/
paligned = addr & PAGE_MASK;
@@ -186,7 +186,7 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
struct vm_struct *area;
area = __get_vm_area_caller(size, VM_IOREMAP,
- ioremap_bot, IOREMAP_END,
+ IOREMAP_BASE, ioremap_bot,
caller);
if (area == NULL)
return NULL;
@@ -194,9 +194,9 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
area->phys_addr = paligned;
ret = __ioremap_at(paligned, area->addr, size, prot);
} else {
- ret = __ioremap_at(paligned, (void *)ioremap_bot, size, prot);
+ ret = __ioremap_at(paligned, (void *)ioremap_bot - size, size, prot);
if (ret)
- ioremap_bot += size;
+ ioremap_bot -= size;
}
if (ret)
@@ -217,7 +217,7 @@ void __iounmap(volatile void __iomem *token)
addr = (void *) ((unsigned long __force)
PCI_FIX_ADDR(token) & PAGE_MASK);
- if ((unsigned long)addr < ioremap_bot) {
+ if ((unsigned long)addr >= ioremap_bot) {
printk(KERN_WARNING "Attempt to iounmap early bolted mapping"
" at 0x%p\n", addr);
return;
--
2.13.3
^ permalink raw reply related
* [PATCH v1 06/10] powerpc/mm: make ioremap_bot common to all
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
Drop multiple definitions of ioremap_bot and make one common to
all subarches.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/book3s/32/pgtable.h | 2 --
arch/powerpc/include/asm/book3s/64/pgtable.h | 1 -
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 --
arch/powerpc/include/asm/pgtable.h | 2 ++
arch/powerpc/mm/ioremap.c | 3 +++
arch/powerpc/mm/mmu_decl.h | 1 -
arch/powerpc/mm/nohash/tlb.c | 2 ++
arch/powerpc/mm/pgtable_32.c | 3 ---
arch/powerpc/mm/pgtable_64.c | 3 ---
9 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 838de59f6754..aa1bc5f8da90 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -201,8 +201,6 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
#include <linux/sched.h>
#include <linux/threads.h>
-extern unsigned long ioremap_bot;
-
/* Bits to mask out from a PGD to get to the PUD page */
#define PGD_MASKED_BITS 0
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 8308f32e9782..11819e3c755e 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -289,7 +289,6 @@ extern unsigned long __kernel_io_end;
#define KERN_IO_END __kernel_io_end
extern struct page *vmemmap;
-extern unsigned long ioremap_bot;
extern unsigned long pci_io_base;
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 0284f8f5305f..7ce2a7c9fade 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -11,8 +11,6 @@
#include <asm/mmu.h> /* For sub-arch specific PPC_PIN_SIZE */
#include <asm/asm-405.h>
-extern unsigned long ioremap_bot;
-
#ifdef CONFIG_44x
extern int icache_44x_need_flush;
#endif
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index c58ba7963688..c54bb68c1354 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -68,6 +68,8 @@ extern pgd_t swapper_pg_dir[];
extern void paging_init(void);
+extern unsigned long ioremap_bot;
+
/*
* kern_addr_valid is intended to indicate whether an address is a valid
* kernel address. Most 32-bit archs define it as always true (like this)
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index a44d9e4c948a..0c23660522ca 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -3,6 +3,9 @@
#include <linux/io.h>
#include <asm/io-workarounds.h>
+unsigned long ioremap_bot;
+EXPORT_SYMBOL(ioremap_bot);
+
void __iomem *__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
{
return __ioremap_caller(addr, size, __pgprot(flags), __builtin_return_address(0));
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 32c1a191c28a..6ee64d5e2824 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -108,7 +108,6 @@ extern u8 early_hash[];
#endif /* CONFIG_PPC32 */
-extern unsigned long ioremap_bot;
extern unsigned long __max_low_memory;
extern phys_addr_t __initial_memory_limit_addr;
extern phys_addr_t total_memory;
diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
index d4acf6fa0596..350a54f70a37 100644
--- a/arch/powerpc/mm/nohash/tlb.c
+++ b/arch/powerpc/mm/nohash/tlb.c
@@ -704,6 +704,8 @@ static void __init early_init_mmu_global(void)
* for use by the TLB miss code
*/
linear_map_top = memblock_end_of_DRAM();
+
+ ioremap_bot = IOREMAP_END;
}
static void __init early_mmu_set_memory_limit(void)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 8126c2d1afbf..7efdb1dee19b 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -33,9 +33,6 @@
#include <mm/mmu_decl.h>
-unsigned long ioremap_bot;
-EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
-
extern char etext[], _stext[], _sinittext[], _einittext[];
void __iomem *
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 0f0b1e1ea5ab..d631659c8859 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -99,9 +99,6 @@ unsigned long __pte_frag_nr;
EXPORT_SYMBOL(__pte_frag_nr);
unsigned long __pte_frag_size_shift;
EXPORT_SYMBOL(__pte_frag_size_shift);
-unsigned long ioremap_bot;
-#else /* !CONFIG_PPC_BOOK3S_64 */
-unsigned long ioremap_bot = IOREMAP_END;
#endif
int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
--
2.13.3
^ permalink raw reply related
* [PATCH v1 07/10] powerpc/mm: move iounmap() into ioremap.c and drop __iounmap()
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
On PPC64 iounmap() does nothing else than calling __iounmap()
and is the only user of __iounmap().
__iounmap() is almost similar to PPC32 iounmap().
Lets define a common iounmap() and drop __iounmap().
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/book3s/32/pgtable.h | 2 ++
arch/powerpc/include/asm/io.h | 5 -----
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 ++
arch/powerpc/mm/ioremap.c | 31 ++++++++++++++++++++++++++++
arch/powerpc/mm/pgtable_32.c | 14 -------------
arch/powerpc/mm/pgtable_64.c | 28 -------------------------
6 files changed, 35 insertions(+), 47 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index aa1bc5f8da90..af34554d19e8 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -165,6 +165,8 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
#define IOREMAP_TOP KVIRT_TOP
#endif
+#define IOREMAP_BASE VMALLOC_START
+
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 16MB value just means that there will be a 64MB "hole" after the
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 23e5d5d16c7e..02d6256fe1ea 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -712,9 +712,6 @@ static inline void iosync(void)
* * __ioremap_caller is the same as above but takes an explicit caller
* reference rather than using __builtin_return_address(0)
*
- * * __iounmap, is the low level implementation used by iounmap and cannot
- * be hooked (but can be used by a hook on iounmap)
- *
*/
extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
@@ -734,8 +731,6 @@ extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
pgprot_t prot, void *caller);
-extern void __iounmap(volatile void __iomem *addr);
-
extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
unsigned long size, pgprot_t prot);
extern void __iounmap_at(void *ea, unsigned long size);
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 7ce2a7c9fade..09f2739ab556 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -93,6 +93,8 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
#define IOREMAP_TOP KVIRT_TOP
#endif
+#define IOREMAP_BASE VMALLOC_START
+
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 16MB value just means that there will be a 64MB "hole" after the
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 0c23660522ca..57d742509cec 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <asm/io-workarounds.h>
+#include <mm/mmu_decl.h>
unsigned long ioremap_bot;
EXPORT_SYMBOL(ioremap_bot);
@@ -72,3 +75,31 @@ void __iomem *ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long f
return __ioremap_caller(addr, size, pte_pgprot(pte), caller);
}
EXPORT_SYMBOL(ioremap_prot);
+
+/*
+ * Unmap an IO region and remove it from vmalloc'd list.
+ * Access to IO memory should be serialized by driver.
+ */
+void iounmap(volatile void __iomem *token)
+{
+ void *addr;
+
+ /*
+ * If mapped by BATs then there is nothing to do.
+ */
+ if (v_block_mapped((unsigned long)token))
+ return;
+
+ if (!slab_is_available())
+ return;
+
+ addr = (void *)((unsigned long __force)PCI_FIX_ADDR(token) & PAGE_MASK);
+ if (WARN_ON((unsigned long)addr < IOREMAP_BASE))
+ return;
+ if ((unsigned long)addr >= ioremap_bot) {
+ pr_warn("Attempt to %s early bolted mapping at 0x%p\n", __func__, addr);
+ return;
+ }
+ vunmap(addr);
+}
+EXPORT_SYMBOL(iounmap);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 7efdb1dee19b..4597f45e4dc6 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -110,20 +110,6 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *call
return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
}
-void iounmap(volatile void __iomem *addr)
-{
- /*
- * If mapped by BATs then there is nothing to do.
- * Calling vfree() generates a benign warning.
- */
- if (v_block_mapped((unsigned long)addr))
- return;
-
- if (addr > high_memory && (unsigned long) addr < ioremap_bot)
- vunmap((void *) (PAGE_MASK & (unsigned long)addr));
-}
-EXPORT_SYMBOL(iounmap);
-
static void __init *early_alloc_pgtable(unsigned long size)
{
void *ptr = memblock_alloc(size, size);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index d631659c8859..b50a53a0a42b 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -201,35 +201,7 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
return ret;
}
-/*
- * Unmap an IO region and remove it from imalloc'd list.
- * Access to IO memory should be serialized by driver.
- */
-void __iounmap(volatile void __iomem *token)
-{
- void *addr;
-
- if (!slab_is_available())
- return;
-
- addr = (void *) ((unsigned long __force)
- PCI_FIX_ADDR(token) & PAGE_MASK);
- if ((unsigned long)addr >= ioremap_bot) {
- printk(KERN_WARNING "Attempt to iounmap early bolted mapping"
- " at 0x%p\n", addr);
- return;
- }
- vunmap(addr);
-}
-
-void iounmap(volatile void __iomem *token)
-{
- __iounmap(token);
-}
-
EXPORT_SYMBOL(__ioremap_at);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__iounmap);
EXPORT_SYMBOL(__iounmap_at);
#ifndef __PAGETABLE_PUD_FOLDED
--
2.13.3
^ permalink raw reply related
* [PATCH v1 08/10] powerpc/mm: move __ioremap_at() and __iounmap_at() into ioremap.c
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
Allthough __ioremap_at() and __iounmap_at() are specific to PPC64,
lets move them into ioremap.c as it wouldn't be worth creating an
ioremap_64.c only for those functions.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/ioremap.c | 43 +++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/pgtable_64.c | 42 ------------------------------------------
2 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 57d742509cec..889ee656cf64 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -103,3 +103,46 @@ void iounmap(volatile void __iomem *token)
vunmap(addr);
}
EXPORT_SYMBOL(iounmap);
+
+#ifdef CONFIG_PPC64
+/**
+ * __ioremap_at - Low level function to establish the page tables
+ * for an IO mapping
+ */
+void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_t prot)
+{
+ /* We don't support the 4K PFN hack with ioremap */
+ if (pgprot_val(prot) & H_PAGE_4K_PFN)
+ return NULL;
+
+ if ((ea + size) >= (void *)IOREMAP_END) {
+ pr_warn("Outside the supported range\n");
+ return NULL;
+ }
+
+ WARN_ON(pa & ~PAGE_MASK);
+ WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
+ WARN_ON(size & ~PAGE_MASK);
+
+ if (ioremap_range((unsigned long)ea, pa, size, prot, NUMA_NO_NODE))
+ return NULL;
+
+ return (void __iomem *)ea;
+}
+EXPORT_SYMBOL(__ioremap_at);
+
+/**
+ * __iounmap_from - Low level function to tear down the page tables
+ * for an IO mapping. This is used for mappings that
+ * are manipulated manually, like partial unmapping of
+ * PCI IOs or ISA space.
+ */
+void __iounmap_at(void *ea, unsigned long size)
+{
+ WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
+ WARN_ON(size & ~PAGE_MASK);
+
+ unmap_kernel_range((unsigned long)ea, size);
+}
+EXPORT_SYMBOL(__iounmap_at);
+#endif
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index b50a53a0a42b..32220f7381d7 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -119,45 +119,6 @@ int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, p
return 0;
}
-/**
- * __ioremap_at - Low level function to establish the page tables
- * for an IO mapping
- */
-void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_t prot)
-{
- /* We don't support the 4K PFN hack with ioremap */
- if (pgprot_val(prot) & H_PAGE_4K_PFN)
- return NULL;
-
- if ((ea + size) >= (void *)IOREMAP_END) {
- pr_warn("Outside the supported range\n");
- return NULL;
- }
-
- WARN_ON(pa & ~PAGE_MASK);
- WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
- WARN_ON(size & ~PAGE_MASK);
-
- if (ioremap_range((unsigned long)ea, pa, size, prot, NUMA_NO_NODE))
- return NULL;
-
- return (void __iomem *)ea;
-}
-
-/**
- * __iounmap_from - Low level function to tear down the page tables
- * for an IO mapping. This is used for mappings that
- * are manipulated manually, like partial unmapping of
- * PCI IOs or ISA space.
- */
-void __iounmap_at(void *ea, unsigned long size)
-{
- WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
- WARN_ON(size & ~PAGE_MASK);
-
- unmap_kernel_range((unsigned long)ea, size);
-}
-
void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
pgprot_t prot, void *caller)
{
@@ -201,9 +162,6 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
return ret;
}
-EXPORT_SYMBOL(__ioremap_at);
-EXPORT_SYMBOL(__iounmap_at);
-
#ifndef __PAGETABLE_PUD_FOLDED
/* 4 level page table */
struct page *pgd_page(pgd_t pgd)
--
2.13.3
^ permalink raw reply related
* [PATCH v1 10/10] powerpc/mm: refactor ioremap_range() and use ioremap_page_range()
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
book3s64's ioremap_range() is almost same as fallback ioremap_range(),
except that it calls radix__ioremap_range() when radix is enabled.
radix__ioremap_range() is also very similar to the other ones, expect
that it calls ioremap_page_range when slab is available.
Lets keep only one version of ioremap_range() which calls
ioremap_page_range() on all platforms when slab is available.
At the same time, drop the nid parameter which is not used.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/book3s/64/radix.h | 3 ---
arch/powerpc/mm/book3s64/pgtable.c | 21 ---------------------
arch/powerpc/mm/book3s64/radix_pgtable.c | 20 --------------------
arch/powerpc/mm/ioremap.c | 23 +++++++++++++----------
4 files changed, 13 insertions(+), 54 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index e04a839cb5b9..574eca33f893 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -266,9 +266,6 @@ extern void radix__vmemmap_remove_mapping(unsigned long start,
extern int radix__map_kernel_page(unsigned long ea, unsigned long pa,
pgprot_t flags, unsigned int psz);
-extern int radix__ioremap_range(unsigned long ea, phys_addr_t pa,
- unsigned long size, pgprot_t prot, int nid);
-
static inline unsigned long radix__get_tree_size(void)
{
unsigned long rts_field;
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 7d0e0d0d22c4..4c8bed856533 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -446,24 +446,3 @@ int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
return true;
}
-
-int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
-{
- unsigned long i;
-
- if (radix_enabled())
- return radix__ioremap_range(ea, pa, size, prot, nid);
-
- for (i = 0; i < size; i += PAGE_SIZE) {
- int err = map_kernel_page(ea + i, pa + i, prot);
- if (err) {
- if (slab_is_available())
- unmap_kernel_range(ea, size);
- else
- WARN_ON_ONCE(1); /* Should clean up */
- return err;
- }
- }
-
- return 0;
-}
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 11303e2fffb1..d39edbb07bd1 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -1218,26 +1218,6 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
return 1;
}
-int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
- pgprot_t prot, int nid)
-{
- if (likely(slab_is_available())) {
- int err = ioremap_page_range(ea, ea + size, pa, prot);
- if (err)
- unmap_kernel_range(ea, size);
- return err;
- } else {
- unsigned long i;
-
- for (i = 0; i < size; i += PAGE_SIZE) {
- int err = map_kernel_page(ea + i, pa + i, prot);
- if (WARN_ON_ONCE(err)) /* Should clean up */
- return err;
- }
- return 0;
- }
-}
-
int __init arch_ioremap_p4d_supported(void)
{
return 0;
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 537c9148cea1..dc538d7f2467 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -76,21 +76,24 @@ void __iomem *ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long f
}
EXPORT_SYMBOL(ioremap_prot);
-int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
- pgprot_t prot, int nid)
+static int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
+ pgprot_t prot)
{
unsigned long i;
+ if (slab_is_available()) {
+ int err = ioremap_page_range(ea, ea + size, pa, prot);
+
+ if (err)
+ unmap_kernel_range(ea, size);
+ return err;
+ }
+
for (i = 0; i < size; i += PAGE_SIZE) {
int err = map_kernel_page(ea + i, pa + i, prot);
- if (err) {
- if (slab_is_available())
- unmap_kernel_range(ea, size);
- else
- WARN_ON_ONCE(1); /* Should clean up */
+ if (WARN_ON_ONCE(err)) /* Should clean up */
return err;
- }
}
return 0;
@@ -165,7 +168,7 @@ void __iomem *__ioremap_caller(phys_addr_t addr, unsigned long size,
ioremap_bot -= size;
va = ioremap_bot;
}
- ret = ioremap_range(va, pa, size, prot, NUMA_NO_NODE);
+ ret = ioremap_range(va, pa, size, prot);
if (!ret)
return (void __iomem *)va + (addr & ~PAGE_MASK);
@@ -223,7 +226,7 @@ void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_
WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
WARN_ON(size & ~PAGE_MASK);
- if (ioremap_range((unsigned long)ea, pa, size, prot, NUMA_NO_NODE))
+ if (ioremap_range((unsigned long)ea, pa, size, prot))
return NULL;
return (void __iomem *)ea;
--
2.13.3
^ permalink raw reply related
* [PATCH v1 09/10] powerpc/mm: make __ioremap_caller() common to PPC32 and PPC64
From: Christophe Leroy @ 2019-08-13 20:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <6bc35eca507359075528bc0e55938bc1ce8ee485.1565726867.git.christophe.leroy@c-s.fr>
__ioremap_caller() do the same thing. Define a common one.
__ioremap() is not reused because most of the tests included in
it are unnecessary when coming from __ioremap_caller()
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/mm/ioremap.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/mm/pgtable_32.c | 75 ---------------------------------
arch/powerpc/mm/pgtable_64.c | 61 ---------------------------
3 files changed, 99 insertions(+), 136 deletions(-)
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index 889ee656cf64..537c9148cea1 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -76,6 +76,105 @@ void __iomem *ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long f
}
EXPORT_SYMBOL(ioremap_prot);
+int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
+ pgprot_t prot, int nid)
+{
+ unsigned long i;
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ int err = map_kernel_page(ea + i, pa + i, prot);
+
+ if (err) {
+ if (slab_is_available())
+ unmap_kernel_range(ea, size);
+ else
+ WARN_ON_ONCE(1); /* Should clean up */
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+void __iomem *__ioremap_caller(phys_addr_t addr, unsigned long size,
+ pgprot_t prot, void *caller)
+{
+ phys_addr_t pa = addr & PAGE_MASK;
+ int ret;
+ unsigned long va;
+
+ size = PAGE_ALIGN(addr + size) - pa;
+
+#ifdef CONFIG_PPC64
+ /* We don't support the 4K PFN hack with ioremap */
+ if (pgprot_val(prot) & H_PAGE_4K_PFN)
+ return NULL;
+#else
+ /*
+ * If the address lies within the first 16 MB, assume it's in ISA
+ * memory space
+ */
+ if (pa < SZ_16M)
+ pa += _ISA_MEM_BASE;
+
+#ifndef CONFIG_CRASH_DUMP
+ /*
+ * Don't allow anybody to remap normal RAM that we're using.
+ * mem_init() sets high_memory so only do the check after that.
+ */
+ if (slab_is_available() && pa <= virt_to_phys(high_memory - 1) &&
+ page_is_ram(__phys_to_pfn(pa))) {
+ pr_err("%s(): phys addr 0x%llx is RAM lr %ps\n", __func__,
+ (unsigned long long)pa, __builtin_return_address(0));
+ return NULL;
+ }
+#endif
+#endif /* CONFIG_PPC64 */
+
+ if (size == 0 || pa == 0)
+ return NULL;
+
+ /*
+ * Is it already mapped? Perhaps overlapped by a previous
+ * mapping.
+ */
+ va = p_block_mapped(pa);
+ if (va)
+ return (void __iomem *)va + (addr & ~PAGE_MASK);
+
+ /*
+ * Choose an address to map it to.
+ * Once the vmalloc system is running, we use it.
+ * Before that, we map using addresses going
+ * down from ioremap_bot. vmalloc will use
+ * the addresses from IOREMAP_BASE through
+ * ioremap_bot
+ *
+ */
+ if (slab_is_available()) {
+ struct vm_struct *area;
+
+ area = __get_vm_area_caller(size, VM_IOREMAP, IOREMAP_BASE,
+ ioremap_bot, caller);
+ if (area == NULL)
+ return NULL;
+
+ area->phys_addr = pa;
+ va = (unsigned long)area->addr;
+ } else {
+ ioremap_bot -= size;
+ va = ioremap_bot;
+ }
+ ret = ioremap_range(va, pa, size, prot, NUMA_NO_NODE);
+ if (!ret)
+ return (void __iomem *)va + (addr & ~PAGE_MASK);
+
+ if (!slab_is_available())
+ ioremap_bot += size;
+
+ return NULL;
+}
+
/*
* Unmap an IO region and remove it from vmalloc'd list.
* Access to IO memory should be serialized by driver.
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 4597f45e4dc6..bacf3b85191c 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -35,81 +35,6 @@
extern char etext[], _stext[], _sinittext[], _einittext[];
-void __iomem *
-__ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *caller)
-{
- unsigned long v, i;
- phys_addr_t p;
- int err;
-
- /*
- * Choose an address to map it to.
- * Once the vmalloc system is running, we use it.
- * Before then, we use space going down from IOREMAP_TOP
- * (ioremap_bot records where we're up to).
- */
- p = addr & PAGE_MASK;
- size = PAGE_ALIGN(addr + size) - p;
-
- /*
- * If the address lies within the first 16 MB, assume it's in ISA
- * memory space
- */
- if (p < 16*1024*1024)
- p += _ISA_MEM_BASE;
-
-#ifndef CONFIG_CRASH_DUMP
- /*
- * Don't allow anybody to remap normal RAM that we're using.
- * mem_init() sets high_memory so only do the check after that.
- */
- if (slab_is_available() && p <= virt_to_phys(high_memory - 1) &&
- page_is_ram(__phys_to_pfn(p))) {
- printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n",
- (unsigned long long)p, __builtin_return_address(0));
- return NULL;
- }
-#endif
-
- if (size == 0)
- return NULL;
-
- /*
- * Is it already mapped? Perhaps overlapped by a previous
- * mapping.
- */
- v = p_block_mapped(p);
- if (v)
- goto out;
-
- if (slab_is_available()) {
- struct vm_struct *area;
- area = get_vm_area_caller(size, VM_IOREMAP, caller);
- if (area == 0)
- return NULL;
- area->phys_addr = p;
- v = (unsigned long) area->addr;
- } else {
- v = (ioremap_bot -= size);
- }
-
- /*
- * Should check if it is a candidate for a BAT mapping
- */
-
- err = 0;
- for (i = 0; i < size && err == 0; i += PAGE_SIZE)
- err = map_kernel_page(v + i, p + i, prot);
- if (err) {
- if (slab_is_available())
- vunmap((void *)v);
- return NULL;
- }
-
-out:
- return (void __iomem *) (v + ((unsigned long)addr & ~PAGE_MASK));
-}
-
static void __init *early_alloc_pgtable(unsigned long size)
{
void *ptr = memblock_alloc(size, size);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 32220f7381d7..781263df9f5e 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -101,67 +101,6 @@ unsigned long __pte_frag_size_shift;
EXPORT_SYMBOL(__pte_frag_size_shift);
#endif
-int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
-{
- unsigned long i;
-
- for (i = 0; i < size; i += PAGE_SIZE) {
- int err = map_kernel_page(ea + i, pa + i, prot);
- if (err) {
- if (slab_is_available())
- unmap_kernel_range(ea, size);
- else
- WARN_ON_ONCE(1); /* Should clean up */
- return err;
- }
- }
-
- return 0;
-}
-
-void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
- pgprot_t prot, void *caller)
-{
- phys_addr_t paligned;
- void __iomem *ret;
-
- /*
- * Choose an address to map it to.
- * Once the vmalloc system is running, we use it.
- * Before that, we map using addresses going
- * down from ioremap_bot. vmalloc will use
- * the addresses from IOREMAP_BASE through
- * ioremap_bot
- *
- */
- paligned = addr & PAGE_MASK;
- size = PAGE_ALIGN(addr + size) - paligned;
-
- if ((size == 0) || (paligned == 0))
- return NULL;
-
- if (slab_is_available()) {
- struct vm_struct *area;
-
- area = __get_vm_area_caller(size, VM_IOREMAP,
- IOREMAP_BASE, ioremap_bot,
- caller);
- if (area == NULL)
- return NULL;
-
- area->phys_addr = paligned;
- ret = __ioremap_at(paligned, area->addr, size, prot);
- } else {
- ret = __ioremap_at(paligned, (void *)ioremap_bot - size, size, prot);
- if (ret)
- ioremap_bot -= size;
- }
-
- if (ret)
- ret += addr & ~PAGE_MASK;
- return ret;
-}
-
#ifndef __PAGETABLE_PUD_FOLDED
/* 4 level page table */
struct page *pgd_page(pgd_t pgd)
--
2.13.3
^ permalink raw reply related
* Re: [RFC PATCH] powerpc/64s/radix: introduce option to disable broadcast tlbie
From: Michael Ellerman @ 2019-08-14 2:06 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev
Cc: Aneesh Kumar K . V, Paul Mackerras, Nicholas Piggin
In-Reply-To: <20190731123203.6370-1-npiggin@gmail.com>
Hi Nick,
Just a few comments.
Nicholas Piggin <npiggin@gmail.com> writes:
> diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c
> index 71f7fede2fa4..56ceecbd3d5c 100644
> --- a/arch/powerpc/mm/book3s64/radix_tlb.c
> +++ b/arch/powerpc/mm/book3s64/radix_tlb.c
> @@ -285,6 +286,30 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
> asm volatile("eieio; tlbsync; ptesync": : :"memory");
> }
>
> +struct tlbiel_pid {
> + unsigned long pid;
> + unsigned long ric;
> +};
> +
> +static void do_tlbiel_pid(void *info)
> +{
> + struct tlbiel_pid *t = info;
> +
> + if (t->ric == RIC_FLUSH_TLB)
> + _tlbiel_pid(t->pid, RIC_FLUSH_TLB);
> + else if (t->ric == RIC_FLUSH_PWC)
> + _tlbiel_pid(t->pid, RIC_FLUSH_PWC);
> + else
> + _tlbiel_pid(t->pid, RIC_FLUSH_ALL);
> +}
> +
> +static inline void _tlbiel_pid_broadcast(const struct cpumask *cpus,
> + unsigned long pid, unsigned long ric)
Can we call these "multicast" instead of "broadcast"?
I think that's more accurate, and avoids confusion with tlbie which
literally does a broadcast (at least architecturally).
> @@ -524,6 +604,12 @@ static bool mm_needs_flush_escalation(struct mm_struct *mm)
> return false;
> }
>
> +static bool tlbie_enabled = true;
> +static bool use_tlbie(void)
> +{
> + return tlbie_enabled;
> +}
No synchronisation, but that's OK. Would probably be good to have
a comment though explaining why.
We could use a static_key but I guess the overhead of a comparison and
branch is in the noise vs the tlbie/tlbiel.
> @@ -1100,3 +1221,13 @@ extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
> }
> EXPORT_SYMBOL_GPL(radix_kvm_prefetch_workaround);
> #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
> +
> +static int __init radix_tlb_setup(void)
> +{
> + debugfs_create_bool("tlbie_enabled", 0600,
> + powerpc_debugfs_root,
> + &tlbie_enabled);
> +
> + return 0;
> +}
> +arch_initcall(radix_tlb_setup);
For working around hardware bugs we would want a command line parameter
or other boot time way to flip this. But I guess you're saying because
we haven't converted all uses of tlbie we can't really support that
anyway, and so a runtime switch is sufficient?
cheers
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: rewrite LOAD_REG_IMMEDIATE() as an intelligent macro
From: Paul Mackerras @ 2019-08-14 2:08 UTC (permalink / raw)
To: Christophe Leroy; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <61d2a0b6f0c89b1ee546851ce9b6bd345e5ec968.1565690241.git.christophe.leroy@c-s.fr>
On Tue, Aug 13, 2019 at 09:59:35AM +0000, Christophe Leroy wrote:
[snip]
> +.macro __LOAD_REG_IMMEDIATE r, x
> + .if \x & ~0xffffffff != 0
> + __LOAD_REG_IMMEDIATE_32 \r, (\x) >> 32
> + rldicr \r, \r, 32, 31
> + .if (\x) & 0xffff0000 != 0
> + oris \r, \r, (\x)@__AS_ATHIGH
> + .endif
> + .if (\x) & 0xffff != 0
> + oris \r, \r, (\x)@l
> + .endif
> + .else
> + __LOAD_REG_IMMEDIATE_32 \r, \x
> + .endif
> +.endm
Doesn't this force all negative constants, even small ones, to use
the long sequence? For example, __LOAD_REG_IMMEDIATE r3, -1 will
generate (as far as I can see):
li r3, -1
rldicr r3, r3, 32, 31
oris r3, r3, 0xffff
ori r3, r3, 0xffff
which seems suboptimal.
Paul.
^ permalink raw reply
* [PATCHv6 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Xiaowei Bao @ 2019-08-14 2:03 UTC (permalink / raw)
To: minghuan.Lian, mingkai.hu, roy.zang, lorenzo.pieralisi, bhelgaas,
linuxppc-dev, linux-pci, linux-arm-kernel, linux-kernel
Cc: Xiaowei Bao
The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
is 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware,
so set the bar_fixed_64bit with 0x14.
Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
- Replace value 0x14 with a macro.
v3:
- No change.
v4:
- send the patch again with '--to'.
v5:
- fix the commit message.
v6:
- remove the [EXT] tag of the $SUBJECT in email.
drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index be61d96..ca9aa45 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = {
.linkup_notifier = false,
.msi_capable = true,
.msix_capable = false,
+ .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
};
static const struct pci_epc_features*
--
2.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox