[PATCH] powerpc/xmon: Update paca fields dumped in xmon
The set of paca fields we dump in xmon has gotten somewhat out of date. Update to add some recently added fields. Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 94cc8ba36c14..a2cbf0caa1f7 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2425,6 +2425,16 @@ static void dump_one_paca(int cpu) DUMP(p, thread_idle_state, "x"); DUMP(p, thread_mask, "x"); DUMP(p, subcore_sibling_mask, "x"); + DUMP(p, thread_sibling_pacas, "px"); + DUMP(p, requested_psscr, "llx"); + DUMP(p, stop_sprs.pid, "llx"); + DUMP(p, stop_sprs.ldbar, "llx"); + DUMP(p, stop_sprs.fscr, "llx"); + DUMP(p, stop_sprs.hfscr, "llx"); + DUMP(p, stop_sprs.mmcr1, "llx"); + DUMP(p, stop_sprs.mmcr2, "llx"); + DUMP(p, stop_sprs.mmcra, "llx"); + DUMP(p, dont_stop, "x"); #endif DUMP(p, accounting.utime, "llx"); -- 2.14.1
Re: powepc: Clear PCR on boot
On Fri, 2018-05-18 at 01:37:42 UTC, Michael Neuling wrote: > Clear the PCR on boot to ensure we are not running in a compat mode. > > We've seen this cause problems when a crash (and kdump) occurs while > running compat mode guests. The kdump kernel then runs with the PCR > set and causes problems. The symptom in the kdump kernel (also seen in > petitboot after fast-reboot) is early userspace programs taking > sigills on newer instructions (seen in libc). > > Signed-off-by: Michael Neuling > Cc: Applied to powerpc fixes, thanks. https://git.kernel.org/powerpc/c/faf37c44a105f3608115785f17cbbf cheers
Re: powerpc/fsl/dts: fix the i2c-mux compatible for t104xqds
On Thu, 2017-08-03 at 12:59:34 UTC, Peter Rosin wrote: > The sanctioned compatible is "nxp,pca9547". > > Signed-off-by: Peter Rosin Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/e4f2419fac381c5a7659834169dbe7 cheers
Re: selftests/powerpc: Remove redundant cp_abort test
On Thu, 2017-10-05 at 23:48:57 UTC, Michael Neuling wrote: > Paste on POWER9 only works on accelerators and no longer on real > memory. Hence this test is broken so remove it. > > Signed-off-by: Michael Neuling Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/00c946a06ec8414ad22f0e8dcd1718 cheers
Re: Revert "powerpc/64: Fix checksum folding in csum_add()"
On Tue, 2018-04-10 at 06:34:37 UTC, Christophe Leroy wrote: > This reverts commit 6ad966d7303b70165228dba1ee8da1a05c10eefe. > > That commit was pointless, because csum_add() sums two 32 bits > values, so the sum is 0x1fffe at the maximum. > And then when adding upper part (1) and lower part (0xfffe), > the result is 0x which doesn't carry. > Any lower value will not carry either. > > And behind the fact that this commit is useless, it also kills the > whole purpose of having an arch specific inline csum_add() > because the resulting code gets even worse than what is obtained > with the generic implementation of csum_add() > > 0240 <.csum_add>: > 240: 38 00 ff ff li r0,-1 > 244: 7c 84 1a 14 add r4,r4,r3 > 248: 78 00 00 20 clrldi r0,r0,32 > 24c: 78 89 00 22 rldicl r9,r4,32,32 > 250: 7c 80 00 38 and r0,r4,r0 > 254: 7c 09 02 14 add r0,r9,r0 > 258: 78 09 00 22 rldicl r9,r0,32,32 > 25c: 7c 00 4a 14 add r0,r0,r9 > 260: 78 03 00 20 clrldi r3,r0,32 > 264: 4e 80 00 20 blr > > In comparison, the generic implementation of csum_add() gives: > > 0290 <.csum_add>: > 290: 7c 63 22 14 add r3,r3,r4 > 294: 7f 83 20 40 cmplw cr7,r3,r4 > 298: 7c 10 10 26 mfocrf r0,1 > 29c: 54 00 ef fe rlwinm r0,r0,29,31,31 > 2a0: 7c 60 1a 14 add r3,r0,r3 > 2a4: 78 63 00 20 clrldi r3,r3,32 > 2a8: 4e 80 00 20 blr > > And the reverted implementation for PPC64 gives: > > 0240 <.csum_add>: > 240: 7c 84 1a 14 add r4,r4,r3 > 244: 78 80 00 22 rldicl r0,r4,32,32 > 248: 7c 80 22 14 add r4,r0,r4 > 24c: 78 83 00 20 clrldi r3,r4,32 > 250: 4e 80 00 20 blr > > Fixes: 6ad966d7303b7 ("powerpc/64: Fix checksum folding in csum_add()") > Signed-off-by: Christophe Leroy > Acked-by: Paul Mackerras Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/96f391cf40ee5c9201cc7b55abe390 cheers
Re: [v2, 1/2] powerpc: avoid an unnecessary test and branch in longjmp()
On Tue, 2018-04-17 at 17:08:16 UTC, Christophe Leroy wrote: > Doing the test at exit of the function avoids an unnecessary > test and branch inside longjmp() > > Signed-off-by: Christophe Leroy Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/24c78586cc6798028205e12c34febf cheers
Re: [1/2] powerpc: flipper-pic: Don't match all IRQ domains
On Thu, 2018-05-10 at 21:59:18 UTC, =?utf-8?q?Jonathan_Neusch=C3=A4fer?= wrote: > On the Wii, there is a secondary IRQ controller (hlwd-pic), so > flipper-pic's match operation should not be hardcoded to return 1. > In fact, the default matching logic is sufficient, and we can completely > omit flipper_pic_match. > > Signed-off-by: Jonathan Neuschäfer Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/c068e6b8caa0c796535cb12f64767c cheers
Re: [1/3] powerpc/io: Add __raw_writeq_be() __raw_rm_writeq_be()
On Mon, 2018-05-14 at 12:50:31 UTC, Michael Ellerman wrote: > Add byte-swapping versions of __raw_writeq() and __raw_rm_writeq(). > > This allows us to avoid sparse warnings caused by passing __be64 to > __raw_writeq(), which takes unsigned long: > > arch/powerpc/platforms/powernv/pci-ioda.c:1981:38: > warning: incorrect type in argument 1 (different base types) > expected unsigned long [unsigned] v > got restricted __be64 [usertype] > > It's also generally preferable to use a byte-swapping accessor rather > than doing it by hand in the code, which is more bug prone. > > Signed-off-by: Michael Ellerman > Reviewed-by: Samuel Mendoza-Jonas Series applied to powerpc next. https://git.kernel.org/powerpc/c/8056fe28d04607106e7d418bd9ee2e cheers
Re: [1/2] powerpc/powernv: Fix opal_event_shutdown() called with interrupts disabled
On Mon, 2018-05-14 at 15:59:46 UTC, Nicholas Piggin wrote: > A kernel crash in process context that calls emergency_restart from > panic will end up calling opal_event_shutdown with interrupts disabled > but not in interrupt. This causes a sleeping function to be called > which gives the following warning with sysrq+c: > > Rebooting in 10 seconds.. > BUG: sleeping function called from invalid context at > kernel/locking/mutex.c:238 > in_atomic(): 0, irqs_disabled(): 1, pid: 7669, name: bash > CPU: 20 PID: 7669 Comm: bash Tainted: G D W 4.17.0-rc5+ #3 > Call Trace: > dump_stack+0xb0/0xf4 (unreliable) > ___might_sleep+0x174/0x1a0 > mutex_lock+0x38/0xb0 > __free_irq+0x68/0x460 > free_irq+0x70/0xc0 > opal_event_shutdown+0xb4/0xf0 > opal_shutdown+0x24/0xa0 > pnv_shutdown+0x28/0x40 > machine_shutdown+0x44/0x60 > machine_restart+0x28/0x80 > emergency_restart+0x30/0x50 > panic+0x2a0/0x328 > oops_end+0x1ec/0x1f0 > bad_page_fault+0xe8/0x154 > handle_page_fault+0x34/0x38 > --- interrupt: 300 at sysrq_handle_crash+0x44/0x60 > LR = __handle_sysrq+0xfc/0x260 > flag_spec.62335+0x12b844/0x1e8db4 (unreliable) > __handle_sysrq+0xfc/0x260 > write_sysrq_trigger+0xa8/0xb0 > proc_reg_write+0xac/0x110 > __vfs_write+0x6c/0x240 > vfs_write+0xd0/0x240 > ksys_write+0x6c/0x110 > > Fixes: 9f0fd0499d30 ("powerpc/powernv: Add a virtual irqchip for opal events") > Signed-off-by: Nicholas Piggin Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/c0beffc4f4c658fde86d52c837e784 cheers
Re: [v2] powerpc/perf: Fix memory allocation for core-imc based on num_possible_cpus()
On Wed, 2018-05-16 at 06:35:18 UTC, Anju T Sudhakar wrote: > Currently memory is allocated for core-imc based on cpu_present_mask, > which has bit 'cpu' set iff cpu is populated. We use (cpu number / threads > per core) as the array index to access the memory. > > Under some circumstances firmware marks a CPU as GUARDed CPU and boot the > system, until cleared of errors, these CPU's are unavailable for all > subsequent boots. GUARDed CPUs are possible but not present from linux > view, so it blows a hole when we assume the max length of our allocation > is driven by our max present cpus, where as one of the cpus might be online > and be beyond the max present cpus, due to the hole. > So (cpu number / threads per core) value bounds the array index and leads > to memory overflow. > > Call trace observed during a guard test: > > Faulting instruction address: 0xc0149f1c > cpu 0x69: Vector: 380 (Data Access Out of Range) at [c03fea303420] > pc:c0149f1c: prefetch_freepointer+0x14/0x30 > lr:c014e0f8: __kmalloc+0x1a8/0x1ac > sp:c03fea3036a0 >msr:90009033 >dar:c9c54b2c91dbf6b7 > current = 0xc03fea2c > paca= 0xcfddd880 softe: 3irq_happened: 0x01 > pid = 1, comm = swapper/104 > Linux version 4.16.7-openpower1 (smc@smc-desktop) (gcc version 6.4.0 > (Buildroot 2018.02.1-6-ga8d1126)) #2 SMP Fri May 4 16:44:54 PDT 2018 > enter ? for help > call trace: >__kmalloc+0x1a8/0x1ac >(unreliable) >init_imc_pmu+0x7f4/0xbf0 >opal_imc_counters_probe+0x3fc/0x43c >platform_drv_probe+0x48/0x80 >driver_probe_device+0x22c/0x308 >__driver_attach+0xa0/0xd8 >bus_for_each_dev+0x88/0xb4 >driver_attach+0x2c/0x40 >bus_add_driver+0x1e8/0x228 >driver_register+0xd0/0x114 >__platform_driver_register+0x50/0x64 >opal_imc_driver_init+0x24/0x38 >do_one_initcall+0x150/0x15c >kernel_init_freeable+0x250/0x254 >kernel_init+0x1c/0x150 >ret_from_kernel_thread+0x5c/0xc8 > > Allocating memory for core-imc based on cpu_possible_mask, which has > bit 'cpu' set iff cpu is populatable, will fix this issue. > > Reported-by: Pridhiviraj Paidipeddi > Signed-off-by: Anju T Sudhakar > Reviewed-by: Balbir Singh > Tested-by: Pridhiviraj Paidipeddi Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/d2032678e57fc508d7878307badde8 cheers
Re: powerpc: get rid of PMD_PAGE_SIZE() and _PMD_SIZE
On Wed, 2018-05-16 at 06:58:57 UTC, Christophe Leroy wrote: > PMD_PAGE_SIZE() is nowhere used and _PMD_SIZE is only > used by PMD_PAGE_SIZE(). > > This patch removes them. > > Signed-off-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/5279821a6f5ff75d7dce632e49b9fb cheers
Re: [1/2] powerpc/ptrace: Fix enforcement of DAWR contraints
On Thu, 2018-05-17 at 05:37:14 UTC, Michael Neuling wrote: > Back when we first introduced the DAWR in this commit: > 4ae7ebe952 powerpc: Change hardware breakpoint to allow longer ranges > > We screwed up the constraint making it a 1024 byte boundary rather > than a 512. This makes the check overly permissive. Fortunately GDB is > the only real user and it always did they right thing, so we never > noticed. > > This fixes the constraint to 512 bytes. > > Signed-off-by: Michael Neuling > cc: # v3.9+ Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/cd6ef7eebf171bfcba7dc2df719c2a cheers
Re: [RESEND] powerpc/lib: Fix "integer constant is too large" build failure
On Fri, 2018-05-18 at 01:18:33 UTC, Finn Thain wrote: > My powerpc-linux-gnu-gcc v4.4.5 compiler can't build a 32-bit kernel > any more: > > arch/powerpc/lib/sstep.c: In function 'do_popcnt': > arch/powerpc/lib/sstep.c:1068: error: integer constant is too large for > 'long' type > arch/powerpc/lib/sstep.c:1069: error: integer constant is too large for > 'long' type > arch/powerpc/lib/sstep.c:1069: error: integer constant is too large for > 'long' type > arch/powerpc/lib/sstep.c:1070: error: integer constant is too large for > 'long' type > arch/powerpc/lib/sstep.c:1079: error: integer constant is too large for > 'long' type > arch/powerpc/lib/sstep.c: In function 'do_prty': > arch/powerpc/lib/sstep.c:1117: error: integer constant is too large for > 'long' type > > This file gets compiled with -std=gnu89 which means a constant can be > given the type 'long' even if it won't fit. Fix the errors with a 'ULL' > suffix on the relevant constants. > > Fixes: 2c979c489fee ("powerpc/lib/sstep: Add prty instruction emulation") > Fixes: dcbd19b48d31 ("powerpc/lib/sstep: Add popcnt instruction emulation") > Signed-off-by: Finn Thain Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/20acf7fc9409e48cfbfb38262aa534 cheers
Re: powerpc: fix spelling mistake: "Discharching" -> "Discharging"
On Fri, 2018-05-18 at 09:31:17 UTC, Colin King wrote: > From: Colin Ian King > > Trivial fix to spelling mistake in battery_charging array > > Signed-off-by: Colin Ian King Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/ba01b058a52abcb0539d94ae976ef1 cheers
[PATCH v3] powerpc/powernv: Add queue mechanism for early messages
Problem being solved is when issuing a BMC soft poweroff during IPL, the poweroff was being lost so the machine would not poweroff. Opal messages were being received before the opal-power code registered its notifiers. Alternatives discussed (option #3 was chosen): 1 - Have opal_message_init() explicitly call opal_power_control_init() before it dequeues any OPAL messages (i.e. before we register the opal-msg IRQ handler). 2 - Introduce concept of critical message types and when we register handlers we track which message types have a registered handler, then defer the opal-msg IRQ registration until we have a handler registered for all the critical types. 3 - Buffering messages, if we receive a message and do not yet have a handler for that type, store the message and replay when a handler for that type is registered. Signed-off-by: Deb McLemore --- arch/powerpc/platforms/powernv/opal.c | 89 ++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 48fbb41..b8cae0d 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -40,6 +40,16 @@ #include "powernv.h" +#define OPAL_MSG_QUEUE_MAX 16 + +struct opal_msg_node { + struct list_headlist; + struct opal_msg msg; +}; + +static DEFINE_SPINLOCK(msg_list_lock); +static LIST_HEAD(msg_list); + /* /sys/firmware/opal */ struct kobject *opal_kobj; @@ -55,6 +65,8 @@ struct mcheck_recoverable_range { u64 recover_addr; }; +static int msg_list_size; + static struct mcheck_recoverable_range *mc_recoverable_range; static int mc_recoverable_range_len; @@ -231,6 +243,44 @@ static int __init opal_register_exception_handlers(void) } machine_early_initcall(powernv, opal_register_exception_handlers); +static void queue_replay_msg(void *msg) +{ + struct opal_msg_node *msg_node; + + if (msg_list_size < OPAL_MSG_QUEUE_MAX) { + msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC); + if (msg_node) { + INIT_LIST_HEAD(&msg_node->list); + memcpy(&msg_node->msg, msg, sizeof(struct opal_msg)); + list_add_tail(&msg_node->list, &msg_list); + msg_list_size++; + } else + pr_warn_once("message queue no memory\n"); + + if (msg_list_size >= OPAL_MSG_QUEUE_MAX) + pr_warn_once("message queue full\n"); + } +} + +static void dequeue_replay_msg(enum opal_msg_type msg_type) +{ + /* msg_list_lock held in register to allow operation to complete */ + /* prior to any subsequent messages */ + + struct opal_msg_node *msg_node, *tmp; + + list_for_each_entry_safe(msg_node, tmp, &msg_list, list) { + if (be32_to_cpu(msg_node->msg.msg_type) != msg_type) + continue; + atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type], + msg_type, + &msg_node->msg); + list_del(&msg_node->list); + kfree(msg_node); + msg_list_size--; + } +} + /* * Opal message notifier based on message type. Allow subscribers to get * notified for specific messgae type. @@ -238,14 +288,32 @@ machine_early_initcall(powernv, opal_register_exception_handlers); int opal_message_notifier_register(enum opal_msg_type msg_type, struct notifier_block *nb) { + int ret; + unsigned long flags; + if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) { pr_warn("%s: Invalid arguments, msg_type:%d\n", __func__, msg_type); return -EINVAL; } - return atomic_notifier_chain_register( - &opal_msg_notifier_head[msg_type], nb); + spin_lock_irqsave(&msg_list_lock, flags); + ret = atomic_notifier_chain_register( + &opal_msg_notifier_head[msg_type], nb); + + if (ret) { + spin_unlock_irqrestore(&msg_list_lock, flags); + return ret; + } + + /* Replay any queued messages that came in */ + /* prior to the notifier chain registration */ + /* msg_list_lock held here to assure completion */ + + dequeue_replay_msg(msg_type); + spin_unlock_irqrestore(&msg_list_lock, flags); + + return 0; } EXPORT_SYMBOL_GPL(opal_message_notifier_register); @@ -259,6 +327,23 @@ EXPORT_SYMBOL_GPL(opal_message_notifier_unregister); static void opal_message_do_notify(uint32_t msg_type, void *msg) { + unsigned long flags; + bool queued = false; + + spin_lock_irqsave(&msg_list_lock, flags); + if (opal_msg_notifier_head[msg_type].head == NULL) {
Re: pkeys on POWER: Access rights not reset on execve
On 05/20/2018 09:11 PM, Ram Pai wrote: Florian, Does the following patch fix the problem for you? Just like x86 I am enabling all keys in the UAMOR register during initialization itself. Hence any key created by any thread at any time, will get activated on all threads. So any thread can change the permission on that key. Smoke tested it with your test program. I think this goes in the right direction, but the AMR value after fork is still strange: AMR (PID 34912): 0x AMR after fork (PID 34913): 0x AMR (PID 34913): 0x Allocated key in subprocess (PID 34913): 2 Allocated key (PID 34912): 2 Setting AMR: 0x New AMR value (PID 34912): 0x0fff About to call execl (PID 34912) ... AMR (PID 34912): 0x0fff AMR after fork (PID 34914): 0x0003 AMR (PID 34914): 0x0003 Allocated key in subprocess (PID 34914): 2 Allocated key (PID 34912): 2 Setting AMR: 0x New AMR value (PID 34912): 0x0fff I mean this line: AMR after fork (PID 34914): 0x0003 Shouldn't it be the same as in the parent process? Thanks, Florian
[PATCH] powerpc/xmon: really enable xmon when a breakpoint is set
When single-stepping kernel code from xmon without a debug hook enabled the kernel crashes. This can happen when kernel starts with xmon on crash disabled but xmon is entered using sysrq. Commit e1368d0c9edb ("powerpc/xmon: Setup debugger hooks when first break-point is set") adds force_enable_xmon function that prints "xmon: Enabling debugger hooks" but does not enable them. Add the call to xmon_init to install the debugger hooks in force_enable_xmon and also call force_enable_xmon when single-stepping in xmon. Fixes: e1368d0c9edb ("powerpc/xmon: Setup debugger hooks when first break-point is set") Signed-off-by: Michal Suchanek --- arch/powerpc/xmon/xmon.c | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a0842f1ff72c..504bd1c3d8b0 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -179,6 +179,9 @@ static const char *getvecname(unsigned long vec); static int do_spu_cmd(void); +static void xmon_init(int enable); +static inline void force_enable_xmon(void); + #ifdef CONFIG_44x static void dump_tlb_44x(void); #endif @@ -1094,6 +1097,7 @@ static int do_step(struct pt_regs *regs) unsigned int instr; int stepped; + force_enable_xmon(); /* check we are in 64-bit kernel mode, translation enabled */ if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) { if (mread(regs->nip, &instr, 4) == 4) { @@ -1275,6 +1279,7 @@ static inline void force_enable_xmon(void) if (!xmon_on) { printf("xmon: Enabling debugger hooks\n"); xmon_on = 1; + xmon_init(1); } } -- 2.13.6
Re: [PATCH] selftests/powerpc: add test to verify rfi flush across a system call
Michael Ellerman wrote: "Naveen N. Rao" writes: diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index d46916867a6f..c6b1d20ed3ba 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -104,3 +111,149 @@ int pick_online_cpu(void) printf("No cpus in affinity mask?!\n"); return -1; } ... + +static void sigill_handler(int signr, siginfo_t *info, void *unused) +{ + static int warned = 0; + ucontext_t *ctx = (ucontext_t *)unused; + unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP]; The above doesn't work on 32-bit, and this code is sometimes built 32-bit. For an example of how to handle 32 and 64-bit, see eg: tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c Thanks. I'll post a v2 that addresses the 32-bit build issue. - Naveen
[PATCH v2 0/2] selftests/powerpc: Add test for rfi_flush
This is v2 of: https://patchwork.ozlabs.org/patch/895765/ Changes: - Patch 1 is new. - Patch 2 uses the new macro introduced in the first patch. The output message has also been slightly tweaked to make things clearer. - Naveen Naveen N. Rao (2): selftests/powerpc: Move UCONTEXT_NIA() into utils.h selftests/powerpc: Add test to verify rfi flush across a system call tools/testing/selftests/powerpc/Makefile | 3 +- .../testing/selftests/powerpc/include/utils.h | 18 +++ .../primitives/load_unaligned_zeropad.c | 8 - .../selftests/powerpc/security/Makefile | 7 + .../selftests/powerpc/security/rfi_flush.c| 132 +++ tools/testing/selftests/powerpc/utils.c | 153 ++ 6 files changed, 312 insertions(+), 9 deletions(-) create mode 100644 tools/testing/selftests/powerpc/security/Makefile create mode 100644 tools/testing/selftests/powerpc/security/rfi_flush.c -- 2.17.0
[PATCH v2 1/2] selftests/powerpc: Move UCONTEXT_NIA() into utils.h
... so that it can be used by others. Signed-off-by: Naveen N. Rao --- tools/testing/selftests/powerpc/include/utils.h | 8 .../selftests/powerpc/primitives/load_unaligned_zeropad.c | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index 735815b3ad7f..b8f9cc6c9ff2 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -78,4 +78,12 @@ do { \ #define PPC_FEATURE2_ARCH_3_00 0x0080 #endif +#if defined(__powerpc64__) +#define UCONTEXT_NIA(UC) (UC)->uc_mcontext.gp_regs[PT_NIP] +#elif defined(__powerpc__) +#define UCONTEXT_NIA(UC) (UC)->uc_mcontext.uc_regs->gregs[PT_NIP] +#else +#error implement UCONTEXT_NIA +#endif + #endif /* _SELFTESTS_POWERPC_UTILS_H */ diff --git a/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c b/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c index ed3239bbfae2..ee1e9ca22f0d 100644 --- a/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c +++ b/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c @@ -65,14 +65,6 @@ static int unprotect_region(void) extern char __start___ex_table[]; extern char __stop___ex_table[]; -#if defined(__powerpc64__) -#define UCONTEXT_NIA(UC) (UC)->uc_mcontext.gp_regs[PT_NIP] -#elif defined(__powerpc__) -#define UCONTEXT_NIA(UC) (UC)->uc_mcontext.uc_regs->gregs[PT_NIP] -#else -#error implement UCONTEXT_NIA -#endif - struct extbl_entry { int insn; int fixup; -- 2.17.0
[PATCH v2 2/2] selftests/powerpc: Add test to verify rfi flush across a system call
This adds a test to verify proper functioning of the rfi flush capability implemented to mitigate meltdown. The test works by measuring the number of L1d cache misses encountered while loading data from memory. Across a system call, since the L1d cache is flushed when rfi_flush is enabled, the number of cache misses is expected to be relative to the number of cachelines corresponding to the data being loaded. The current system setting is reflected via powerpc/rfi_flush under debugfs (assumed to be /sys/kernel/debug/). This test verifies the expected result with rfi_flush enabled as well as when it is disabled. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman Signed-off-by: Naveen N. Rao --- tools/testing/selftests/powerpc/Makefile | 3 +- .../testing/selftests/powerpc/include/utils.h | 10 ++ .../selftests/powerpc/security/Makefile | 7 + .../selftests/powerpc/security/rfi_flush.c| 132 +++ tools/testing/selftests/powerpc/utils.c | 153 ++ 5 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/security/Makefile create mode 100644 tools/testing/selftests/powerpc/security/rfi_flush.c diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 201b598558b9..b3ad909aefbc 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -28,7 +28,8 @@ SUB_DIRS = alignment \ tm \ vphn \ math \ - ptrace + ptrace \ + security endif diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index b8f9cc6c9ff2..684b9d554639 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "reg.h" /* Avoid headaches with PRI?64 - just use %ll? always */ @@ -31,6 +32,15 @@ void *get_auxv_entry(int type); int pick_online_cpu(void); +int read_debugfs_file(char *debugfs_file, int *result); +int write_debugfs_file(char *debugfs_file, int result); +void set_dscr(unsigned long val); +int perf_event_open_counter(unsigned int type, + unsigned long config, int group_fd); +int perf_event_enable(int fd); +int perf_event_disable(int fd); +int perf_event_reset(int fd); + static inline bool have_hwcap(unsigned long ftr) { return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr; diff --git a/tools/testing/selftests/powerpc/security/Makefile b/tools/testing/selftests/powerpc/security/Makefile new file mode 100644 index ..8a472e13950a --- /dev/null +++ b/tools/testing/selftests/powerpc/security/Makefile @@ -0,0 +1,7 @@ +TEST_GEN_PROGS := rfi_flush + +CFLAGS += -I../../../../../usr/include + +include ../../lib.mk + +$(TEST_GEN_PROGS): ../harness.c ../utils.c diff --git a/tools/testing/selftests/powerpc/security/rfi_flush.c b/tools/testing/selftests/powerpc/security/rfi_flush.c new file mode 100644 index ..a20fe8eca161 --- /dev/null +++ b/tools/testing/selftests/powerpc/security/rfi_flush.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +#define CACHELINE_SIZE 128 + +struct perf_event_read { + uint64_t nr; + uint64_t l1d_misses; +}; + +static inline uint64_t load(void *addr) +{ + uint64_t tmp; + + asm volatile("ld %0,0(%1)" : "=r"(tmp) : "b" (addr)); + + return tmp; +} + +static void syscall_loop(char *p, unsigned long iterations, unsigned long zero_size) +{ + for (unsigned long i = 0; i < iterations; i++) { + for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE) + load(p + j); + getppid(); + } +} + +int rfi_flush_test(void) +{ + char *p; + int repetitions = 10; + int fd, passes = 0, iter, rc = 0; + struct perf_event_read v; + uint64_t l1d_misses_total = 0; + unsigned long iterations = 10, zero_size = 24*1024; + int rfi_flush_org, rfi_flush; + + SKIP_IF(geteuid() != 0); + + if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_org)) { + perror("error reading powerpc/rfi_flush debugfs file"); + printf("unable to determine current rfi_flush setting"); + return 1; + } + + rfi_flush = rfi_flush_org; + + FAIL_IF((fd = perf_event_open_counter(PERF_TYPE_RAW, + 0x400f0, /* L1d miss */ + -1)) < 0); + + p = (char *)memalign(zero_size, CACHELINE_SIZE); + + FAIL_IF(perf_event_enable(fd)); + + set_dscr(1); + + iter = repetitions; + +again: + FAIL_IF(perf_event_reset(fd)); + + syscall_loop(p, i
[RFC v5 0/6] powerpc/hotplug: Fix affinity assoc for LPAR migration
The migration of LPARs across Power systems affects many attributes including that of the associativity of memory blocks and CPUs. The patches in this set execute when a system is coming up fresh upon a migration target. They are intended to, * Recognize changes to the associativity of memory and CPUs recorded in internal data structures when compared to the latest copies in the device tree (e.g. ibm,dynamic-memory, ibm,dynamic-memory-v2, cpus), * Recognize changes to the associativity mapping (e.g. ibm, associativity-lookup-arrays), locate all assigned memory blocks corresponding to each changed row, and readd all such blocks. * Generate calls to other code layers to reset the data structures related to associativity of the CPUs and memory. * Re-register the 'changed' entities into the target system. Re-registration of CPUs and memory blocks mostly entails acting as if they have been newly hot-added into the target system. Signed-off-by: Michael Bringmann Michael Bringmann (3): powerpc migration/drmem: Modify DRMEM code to export more features powerpc migration/cpu: Associativity & cpu changes powerpc migration/memory: Associativity & memory updates --- Changes in RFC: -- Restructure and rearrange content of patches to co-locate similar or related modifications -- Rename pseries_update_drconf_cpu to pseries_update_cpu -- Simplify code to update CPU nodes during mobility checks. Remove functions to generate extra HP_ELOG messages in favor of direct function calls to dlpar_cpu_readd_by_index, or dlpar_memory_readd_by_index. -- Revise code order in dlpar_cpu_readd_by_index() to present more appropriate error codes from underlying layers of the implementation. -- Add hotplug device lock around all property updates -- Schedule all CPU and memory changes due to device-tree updates / LPAR mobility as workqueue operations -- Export DRMEM accessor functions to parse 'ibm,dynamic-memory-v2' -- Export DRMEM functions to provide user copies of LMB array -- Compress code using DRMEM accessor functions. -- Split topology timer crash fix into new patch. -- Modify DRMEM code to replace usages of dt_root_addr_cells, and dt_mem_next_cell, as these are only available at first boot. -- Correct a bug in DRC index selection for queued operation. -- Rebase to 4.17-rc5 kernel -- Minor code cleanups
[RFC v5 1/6] powerpc/drmem: Export 'dynamic-memory' loader
powerpc/drmem: Export many of the functions of DRMEM to parse "ibm,dynamic-memory" and "ibm,dynamic-memory-v2" during hotplug operations and for Post Migration events. Also modify the DRMEM initialization code to allow it to, * Be called after system initialization * Provide a separate user copy of the LMB array that is produces * Free the user copy upon request Signed-off-by: Michael Bringmann --- Changes in RFC: -- Separate DRMEM changes into a standalone patch -- Do not export excess functions. Make exported names more explicit. -- Add new iterator to work through a pair of drmem_info arrays. -- Modify DRMEM code to replace usages of dt_root_addr_cells, and dt_mem_next_cell, as these are only available at first boot. -- Rebase to 4.17-rc5 kernel -- Apply several code and patch cleanups. --- arch/powerpc/include/asm/drmem.h | 10 + arch/powerpc/mm/drmem.c | 73 -- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h index ce242b9..e82d254 100644 --- a/arch/powerpc/include/asm/drmem.h +++ b/arch/powerpc/include/asm/drmem.h @@ -35,6 +35,13 @@ struct drmem_lmb_info { &drmem_info->lmbs[0], \ &drmem_info->lmbs[drmem_info->n_lmbs - 1]) +#define for_each_pair_drmem_lmb(dinfo1, lmb1, dinfo2, lmb2)\ + for ((lmb1) = (&dinfo1->lmbs[0]), \ +(lmb2) = (&dinfo2->lmbs[0]); \ +((lmb1) <= (&dinfo1->lmbs[dinfo1->n_lmbs - 1])) && \ +((lmb2) <= (&dinfo2->lmbs[dinfo2->n_lmbs - 1])); \ +(lmb1)++, (lmb2)++) + /* * The of_drconf_cell_v1 struct defines the layout of the LMB data * specified in the ibm,dynamic-memory device tree property. @@ -94,6 +101,9 @@ void __init walk_drmem_lmbs(struct device_node *dn, void (*func)(struct drmem_lmb *, const __be32 **)); int drmem_update_dt(void); +struct drmem_lmb_info *drmem_lmbs_init(struct property *prop); +void drmem_lmbs_free(struct drmem_lmb_info *dinfo); + #ifdef CONFIG_PPC_PSERIES void __init walk_drmem_lmbs_early(unsigned long node, void (*func)(struct drmem_lmb *, const __be32 **)); diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index 3f18036..2bd6a70 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c @@ -20,6 +20,7 @@ static struct drmem_lmb_info __drmem_info; struct drmem_lmb_info *drmem_info = &__drmem_info; +static int n_root_addr_cells; u64 drmem_lmb_memory_max(void) { @@ -193,12 +194,13 @@ int drmem_update_dt(void) return rc; } -static void __init read_drconf_v1_cell(struct drmem_lmb *lmb, +static void read_drconf_v1_cell(struct drmem_lmb *lmb, const __be32 **prop) { const __be32 *p = *prop; - lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p); + lmb->base_addr = of_read_number(p, n_root_addr_cells); + p += n_root_addr_cells; lmb->drc_index = of_read_number(p++, 1); p++; /* skip reserved field */ @@ -209,7 +211,7 @@ static void __init read_drconf_v1_cell(struct drmem_lmb *lmb, *prop = p; } -static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, +static void __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, void (*func)(struct drmem_lmb *, const __be32 **)) { struct drmem_lmb lmb; @@ -225,13 +227,14 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, } } -static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell, +static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell, const __be32 **prop) { const __be32 *p = *prop; dr_cell->seq_lmbs = of_read_number(p++, 1); - dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p); + dr_cell->base_addr = of_read_number(p, n_root_addr_cells); + p += n_root_addr_cells; dr_cell->drc_index = of_read_number(p++, 1); dr_cell->aa_index = of_read_number(p++, 1); dr_cell->flags = of_read_number(p++, 1); @@ -239,7 +242,7 @@ static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell, *prop = p; } -static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, +static void __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, void (*func)(struct drmem_lmb *, const __be32 **)) { struct of_drconf_cell_v2 dr_cell; @@ -275,6 +278,9 @@ void __init walk_drmem_lmbs_early(unsigned long node, const __be32 *prop, *usm; int len; + if (n_root_addr_cells == 0) + n_root_addr_cells = dt_root_addr_cells; + prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); if (!prop || le
[RFC v5 2/6] powerpc/cpu: Conditionally acquire/release DRC index
powerpc/cpu: Modify dlpar_cpu_add and dlpar_cpu_remove to allow the skipping of DRC index acquire or release operations during the CPU add or remove operations. This is intended to support subsequent changes to provide a 'CPU readd' operation. Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 71 +++--- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index a408217..ec78cc6 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -474,7 +474,7 @@ static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index) &cdata); } -static ssize_t dlpar_cpu_add(u32 drc_index) +static ssize_t dlpar_cpu_add(u32 drc_index, bool acquire_drc) { struct device_node *dn, *parent; int rc, saved_rc; @@ -499,19 +499,22 @@ static ssize_t dlpar_cpu_add(u32 drc_index) return -EINVAL; } - rc = dlpar_acquire_drc(drc_index); - if (rc) { - pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n", - rc, drc_index); - of_node_put(parent); - return -EINVAL; + if (acquire_drc) { + rc = dlpar_acquire_drc(drc_index); + if (rc) { + pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n", + rc, drc_index); + of_node_put(parent); + return -EINVAL; + } } dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); if (!dn) { pr_warn("Failed call to configure-connector, drc index: %x\n", drc_index); - dlpar_release_drc(drc_index); + if (acquire_drc) + dlpar_release_drc(drc_index); of_node_put(parent); return -EINVAL; } @@ -526,8 +529,9 @@ static ssize_t dlpar_cpu_add(u32 drc_index) pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n", dn->name, rc, drc_index); - rc = dlpar_release_drc(drc_index); - if (!rc) + if (acquire_drc) + rc = dlpar_release_drc(drc_index); + if (!rc || acquire_drc) dlpar_free_cc_nodes(dn); return saved_rc; @@ -540,7 +544,7 @@ static ssize_t dlpar_cpu_add(u32 drc_index) dn->name, rc, drc_index); rc = dlpar_detach_node(dn); - if (!rc) + if (!rc && acquire_drc) dlpar_release_drc(drc_index); return saved_rc; @@ -608,7 +612,8 @@ static int dlpar_offline_cpu(struct device_node *dn) } -static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) +static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index, + bool release_drc) { int rc; @@ -621,12 +626,14 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) return -EINVAL; } - rc = dlpar_release_drc(drc_index); - if (rc) { - pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n", - drc_index, dn->name, rc); - dlpar_online_cpu(dn); - return rc; + if (release_drc) { + rc = dlpar_release_drc(drc_index); + if (rc) { + pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n", + drc_index, dn->name, rc); + dlpar_online_cpu(dn); + return rc; + } } rc = dlpar_detach_node(dn); @@ -635,7 +642,10 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index) pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc); - rc = dlpar_acquire_drc(drc_index); + if (release_drc) + rc = dlpar_acquire_drc(drc_index); + else + rc = 0; if (!rc) dlpar_online_cpu(dn); @@ -664,7 +674,7 @@ static struct device_node *cpu_drc_index_to_dn(u32 drc_index) return dn; } -static int dlpar_cpu_remove_by_index(u32 drc_index) +static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc) { struct device_node *dn; int rc; @@ -676,7 +686,7 @@ static int dlpar_cpu_remove_by_index(u32 drc_index) return -ENODEV; } - rc = dlpar_cpu_remove(dn, drc_index); + rc = dlpar_cpu_remove(dn, drc_index, release_drc); of_node_put(dn); return rc; } @@ -741,7 +751,7 @@ static int dlpar_
[RFC v5 3/6] migration/dlpar: Add device readd queuing function
migration/dlpar: This patch adds function dlpar_readd_action() which will queue a worker function to 'readd' a device in the system. Such devices must be identified by a 'resource' type and a drc_index to be readded. Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/dlpar.c | 14 ++ arch/powerpc/platforms/pseries/pseries.h |1 + 2 files changed, 15 insertions(+) diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index a0b20c0..a14684e 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -407,6 +407,20 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, } } +int dlpar_queue_action(int resource, int action, u32 drc_index) +{ + struct pseries_hp_errorlog hp_elog; + + hp_elog.resource = resource; + hp_elog.action = action; + hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; + hp_elog._drc_u.drc_index = drc_index; + + queue_hotplug_event(&hp_elog, NULL, NULL); + + return 0; +} + static int dlpar_parse_resource(char **cmd, struct pseries_hp_errorlog *hp_elog) { char *arg; diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 60db2ee..cb2beb1 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -61,6 +61,7 @@ extern struct device_node *dlpar_configure_connector(__be32, void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, struct completion *hotplug_done, int *rc); +extern int dlpar_queue_action(int resource, int action, u32 drc_index); #ifdef CONFIG_MEMORY_HOTPLUG int dlpar_memory(struct pseries_hp_errorlog *hp_elog); #else
[RFC v5 4/6] powerpc/dlpar: Provide CPU readd operation
powerpc/dlpar: Provide hotplug CPU 'readd by index' operation to support LPAR Post Migration state updates. When such changes are invoked by the PowerPC 'mobility' code, they will be queued up so that modifications to CPU properties will take place after the new property value is written to the device-tree. Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 29 ++ 1 file changed, 29 insertions(+) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index ec78cc6..ac08d85 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -691,6 +691,26 @@ static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc) return rc; } +static int dlpar_cpu_readd_by_index(u32 drc_index) +{ + int rc = 0; + + pr_info("Attempting to re-add CPU, drc index %x\n", drc_index); + + rc = dlpar_cpu_remove_by_index(drc_index, false); + if (!rc) + rc = dlpar_cpu_add(drc_index, false); + + if (rc) + pr_info("Failed to update cpu at drc_index %lx\n", + (unsigned long int)drc_index); + else + pr_info("CPU at drc_index %lx was updated\n", + (unsigned long int)drc_index); + + return rc; +} + static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove) { struct device_node *dn; @@ -902,6 +922,9 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) else rc = -EINVAL; break; + case PSERIES_HP_ELOG_ACTION_READD: + rc = dlpar_cpu_readd_by_index(drc_index); + break; default: pr_err("Invalid action (%d) specified\n", hp_elog->action); rc = -EINVAL; @@ -968,6 +991,12 @@ static int pseries_smp_notifier(struct notifier_block *nb, case OF_RECONFIG_DETACH_NODE: pseries_remove_processor(rd->dn); break; + case OF_RECONFIG_UPDATE_PROPERTY: + if (!strcmp(rd->prop->name, "ibm,associativity")) + dlpar_queue_action(PSERIES_HP_ELOG_RESOURCE_CPU, + PSERIES_HP_ELOG_ACTION_READD, + be32_to_cpu(rd->dn->phandle)); + break; } return notifier_from_errno(err); }
[RFC v5 5/6] powerpc/mobility: Add lock/unlock device hotplug
powerpc/mobility: Add device lock/unlock to PowerPC 'mobility' operation to delay the operation of CPU DLPAR work queue operations by the 'readd' activity until after any changes to the corresponding device-tree properties have been written. Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/mobility.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 8a8033a..6d98f84 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -283,6 +283,8 @@ int pseries_devicetree_update(s32 scope) if (!rtas_buf) return -ENOMEM; + lock_device_hotplug(); + do { rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope); if (rc && rc != 1) @@ -321,6 +323,7 @@ int pseries_devicetree_update(s32 scope) } while (rc == 1); kfree(rtas_buf); + unlock_device_hotplug(); return rc; }
[RFC v5 6/6] migration/memory: Update memory for assoc changes
migration/memory: This patch adds more recognition for changes to the associativity of memory blocks described by the device-tree properties and updates local and general kernel data structures to reflect those changes. These differences may include: * Evaluating 'ibm,dynamic-memory' properties when processing the topology of LPARS in Post Migration events. Previous efforts only recognized whether a memory block's assignment had changed in the property. Changes here include checking the aa_index values for each drc_index of the old/new LMBs and to 'readd' any block for which the setting has changed. * In an LPAR migration scenario, the "ibm,associativity-lookup-arrays" property may change. In the event that a row of the array differs, locate all assigned memory blocks with that 'aa_index' and 're-add' them to the system memory block data structures. In the process of the 're-add', the system routines will update the corresponding entry for the memory in the LMB structures and any other relevant kernel data structures. * Extend the previous work for the 'ibm,associativity-lookup-array' and 'ibm,dynamic-memory' properties to support the property 'ibm,dynamic-memory-v2' by means of the DRMEM LMB interpretation code. Signed-off-by: Michael Bringmann --- Changes in RFC: -- Simplify code to update memory nodes during mobility checks. -- Reuse code from DRMEM changes to scan for LMBs when updating aa_index -- Combine common code for properties 'ibm,dynamic-memory' and 'ibm,dynamic-memory-v2' after integrating DRMEM features. -- Rearrange patches to co-locate memory property-related changes. -- Use new paired list iterator for the drmem info arrays. -- Use direct calls to add/remove memory from the update drconf function as those operations are only intended for user DLPAR ops, and should not occur during Migration reconfig notifier changes. -- Correct processing bug in processing of ibm,associativity-lookup-arrays -- Rebase to 4.17-rc5 kernel -- Apply minor code cleanups --- arch/powerpc/platforms/pseries/hotplug-memory.c | 153 ++- 1 file changed, 121 insertions(+), 32 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index c1578f5..ac329aa 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -994,13 +994,11 @@ static int pseries_add_mem_node(struct device_node *np) return (ret < 0) ? -EINVAL : 0; } -static int pseries_update_drconf_memory(struct of_reconfig_data *pr) +static int pseries_update_drconf_memory(struct drmem_lmb_info *new_dinfo) { - struct of_drconf_cell_v1 *new_drmem, *old_drmem; + struct drmem_lmb *old_lmb, *new_lmb; unsigned long memblock_size; - u32 entries; - __be32 *p; - int i, rc = -EINVAL; + int rc = 0; if (rtas_hp_event) return 0; @@ -1009,42 +1007,124 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr) if (!memblock_size) return -EINVAL; - p = (__be32 *) pr->old_prop->value; - if (!p) - return -EINVAL; + /* Arrays should have the same size and DRC indexes */ + for_each_pair_drmem_lmb(drmem_info, old_lmb, new_dinfo, new_lmb) { - /* The first int of the property is the number of lmb's described -* by the property. This is followed by an array of of_drconf_cell -* entries. Get the number of entries and skip to the array of -* of_drconf_cell's. -*/ - entries = be32_to_cpu(*p++); - old_drmem = (struct of_drconf_cell_v1 *)p; - - p = (__be32 *)pr->prop->value; - p++; - new_drmem = (struct of_drconf_cell_v1 *)p; + if (new_lmb->drc_index != old_lmb->drc_index) + continue; - for (i = 0; i < entries; i++) { - if ((be32_to_cpu(old_drmem[i].flags) & DRCONF_MEM_ASSIGNED) && - (!(be32_to_cpu(new_drmem[i].flags) & DRCONF_MEM_ASSIGNED))) { + if ((old_lmb->flags & DRCONF_MEM_ASSIGNED) && + (!(new_lmb->flags & DRCONF_MEM_ASSIGNED))) { rc = pseries_remove_memblock( - be64_to_cpu(old_drmem[i].base_addr), -memblock_size); + old_lmb->base_addr, memblock_size); break; - } else if ((!(be32_to_cpu(old_drmem[i].flags) & - DRCONF_MEM_ASSIGNED)) && - (be32_to_cpu(new_drmem[i].flags) & - DRCONF_MEM_ASSIGNED)) { - rc = memblock_add(be64_to_cpu(old_drmem[i].base_addr), - memblock_size); + } else if ((!(old_lmb->flags & D
Re: [PATCH bpf v2 6/6] bpf: fix JITed dump for multi-function programs via syscall
Hi Daniel, On 05/18/2018 09:21 PM, Daniel Borkmann wrote: > On 05/18/2018 02:50 PM, Sandipan Das wrote: >> Currently, for multi-function programs, we cannot get the JITed >> instructions using the bpf system call's BPF_OBJ_GET_INFO_BY_FD >> command. Because of this, userspace tools such as bpftool fail >> to identify a multi-function program as being JITed or not. >> >> With the JIT enabled and the test program running, this can be >> verified as follows: >> >> # cat /proc/sys/net/core/bpf_jit_enable >> 1 >> >> Before applying this patch: >> >> # bpftool prog list >> 1: kprobe name foo tag b811aab41a39ad3d gpl >> loaded_at 2018-05-16T11:43:38+0530 uid 0 >> xlated 216B not jited memlock 65536B >> ... >> >> # bpftool prog dump jited id 1 >> no instructions returned >> >> After applying this patch: >> >> # bpftool prog list >> 1: kprobe name foo tag b811aab41a39ad3d gpl >> loaded_at 2018-05-16T12:13:01+0530 uid 0 >> xlated 216B jited 308B memlock 65536B >> ... > > That's really nice! One comment inline below: > >> # bpftool prog dump jited id 1 >> 0: nop >> 4: nop >> 8: mflrr0 >> c: std r0,16(r1) >> 10: stdur1,-112(r1) >> 14: std r31,104(r1) >> 18: addir31,r1,48 >> 1c: li r3,10 >> ... >> >> Signed-off-by: Sandipan Das >> --- >> kernel/bpf/syscall.c | 38 -- >> 1 file changed, 32 insertions(+), 6 deletions(-) >> >> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c >> index 54a72fafe57c..2430d159078c 100644 >> --- a/kernel/bpf/syscall.c >> +++ b/kernel/bpf/syscall.c >> @@ -1896,7 +1896,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog >> *prog, >> struct bpf_prog_info info = {}; >> u32 info_len = attr->info.info_len; >> char __user *uinsns; >> -u32 ulen; >> +u32 ulen, i; >> int err; >> >> err = check_uarg_tail_zero(uinfo, sizeof(info), info_len); >> @@ -1922,7 +1922,6 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog >> *prog, >> ulen = min_t(u32, info.nr_map_ids, ulen); >> if (ulen) { >> u32 __user *user_map_ids = u64_to_user_ptr(info.map_ids); >> -u32 i; >> >> for (i = 0; i < ulen; i++) >> if (put_user(prog->aux->used_maps[i]->id, >> @@ -1970,13 +1969,41 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog >> *prog, >> * for offload. >> */ >> ulen = info.jited_prog_len; >> -info.jited_prog_len = prog->jited_len; >> +if (prog->aux->func_cnt) { >> +info.jited_prog_len = 0; >> +for (i = 0; i < prog->aux->func_cnt; i++) >> +info.jited_prog_len += prog->aux->func[i]->jited_len; >> +} else { >> +info.jited_prog_len = prog->jited_len; >> +} >> + >> if (info.jited_prog_len && ulen) { >> if (bpf_dump_raw_ok()) { >> uinsns = u64_to_user_ptr(info.jited_prog_insns); >> ulen = min_t(u32, info.jited_prog_len, ulen); >> -if (copy_to_user(uinsns, prog->bpf_func, ulen)) >> -return -EFAULT; >> + >> +/* for multi-function programs, copy the JITed >> + * instructions for all the functions >> + */ >> +if (prog->aux->func_cnt) { >> +u32 len, free; >> +u8 *img; >> + >> +free = ulen; >> +for (i = 0; i < prog->aux->func_cnt; i++) { >> +len = prog->aux->func[i]->jited_len; >> +img = (u8 *) >> prog->aux->func[i]->bpf_func; >> +if (len > free) >> +break; >> +if (copy_to_user(uinsns, img, len)) >> +return -EFAULT; >> +uinsns += len; >> +free -= len; > > Is there any way we can introduce a delimiter between the different > images such that they could be more easily correlated with the call > from the main (or other sub-)program instead of having one contiguous > dump blob? > Can we have another member in bpf_prog_info that points to a list of the lengths of the JITed images for each subprogram? We can use this information to split up the dump. - Sandipan >> +} >> +} else { >> +if (copy_to_user(uinsns, prog->bpf_func, ulen)) >> +return -EFAULT; >> +} >> } else { >> info.jited_prog_insns = 0; >> } >> @@ -1987,7 +2014,6 @@ static int bpf_prog_get_info_by_fd(struc
Re: [PATCH v2] powerpc/64s/radix: do not flush TLB when relaxing access
Hi Nicholas, I love your patch! Yet something to improve: [auto build test ERROR on v4.17-rc6] [cannot apply to powerpc/next next-20180517] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-radix-do-not-flush-TLB-when-relaxing-access/20180522-024317 config: powerpc-bamboo_defconfig (attached as .config) compiler: powerpc-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): arch/powerpc/mm/pgtable.c: In function 'ptep_set_access_flags': >> arch/powerpc/mm/pgtable.c:246:32: error: 'mm_context_t {aka struct >> }' has no member named 'copros' if (atomic_read(&mm->context.copros) > 0) ^ vim +246 arch/powerpc/mm/pgtable.c 209 210 /* 211 * This is called when relaxing access to a PTE. It's also called in the page 212 * fault path when we don't hit any of the major fault cases, ie, a minor 213 * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have 214 * handled those two for us, we additionally deal with missing execute 215 * permission here on some processors 216 */ 217 int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, 218pte_t *ptep, pte_t entry, int dirty) 219 { 220 struct mm_struct *mm = vma->vm_mm; 221 int changed; 222 223 entry = set_access_flags_filter(entry, vma, dirty); 224 changed = !pte_same(*(ptep), entry); 225 if (changed) { 226 if (!is_vm_hugetlb_page(vma)) 227 assert_pte_locked(mm, address); 228 __ptep_set_access_flags(mm, ptep, entry, address); 229 if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) { 230 /* 231 * Book3S does not require a TLB flush when relaxing 232 * access restrictions because the core MMU will reload 233 * the pte after taking an access fault. However the 234 * NMMU on POWER9 does not re-load the pte, so flush 235 * if we have a coprocessor attached to this address 236 * space. 237 * 238 * This could be further refined and pushed out to 239 * NMMU drivers so TLBIEs are only done for NMMU 240 * faults, but this is a more minimal fix. The NMMU 241 * fault handler does a get_user_pages_remote or 242 * similar to bring the page tables in, and this 243 * flush_tlb_page will do a global TLBIE because the 244 * coprocessor is attached to the address space. 245 */ > 246 if (atomic_read(&mm->context.copros) > 0) 247 flush_tlb_page(vma, address); 248 } else { 249 flush_tlb_page(vma, address); 250 } 251 } 252 return changed; 253 } 254 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH ] powerpc/pkeys: Detach execute_only key on !PROT_EXEC
Ram Pai writes: > Disassociate the exec_key from a VMA if the VMA permission is not > PROT_EXEC anymore. Otherwise the exec_only key continues to be > associated with the vma, causing unexpected behavior. > > The problem was reported on x86 by Shakeel Butt, > which is also applicable on powerpc. > > cc: Shakeel Butt > Reported-by: Shakeel Butt > Fixes 5586cf6 ("powerpc: introduce execute-only pkey") ^ Missing a colon here. > Signed-off-by: Ram Pai > --- > arch/powerpc/mm/pkeys.c |4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/powerpc/mm/pkeys.c b/arch/powerpc/mm/pkeys.c > index e81d59e..fdeb9f5 100644 > --- a/arch/powerpc/mm/pkeys.c > +++ b/arch/powerpc/mm/pkeys.c > @@ -425,9 +425,9 @@ int __arch_override_mprotect_pkey(struct vm_area_struct > *vma, int prot, > { > /* >* If the currently associated pkey is execute-only, but the requested > - * protection requires read or write, move it back to the default pkey. > + * protection is not execute-only, move it back to the default pkey. >*/ > - if (vma_is_pkey_exec_only(vma) && (prot & (PROT_READ | PROT_WRITE))) > + if (vma_is_pkey_exec_only(vma) && (prot != PROT_EXEC)) > return 0; > > /* I think I'm slow today. It took me a while to figure out why this is buggy. It will leave the VMA with the execute-only pkey if prot = 0. Other bit combinations work fine IIUC. Reviewed-by: Thiago Jung Bauermann -- Thiago Jung Bauermann IBM Linux Technology Center
Re: [PATCH 1/2] powerpc: Detect the presence of big-core with interleaved threads
Hello Michael, On Fri, May 18, 2018 at 11:14:04PM +1000, Michael Ellerman wrote: > Gautham R Shenoy writes: > ... > >> > @@ -565,7 +615,16 @@ void __init smp_setup_cpu_maps(void) > >> > vdso_data->processorCount = num_present_cpus(); > >> > #endif /* CONFIG_PPC64 */ > >> > > >> > -/* Initialize CPU <=> thread mapping/ > >> > +dn = of_find_node_by_type(NULL, "cpu"); > >> > +if (dn) { > >> > +if (check_for_interleaved_big_core(dn)) { > >> > +has_interleaved_big_core = true; > >> > +pr_info("Detected interleaved big-cores\n"); > >> > >> Is there a runtime way to check this also? If the dmesg buffer overflows, > >> we > >> lose this. > > > > Where do you suggest we put this ? Should it be a part of > > /proc/cpuinfo ? > > Hmm, it'd be nice not to pollute it with more junk. > > Can you just look at the pir files in sysfs? Sure Michael. I will explore this option. If we add a file called l1cache_thread_group, then the siblings of the big-core that share the L1-cache can be described as follows. # cd /sys/devices/system/cpu # grep . cpu[0-7]/l1cache_thread_group cpu0/l1cache_thread_group:0,2,4,6 cpu1/l1cache_thread_group:1,3,5,7 cpu2/l1cache_thread_group:0,2,4,6 cpu3/l1cache_thread_group:1,3,5,7 cpu4/l1cache_thread_group:0,2,4,6 cpu5/l1cache_thread_group:1,3,5,7 cpu6/l1cache_thread_group:0,2,4,6 cpu7/l1cache_thread_group:1,3,5,7 > > eg. on a normal system: > > # cd /sys/devices/system/cpu > # grep . cpu[0-7]/pir > cpu0/pir:20 > cpu1/pir:21 > cpu2/pir:22 > cpu3/pir:23 > cpu4/pir:24 > cpu5/pir:25 > cpu6/pir:26 > cpu7/pir:27 > > > cheers >
Re: [PATCH 1/2] powerpc: Detect the presence of big-core with interleaved threads
Hello Michael, On Fri, May 18, 2018 at 11:21:22PM +1000, Michael Ellerman wrote: > "Gautham R. Shenoy" writes: > > > diff --git a/arch/powerpc/kernel/setup-common.c > > b/arch/powerpc/kernel/setup-common.c > > index 0af5c11..884dff2 100644 > > --- a/arch/powerpc/kernel/setup-common.c > > +++ b/arch/powerpc/kernel/setup-common.c > > @@ -436,8 +438,56 @@ static void __init cpu_init_thread_core_maps(int tpc) > > printk(KERN_DEBUG " (thread shift is %d)\n", threads_shift); > > } > > > > - > > u32 *cpu_to_phys_id = NULL; > > +/* > > + * check_for_interleaved_big_core - Checks if the core represented by > > + * dn is a big-core whose threads are interleavings of the > > + * threads of the component small cores. > > + * > > + * @dn: device node corresponding to the core. > > + * > > + * Returns true if the core is a interleaved big-core. > > + * Returns false otherwise. > > + */ > > +static inline bool check_for_interleaved_big_core(struct device_node *dn) > > +{ > > + int len, nr_groups, threads_per_group; > > + const __be32 *thread_groups; > > + __be32 *thread_list, *first_cpu_idx; > > + int cur_cpu, next_cpu, i, j; > > + > > + thread_groups = of_get_property(dn, "ibm,thread-groups", &len); > > + if (!thread_groups) > > + return false; > > There are better device tree APIs than bare of_get_property() these > days, can you try to use those? Ok, I will use them. > > > + nr_groups = be32_to_cpu(*(thread_groups + 1)); > > + if (nr_groups <= 1) > > + return false; > > eg. this would be of_property_read_u32_index() > Ok. > > @@ -565,7 +615,16 @@ void __init smp_setup_cpu_maps(void) > > vdso_data->processorCount = num_present_cpus(); > > #endif /* CONFIG_PPC64 */ > > > > -/* Initialize CPU <=> thread mapping/ > > + dn = of_find_node_by_type(NULL, "cpu"); > > + if (dn) { > > + if (check_for_interleaved_big_core(dn)) { > > + has_interleaved_big_core = true; > > + pr_info("Detected interleaved big-cores\n"); > > + } > > + of_node_put(dn); > > + } > > This is a bit untidy, given how unlikely it is that you would have no > CPUs :) This can actually go into the earlier loop where we initialize the smp_processor_ids(). I have fixed it in the next iteration. > > You should be able to do the lookup of the property and the setting of > has_interleaved_big_core all inside > check_for_interleaved_big_core(). Yes, that's what I am doing in the next iteration. > > cheers >
[PATCH v2] powerpc/32: Implement csum_ipv6_magic in assembly
The generic csum_ipv6_magic() generates a pretty bad result : 0: 81 23 00 00 lwz r9,0(r3) 4: 81 03 00 04 lwz r8,4(r3) 8: 7c e7 4a 14 add r7,r7,r9 c: 7d 29 38 10 subfc r9,r9,r7 10: 7d 4a 51 10 subfe r10,r10,r10 14: 7d 27 42 14 add r9,r7,r8 18: 7d 2a 48 50 subfr9,r10,r9 1c: 80 e3 00 08 lwz r7,8(r3) 20: 7d 08 48 10 subfc r8,r8,r9 24: 7d 4a 51 10 subfe r10,r10,r10 28: 7d 29 3a 14 add r9,r9,r7 2c: 81 03 00 0c lwz r8,12(r3) 30: 7d 2a 48 50 subfr9,r10,r9 34: 7c e7 48 10 subfc r7,r7,r9 38: 7d 4a 51 10 subfe r10,r10,r10 3c: 7d 29 42 14 add r9,r9,r8 40: 7d 2a 48 50 subfr9,r10,r9 44: 80 e4 00 00 lwz r7,0(r4) 48: 7d 08 48 10 subfc r8,r8,r9 4c: 7d 4a 51 10 subfe r10,r10,r10 50: 7d 29 3a 14 add r9,r9,r7 54: 7d 2a 48 50 subfr9,r10,r9 58: 81 04 00 04 lwz r8,4(r4) 5c: 7c e7 48 10 subfc r7,r7,r9 60: 7d 4a 51 10 subfe r10,r10,r10 64: 7d 29 42 14 add r9,r9,r8 68: 7d 2a 48 50 subfr9,r10,r9 6c: 80 e4 00 08 lwz r7,8(r4) 70: 7d 08 48 10 subfc r8,r8,r9 74: 7d 4a 51 10 subfe r10,r10,r10 78: 7d 29 3a 14 add r9,r9,r7 7c: 7d 2a 48 50 subfr9,r10,r9 80: 81 04 00 0c lwz r8,12(r4) 84: 7c e7 48 10 subfc r7,r7,r9 88: 7d 4a 51 10 subfe r10,r10,r10 8c: 7d 29 42 14 add r9,r9,r8 90: 7d 2a 48 50 subfr9,r10,r9 94: 7d 08 48 10 subfc r8,r8,r9 98: 7d 4a 51 10 subfe r10,r10,r10 9c: 7d 29 2a 14 add r9,r9,r5 a0: 7d 2a 48 50 subfr9,r10,r9 a4: 7c a5 48 10 subfc r5,r5,r9 a8: 7c 63 19 10 subfe r3,r3,r3 ac: 7d 29 32 14 add r9,r9,r6 b0: 7d 23 48 50 subfr9,r3,r9 b4: 7c c6 48 10 subfc r6,r6,r9 b8: 7c 63 19 10 subfe r3,r3,r3 bc: 7c 63 48 50 subfr3,r3,r9 c0: 54 6a 80 3e rotlwi r10,r3,16 c4: 7c 63 52 14 add r3,r3,r10 c8: 7c 63 18 f8 not r3,r3 cc: 54 63 84 3e rlwinm r3,r3,16,16,31 d0: 4e 80 00 20 blr This patch implements it in assembly for PPC32 Link: https://github.com/linuxppc/linux/issues/9 Signed-off-by: Christophe Leroy --- v2: Fix number of args in final addze arch/powerpc/include/asm/checksum.h | 8 arch/powerpc/lib/checksum_32.S | 33 + 2 files changed, 41 insertions(+) diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index 54065caa40b3..c41c280c252f 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -13,6 +13,7 @@ #include #else #include +#include /* * Computes the checksum of a memory block at src, length len, * and adds in "sum" (32-bit), while copying the block to dst. @@ -211,6 +212,13 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) return csum_fold(csum_partial(buff, len, 0)); } +#ifdef CONFIG_PPC32 +#define _HAVE_ARCH_IPV6_CSUM +__sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum sum); +#endif + #endif #endif /* __KERNEL__ */ #endif diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index 9a671c774b22..9167ab088f04 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S @@ -293,3 +293,36 @@ dst_error: EX_TABLE(51b, dst_error); EXPORT_SYMBOL(csum_partial_copy_generic) + +/* + * static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + * const struct in6_addr *daddr, + * __u32 len, __u8 proto, __wsum sum) + */ + +_GLOBAL(csum_ipv6_magic) + lwz r8, 0(r3) + lwz r9, 4(r3) + lwz r10, 8(r3) + lwz r11, 12(r3) + addcr0, r5, r6 + adder0, r0, r7 + adder0, r0, r8 + adder0, r0, r9 + adder0, r0, r10 + adder0, r0, r11 + lwz r8, 0(r4) + lwz r9, 4(r4) + lwz r10, 8(r4) + lwz r11, 12(r4) + adder0, r0, r8 + adder0, r0, r9 + adder0, r0, r10 + adder0, r0, r11 + addze r0, r0 + rotlwi r3, r0, 16 + add r3, r0, r3 + not r3, r3 + rlwinm r3, r3, 16, 16, 31 + blr +EXPORT_SYMBOL(csum_ipv6_magic) -- 2.13.3
[PATCH] selftests/powerpc: Add missing .gitignores
Signed-off-by: Michael Neuling --- tools/testing/selftests/powerpc/alignment/.gitignore | 1 + tools/testing/selftests/powerpc/tm/.gitignore| 1 + 2 files changed, 2 insertions(+) diff --git a/tools/testing/selftests/powerpc/alignment/.gitignore b/tools/testing/selftests/powerpc/alignment/.gitignore index 1d980e3d70..9d383073b7 100644 --- a/tools/testing/selftests/powerpc/alignment/.gitignore +++ b/tools/testing/selftests/powerpc/alignment/.gitignore @@ -3,3 +3,4 @@ copy_first_unaligned paste_unaligned paste_last_unaligned copy_paste_unaligned_common +alignment_handler diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index bb90d4b795..c3ee8393da 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -14,3 +14,4 @@ tm-signal-context-chk-vsx tm-vmx-unavail tm-unavailable tm-trap +tm-sigreturn -- 2.17.0
[PATCH 1/2] selftests/powerpc: Add ptrace hw breakpoint test
This test the ptrace hw breakpoints via PTRACE_SET_DEBUGREG and PPC_PTRACE_SETHWDEBUG. This test was use to find the bugs fixed by these recent commits: 4f7c06e26e powerpc/ptrace: Fix setting 512B aligned breakpoints with PTRACE_SET_DEBUGREG cd6ef7eebf powerpc/ptrace: Fix enforcement of DAWR constraints Signed-off-by: Michael Neuling --- This test (and the next) could be expanded to do a bunch more but it's been sitting out of tree too long, so trying to get them upstream. --- .../selftests/powerpc/ptrace/.gitignore | 1 + .../testing/selftests/powerpc/ptrace/Makefile | 2 +- .../selftests/powerpc/ptrace/ptrace-hwbreak.c | 341 ++ 3 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c diff --git a/tools/testing/selftests/powerpc/ptrace/.gitignore b/tools/testing/selftests/powerpc/ptrace/.gitignore index 349acfafc9..9dcc16ea81 100644 --- a/tools/testing/selftests/powerpc/ptrace/.gitignore +++ b/tools/testing/selftests/powerpc/ptrace/.gitignore @@ -8,3 +8,4 @@ ptrace-vsx ptrace-tm-vsx ptrace-tm-spd-vsx ptrace-tm-spr +ptrace-hwbreak diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile index 4803052665..0e2f4601d1 100644 --- a/tools/testing/selftests/powerpc/ptrace/Makefile +++ b/tools/testing/selftests/powerpc/ptrace/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \ ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \ - ptrace-tm-spd-vsx ptrace-tm-spr + ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c new file mode 100644 index 00..792cdea266 --- /dev/null +++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c @@ -0,0 +1,341 @@ +/* + * Ptrace test for hw breakpoints + * + * Based on tools/testing/selftests/breakpoints/breakpoint_test.c + * + * This test forks and the parent then traces the child doing various + * types of ptrace enabled breakpoints + * + * Copyright (C) 2018 Michael Neuling, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ptrace.h" + +/* Breakpoint access modes */ +enum { + BP_X = 1, + BP_RW = 2, + BP_W = 4, +}; + +static pid_t child_pid; +static struct ppc_debug_info dbginfo; + +static void get_dbginfo(void) +{ + int ret; + + ret = ptrace(PPC_PTRACE_GETHWDBGINFO, child_pid, NULL, &dbginfo); + if (ret) { + perror("Can't get breakpoint info\n"); + exit(-1); + } +} + +static bool hwbreak_present(void) +{ + return (dbginfo.num_data_bps != 0); +} + +static bool dawr_present(void) +{ + return !!(dbginfo.features & PPC_DEBUG_FEATURE_DATA_BP_DAWR); +} + +static void set_breakpoint_addr(void *addr) +{ + int ret; + + ret = ptrace(PTRACE_SET_DEBUGREG, child_pid, 0, addr); + if (ret) { + perror("Can't set breakpoint addr\n"); + exit(-1); + } +} + +static int set_hwbreakpoint_addr(void *addr, int range) +{ + int ret; + + struct ppc_hw_breakpoint info; + + info.version = 1; + info.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; + info.addr_mode = PPC_BREAKPOINT_MODE_EXACT; + if (range > 0) + info.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; + info.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; + info.addr = (__u64)addr; + info.addr2 = (__u64)addr + range; + info.condition_value = 0; + + ret = ptrace(PPC_PTRACE_SETHWDEBUG, child_pid, 0, &info); + if (ret < 0) { + perror("Can't set breakpoint\n"); + exit(-1); + } + return ret; +} + +static int del_hwbreakpoint_addr(int watchpoint_handle) +{ + int ret; + + ret = ptrace(PPC_PTRACE_DELHWDEBUG, child_pid, 0, watchpoint_handle); + if (ret < 0) { + perror("Can't delete hw breakpoint\n"); + exit(-1); + } + return ret; +} + +#define DAWR_LENGTH_MAX 512 + +/* Dummy variables to test read/write accesses */ +static unsigned long long dummy_array[DAWR_LENGTH_MAX/sizeof(unsigned long long)] __attribute__ ((aligned (512))); +static unsigned long long *dummy_var = dummy_array; + +static void write_var(int len) +{ + char *pcval; short *psval; int *pival; long long *plval; + + switch (len) { + case 1: + pcval = (char *)dummy_var;
[PATCH 2/2] selftests/powerpc: Add perf breakpoint test
This tests perf hardware breakpoints (ie PERF_TYPE_BREAKPOINT) on powerpc. Signed-off-by: Michael Neuling --- .../selftests/powerpc/ptrace/.gitignore | 1 + .../testing/selftests/powerpc/ptrace/Makefile | 3 +- .../selftests/powerpc/ptrace/perf-hwbreak.c | 214 ++ 3 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c diff --git a/tools/testing/selftests/powerpc/ptrace/.gitignore b/tools/testing/selftests/powerpc/ptrace/.gitignore index 9dcc16ea81..07ec449a27 100644 --- a/tools/testing/selftests/powerpc/ptrace/.gitignore +++ b/tools/testing/selftests/powerpc/ptrace/.gitignore @@ -9,3 +9,4 @@ ptrace-tm-vsx ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak +perf-hwbreak diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile index 0e2f4601d1..532f5dda37 100644 --- a/tools/testing/selftests/powerpc/ptrace/Makefile +++ b/tools/testing/selftests/powerpc/ptrace/Makefile @@ -1,13 +1,14 @@ # SPDX-License-Identifier: GPL-2.0 TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \ ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \ - ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak + ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak perf-hwbreak include ../../lib.mk all: $(TEST_PROGS) CFLAGS += -m64 -I../../../../../usr/include -I../tm -mhtm -fno-pie +LDLIBS += -lpthread $(TEST_PROGS): ../harness.c ../utils.c ../lib/reg.S ptrace.h diff --git a/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c new file mode 100644 index 00..4ab7059029 --- /dev/null +++ b/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c @@ -0,0 +1,214 @@ +/* + * perf events self profiling example test case for hw breakpoints. + * + * Start an number of threads. In each thread setup a breakpoint with + * a number of variables: + * 1) number of times we loop over it + * 2) read, write or read&write match + * 3) exclude userspace + * setup this breakpoint, then read and write the data a number of times. + * Then check the output count from perf is as expected. + * + * Based on: + * http://ozlabs.org/~anton/junkcode/perf_events_example1.c + * + * Copyright (C) 2018 Michael Neuling, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +int max_loops; +int num_threads; +int fail = 0; +int arraytest; + +#define DAWR_LENGTH_MAX ((0x3f + 1) * 8) + +static inline int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, + int cpu, int group_fd, + unsigned long flags) +{ + attr->size = sizeof(*attr); + return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); +} + +static inline bool breakpoint_test(int len) +{ + struct perf_event_attr attr; + int fd; + + /* setup counters */ + memset(&attr, 0, sizeof(attr)); + attr.disabled = 1; + attr.type = PERF_TYPE_BREAKPOINT; + attr.bp_type = HW_BREAKPOINT_R; + /* bp_addr can point anywhere but needs to be aligned */ + attr.bp_addr = (__u64)(&attr) & 0xf800; + attr.bp_len = len; + fd = sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd < 0) + return false; + close(fd); + return true; +} + +static inline bool perf_breakpoint_supported(void) +{ + return breakpoint_test(4); +} + +static inline bool dawr_supported(void) +{ + return breakpoint_test(DAWR_LENGTH_MAX); +} + +/* + */ +static void *runtestsingle(void *vptr_args) +{ + int i,j; + struct perf_event_attr attr; + size_t res; + unsigned long long breaks, needed; + int readint; /* random stacks will give diff addr here */ + int readintarraybig[2*DAWR_LENGTH_MAX/sizeof(int)]; + int *readintalign; + volatile int *ptr; + int break_fd; + int loop_num = rand() % max_loops; + int readwriteflag = (rand() % 3) + 1; /* needs to be 1-3 */ + int exclude_user = rand() % 2; + volatile int *k; + + /* align to 0x400 boundary as required by DAWR */ + readintalign = (int *)(((unsigned long)readintarraybig + 0x7ff) & 0xf800); + + ptr = &readint; + if (arraytest) + ptr = &readintalign[0]; + + /* setup counters */ + memset(&attr, 0, sizeof(attr)); + attr.disabled = 1; + attr.type = PERF_TYPE_BREAKPOINT; + attr.bp_type = readwriteflag; + at
Re: [PATCH 00/19] powerpc/ppc32: make W=1 compilation errors free
Any chance this could be applied to powerpc/next ? On Thu, Mar 22, 2018 at 9:19 PM, Mathieu Malaterre wrote: > Here is another batch for warnings treated as error on ppc32. Tested with: > > $ make ARCH=powerpc ppc32_defconfig > $ make -j8 ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- W=1 > > Using: > > $ powerpc-linux-gnu-gcc --version > powerpc-linux-gnu-gcc (Debian 6.3.0-18) 6.3.0 20170516 > > Mathieu Malaterre (19): > powerpc/powermac: Mark variable x as unused > powerpc/powermac: Mark variable x as unused > powerpc: Mark variables as unused > powerpc/kvm: Mark variable tmp unused > powerpc/chrp/setup: Add attribute unused and make some functions > static > powerpc: Make function btext_initialize static > powerpc/powermac: Make some functions static > powerpc/tau: Make some function static > powerpc/chrp/pci: Make some functions static > powerpc/chrp/time: Make some functions static, add missing header > include > powerpc/powermac: Move pmac_pfunc_base_install prototype to header > file > powerpc/powermac: Add missing prototype for note_bootable_part() > powerpc/52xx: Add missing functions prototypes > powerpc/altivec: Add missing prototypes for altivec > powerpc: Add missing prototype > powerpc/powermac: Add missing include of header pmac.h > powerpc/32: Add a missing include header > powerpc: Add a missing include header > powerpc/tau: Synchronize function prototypes and body > > arch/powerpc/include/asm/mpc52xx.h | 6 +++--- > arch/powerpc/include/asm/pmac_pfunc.h| 1 + > arch/powerpc/include/asm/rheap.h | 3 +++ > arch/powerpc/kernel/btext.c | 2 +- > arch/powerpc/kernel/irq.c| 2 +- > arch/powerpc/kernel/kvm.c| 2 +- > arch/powerpc/kernel/pci_32.c | 1 + > arch/powerpc/kernel/prom_init.c | 4 ++-- > arch/powerpc/kernel/setup-common.c | 6 -- > arch/powerpc/kernel/setup.h | 6 ++ > arch/powerpc/kernel/tau_6xx.c| 15 +-- > arch/powerpc/kernel/vecemu.c | 1 + > arch/powerpc/lib/xor_vmx.h | 14 ++ > arch/powerpc/platforms/chrp/pci.c| 8 > arch/powerpc/platforms/chrp/setup.c | 10 +- > arch/powerpc/platforms/chrp/time.c | 6 -- > arch/powerpc/platforms/powermac/bootx_init.c | 2 +- > arch/powerpc/platforms/powermac/pci.c| 10 +- > arch/powerpc/platforms/powermac/setup.c | 1 + > arch/powerpc/platforms/powermac/smp.c| 1 - > arch/powerpc/platforms/powermac/time.c | 4 +++- > arch/powerpc/platforms/powermac/udbg_scc.c | 2 +- > 22 files changed, 67 insertions(+), 40 deletions(-) > > -- > 2.11.0 >
[RFC V2] virtio: Add platform specific DMA API translation for virito devices
This adds a hook which a platform can define in order to allow it to force the use of the DMA API for all virtio devices even if they don't have the VIRTIO_F_IOMMU_PLATFORM flag set. We want to use this to do bounce-buffering of data on the new secure pSeries platform, currently under development, where a KVM host cannot access all of the memory space of a secure KVM guest. The host can only access the pages which the guest has explicitly requested to be shared with the host, thus the virtio implementation in the guest has to copy data to and from shared pages. With this hook, the platform code in the secure guest can force the use of swiotlb for virtio buffers, with a back-end for swiotlb which will use a pool of pre-allocated shared pages. Thus all data being sent or received by virtio devices will be copied through pages which the host has access to. Signed-off-by: Anshuman Khandual --- Changes in V2: The arch callback has been enabled through an weak symbol defintion so that it is enabled only for those architectures subscribing to this new framework. Clarified the patch description. The primary objective for this RFC has been to get an in principle agreement on this approach. Original V1: Original RFC and discussions https://patchwork.kernel.org/patch/10324405/ arch/powerpc/include/asm/dma-mapping.h | 6 ++ arch/powerpc/platforms/pseries/iommu.c | 11 +++ drivers/virtio/virtio_ring.c | 10 ++ 3 files changed, 27 insertions(+) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 8fa3945..056e578 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -115,4 +115,10 @@ extern u64 __dma_get_required_mask(struct device *dev); #define ARCH_HAS_DMA_MMAP_COHERENT #endif /* __KERNEL__ */ + +#define platform_forces_virtio_dma platform_forces_virtio_dma + +struct virtio_device; + +extern bool platform_forces_virtio_dma(struct virtio_device *vdev); #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 06f0296..a2ec15a 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1396,3 +1397,13 @@ static int __init disable_multitce(char *str) __setup("multitce=", disable_multitce); machine_subsys_initcall_sync(pseries, tce_iommu_bus_notifier_init); + +bool platform_forces_virtio_dma(struct virtio_device *vdev) +{ + /* +* On protected guest platforms, force virtio core to use DMA +* MAP API for all virtio devices. But there can also be some +* exceptions for individual devices like virtio balloon. +*/ + return (of_find_compatible_node(NULL, NULL, "ibm,ultravisor") != NULL); +} diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 21d464a..47ea6c3 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -141,8 +141,18 @@ struct vring_virtqueue { * unconditionally on data path. */ +#ifndef platform_forces_virtio_dma +static inline bool platform_forces_virtio_dma(struct virtio_device *vdev) +{ + return false; +} +#endif + static bool vring_use_dma_api(struct virtio_device *vdev) { + if (platform_forces_virtio_dma(vdev)) + return true; + if (!virtio_has_iommu_quirk(vdev)) return true; -- 2.9.3
[PATCH] powerpc: Implement csum_ipv6_magic in assembly
The generic csum_ipv6_magic() generates a pretty bad result : (PPC32) 0: 81 23 00 00 lwz r9,0(r3) 4: 81 03 00 04 lwz r8,4(r3) 8: 7c e7 4a 14 add r7,r7,r9 c: 7d 29 38 10 subfc r9,r9,r7 10: 7d 4a 51 10 subfe r10,r10,r10 14: 7d 27 42 14 add r9,r7,r8 18: 7d 2a 48 50 subfr9,r10,r9 1c: 80 e3 00 08 lwz r7,8(r3) 20: 7d 08 48 10 subfc r8,r8,r9 24: 7d 4a 51 10 subfe r10,r10,r10 28: 7d 29 3a 14 add r9,r9,r7 2c: 81 03 00 0c lwz r8,12(r3) 30: 7d 2a 48 50 subfr9,r10,r9 34: 7c e7 48 10 subfc r7,r7,r9 38: 7d 4a 51 10 subfe r10,r10,r10 3c: 7d 29 42 14 add r9,r9,r8 40: 7d 2a 48 50 subfr9,r10,r9 44: 80 e4 00 00 lwz r7,0(r4) 48: 7d 08 48 10 subfc r8,r8,r9 4c: 7d 4a 51 10 subfe r10,r10,r10 50: 7d 29 3a 14 add r9,r9,r7 54: 7d 2a 48 50 subfr9,r10,r9 58: 81 04 00 04 lwz r8,4(r4) 5c: 7c e7 48 10 subfc r7,r7,r9 60: 7d 4a 51 10 subfe r10,r10,r10 64: 7d 29 42 14 add r9,r9,r8 68: 7d 2a 48 50 subfr9,r10,r9 6c: 80 e4 00 08 lwz r7,8(r4) 70: 7d 08 48 10 subfc r8,r8,r9 74: 7d 4a 51 10 subfe r10,r10,r10 78: 7d 29 3a 14 add r9,r9,r7 7c: 7d 2a 48 50 subfr9,r10,r9 80: 81 04 00 0c lwz r8,12(r4) 84: 7c e7 48 10 subfc r7,r7,r9 88: 7d 4a 51 10 subfe r10,r10,r10 8c: 7d 29 42 14 add r9,r9,r8 90: 7d 2a 48 50 subfr9,r10,r9 94: 7d 08 48 10 subfc r8,r8,r9 98: 7d 4a 51 10 subfe r10,r10,r10 9c: 7d 29 2a 14 add r9,r9,r5 a0: 7d 2a 48 50 subfr9,r10,r9 a4: 7c a5 48 10 subfc r5,r5,r9 a8: 7c 63 19 10 subfe r3,r3,r3 ac: 7d 29 32 14 add r9,r9,r6 b0: 7d 23 48 50 subfr9,r3,r9 b4: 7c c6 48 10 subfc r6,r6,r9 b8: 7c 63 19 10 subfe r3,r3,r3 bc: 7c 63 48 50 subfr3,r3,r9 c0: 54 6a 80 3e rotlwi r10,r3,16 c4: 7c 63 52 14 add r3,r3,r10 c8: 7c 63 18 f8 not r3,r3 cc: 54 63 84 3e rlwinm r3,r3,16,16,31 d0: 4e 80 00 20 blr <.csum_ipv6_magic>: (PPC64) 0: 81 23 00 00 lwz r9,0(r3) 4: 80 03 00 04 lwz r0,4(r3) 8: 81 63 00 08 lwz r11,8(r3) c: 7c e7 4a 14 add r7,r7,r9 10: 7f 89 38 40 cmplw cr7,r9,r7 14: 7d 47 02 14 add r10,r7,r0 18: 7d 30 10 26 mfocrf r9,1 1c: 55 29 f7 fe rlwinm r9,r9,30,31,31 20: 7d 4a 4a 14 add r10,r10,r9 24: 7f 80 50 40 cmplw cr7,r0,r10 28: 7d 2a 5a 14 add r9,r10,r11 2c: 80 03 00 0c lwz r0,12(r3) 30: 81 44 00 00 lwz r10,0(r4) 34: 7d 10 10 26 mfocrf r8,1 38: 55 08 f7 fe rlwinm r8,r8,30,31,31 3c: 7d 29 42 14 add r9,r9,r8 40: 81 04 00 04 lwz r8,4(r4) 44: 7f 8b 48 40 cmplw cr7,r11,r9 48: 7d 29 02 14 add r9,r9,r0 4c: 7d 70 10 26 mfocrf r11,1 50: 55 6b f7 fe rlwinm r11,r11,30,31,31 54: 7d 29 5a 14 add r9,r9,r11 58: 7f 80 48 40 cmplw cr7,r0,r9 5c: 7d 29 52 14 add r9,r9,r10 60: 7c 10 10 26 mfocrf r0,1 64: 54 00 f7 fe rlwinm r0,r0,30,31,31 68: 7d 69 02 14 add r11,r9,r0 6c: 7f 8a 58 40 cmplw cr7,r10,r11 70: 7c 0b 42 14 add r0,r11,r8 74: 81 44 00 08 lwz r10,8(r4) 78: 7c f0 10 26 mfocrf r7,1 7c: 54 e7 f7 fe rlwinm r7,r7,30,31,31 80: 7c 00 3a 14 add r0,r0,r7 84: 7f 88 00 40 cmplw cr7,r8,r0 88: 7d 20 52 14 add r9,r0,r10 8c: 80 04 00 0c lwz r0,12(r4) 90: 7d 70 10 26 mfocrf r11,1 94: 55 6b f7 fe rlwinm r11,r11,30,31,31 98: 7d 29 5a 14 add r9,r9,r11 9c: 7f 8a 48 40 cmplw cr7,r10,r9 a0: 7d 29 02 14 add r9,r9,r0 a4: 7d 70 10 26 mfocrf r11,1 a8: 55 6b f7 fe rlwinm r11,r11,30,31,31 ac: 7d 29 5a 14 add r9,r9,r11 b0: 7f 80 48 40 cmplw cr7,r0,r9 b4: 7d 29 2a 14 add r9,r9,r5 b8: 7c 10 10 26 mfocrf r0,1 bc: 54 00 f7 fe rlwinm r0,r0,30,31,31 c0: 7d 29 02 14 add r9,r9,r0 c4: 7f 85 48 40 cmplw cr7,r5,r9 c8: 7c 09 32 14 add r0,r9,r6 cc: 7d 50 10 26 mfocrf r10,1 d0: 55 4a f7 fe rlwinm r10,r10,30,31,31 d4: 7c 00 52 14 add r0,r0,r10 d8: 7f 80 30 40 cmplw cr7,r0,r6 dc: 7d 30 10 26 mfocrf r9,1 e0: 55 29 ef fe rlwinm r9,r9,29,31,31 e4: 7c 09 02 14 add r0,r9,r0 e8: 54 03 80 3e rotlwi r3,r0,16 ec: 7c 03 02 14 add r0,r3,r0 f0: 7c 03 00 f8 not r3,r0 f4: 78 63 84 22 rldicl r3,r3,48,48 f8: 4e 80 00 20 blr This patch implements it in assembly f
[PATCH v3] powerpc: Implement csum_ipv6_magic in assembly
The generic csum_ipv6_magic() generates a pretty bad result : (PPC32) 0: 81 23 00 00 lwz r9,0(r3) 4: 81 03 00 04 lwz r8,4(r3) 8: 7c e7 4a 14 add r7,r7,r9 c: 7d 29 38 10 subfc r9,r9,r7 10: 7d 4a 51 10 subfe r10,r10,r10 14: 7d 27 42 14 add r9,r7,r8 18: 7d 2a 48 50 subfr9,r10,r9 1c: 80 e3 00 08 lwz r7,8(r3) 20: 7d 08 48 10 subfc r8,r8,r9 24: 7d 4a 51 10 subfe r10,r10,r10 28: 7d 29 3a 14 add r9,r9,r7 2c: 81 03 00 0c lwz r8,12(r3) 30: 7d 2a 48 50 subfr9,r10,r9 34: 7c e7 48 10 subfc r7,r7,r9 38: 7d 4a 51 10 subfe r10,r10,r10 3c: 7d 29 42 14 add r9,r9,r8 40: 7d 2a 48 50 subfr9,r10,r9 44: 80 e4 00 00 lwz r7,0(r4) 48: 7d 08 48 10 subfc r8,r8,r9 4c: 7d 4a 51 10 subfe r10,r10,r10 50: 7d 29 3a 14 add r9,r9,r7 54: 7d 2a 48 50 subfr9,r10,r9 58: 81 04 00 04 lwz r8,4(r4) 5c: 7c e7 48 10 subfc r7,r7,r9 60: 7d 4a 51 10 subfe r10,r10,r10 64: 7d 29 42 14 add r9,r9,r8 68: 7d 2a 48 50 subfr9,r10,r9 6c: 80 e4 00 08 lwz r7,8(r4) 70: 7d 08 48 10 subfc r8,r8,r9 74: 7d 4a 51 10 subfe r10,r10,r10 78: 7d 29 3a 14 add r9,r9,r7 7c: 7d 2a 48 50 subfr9,r10,r9 80: 81 04 00 0c lwz r8,12(r4) 84: 7c e7 48 10 subfc r7,r7,r9 88: 7d 4a 51 10 subfe r10,r10,r10 8c: 7d 29 42 14 add r9,r9,r8 90: 7d 2a 48 50 subfr9,r10,r9 94: 7d 08 48 10 subfc r8,r8,r9 98: 7d 4a 51 10 subfe r10,r10,r10 9c: 7d 29 2a 14 add r9,r9,r5 a0: 7d 2a 48 50 subfr9,r10,r9 a4: 7c a5 48 10 subfc r5,r5,r9 a8: 7c 63 19 10 subfe r3,r3,r3 ac: 7d 29 32 14 add r9,r9,r6 b0: 7d 23 48 50 subfr9,r3,r9 b4: 7c c6 48 10 subfc r6,r6,r9 b8: 7c 63 19 10 subfe r3,r3,r3 bc: 7c 63 48 50 subfr3,r3,r9 c0: 54 6a 80 3e rotlwi r10,r3,16 c4: 7c 63 52 14 add r3,r3,r10 c8: 7c 63 18 f8 not r3,r3 cc: 54 63 84 3e rlwinm r3,r3,16,16,31 d0: 4e 80 00 20 blr <.csum_ipv6_magic>: (PPC64) 0: 81 23 00 00 lwz r9,0(r3) 4: 80 03 00 04 lwz r0,4(r3) 8: 81 63 00 08 lwz r11,8(r3) c: 7c e7 4a 14 add r7,r7,r9 10: 7f 89 38 40 cmplw cr7,r9,r7 14: 7d 47 02 14 add r10,r7,r0 18: 7d 30 10 26 mfocrf r9,1 1c: 55 29 f7 fe rlwinm r9,r9,30,31,31 20: 7d 4a 4a 14 add r10,r10,r9 24: 7f 80 50 40 cmplw cr7,r0,r10 28: 7d 2a 5a 14 add r9,r10,r11 2c: 80 03 00 0c lwz r0,12(r3) 30: 81 44 00 00 lwz r10,0(r4) 34: 7d 10 10 26 mfocrf r8,1 38: 55 08 f7 fe rlwinm r8,r8,30,31,31 3c: 7d 29 42 14 add r9,r9,r8 40: 81 04 00 04 lwz r8,4(r4) 44: 7f 8b 48 40 cmplw cr7,r11,r9 48: 7d 29 02 14 add r9,r9,r0 4c: 7d 70 10 26 mfocrf r11,1 50: 55 6b f7 fe rlwinm r11,r11,30,31,31 54: 7d 29 5a 14 add r9,r9,r11 58: 7f 80 48 40 cmplw cr7,r0,r9 5c: 7d 29 52 14 add r9,r9,r10 60: 7c 10 10 26 mfocrf r0,1 64: 54 00 f7 fe rlwinm r0,r0,30,31,31 68: 7d 69 02 14 add r11,r9,r0 6c: 7f 8a 58 40 cmplw cr7,r10,r11 70: 7c 0b 42 14 add r0,r11,r8 74: 81 44 00 08 lwz r10,8(r4) 78: 7c f0 10 26 mfocrf r7,1 7c: 54 e7 f7 fe rlwinm r7,r7,30,31,31 80: 7c 00 3a 14 add r0,r0,r7 84: 7f 88 00 40 cmplw cr7,r8,r0 88: 7d 20 52 14 add r9,r0,r10 8c: 80 04 00 0c lwz r0,12(r4) 90: 7d 70 10 26 mfocrf r11,1 94: 55 6b f7 fe rlwinm r11,r11,30,31,31 98: 7d 29 5a 14 add r9,r9,r11 9c: 7f 8a 48 40 cmplw cr7,r10,r9 a0: 7d 29 02 14 add r9,r9,r0 a4: 7d 70 10 26 mfocrf r11,1 a8: 55 6b f7 fe rlwinm r11,r11,30,31,31 ac: 7d 29 5a 14 add r9,r9,r11 b0: 7f 80 48 40 cmplw cr7,r0,r9 b4: 7d 29 2a 14 add r9,r9,r5 b8: 7c 10 10 26 mfocrf r0,1 bc: 54 00 f7 fe rlwinm r0,r0,30,31,31 c0: 7d 29 02 14 add r9,r9,r0 c4: 7f 85 48 40 cmplw cr7,r5,r9 c8: 7c 09 32 14 add r0,r9,r6 cc: 7d 50 10 26 mfocrf r10,1 d0: 55 4a f7 fe rlwinm r10,r10,30,31,31 d4: 7c 00 52 14 add r0,r0,r10 d8: 7f 80 30 40 cmplw cr7,r0,r6 dc: 7d 30 10 26 mfocrf r9,1 e0: 55 29 ef fe rlwinm r9,r9,29,31,31 e4: 7c 09 02 14 add r0,r9,r0 e8: 54 03 80 3e rotlwi r3,r0,16 ec: 7c 03 02 14 add r0,r3,r0 f0: 7c 03 00 f8 not r3,r0 f4: 78 63 84 22 rldicl r3,r3,48,48 f8: 4e 80 00 20 blr This patch implements it in assembly f