Re: z constraint in powerpc inline assembly ?
On Thu, Jan 16, 2020 at 07:11:36AM +0100, Christophe Leroy wrote: > Hi Segher, > > I'm trying to see if we could enhance TCP checksum calculations by splitting > inline assembly blocks to give GCC the opportunity to mix it with other > stuff, but I'm getting difficulties with the carry. > > As far as I can read in the documentation, the z constraint represents > '‘XER[CA]’ carry bit (part of the XER register)' Well, the documentation is very optimisitic. From the GCC source code (thanks for switching to git last week-end ;-)), it is clear that the carry is not, for the time being, properly modeled. Right now, in the machine description, all setters and users of the carry are in the same block of generated instructions. For a start, all single instructions patterns that set the carry (and do not use it) as a side effect should mention the they clobber the carry, otherwise inserting one between a setter and a user of the carry would break. This includes all arithmetic right shift (sra[wd]{,i}, subfic, addic{,\.} and I may have forgotten some. If you want to future proof your code just in case, you should also add an "xer" clobber to all instruction sequences that may modify the carry bit. But any inline assembly that touches XER might break if GCC is ugraded to properly model the carry bit, and a lot of code might need to be audited. Gabriel > > I've tried the following, but I get errors. Can you help ? > > unsigned long cksum(unsigned long a, unsigned long b, unsigned long c) > { > unsigned long sum; > unsigned long carry; > > asm("addc %0, %2, %3" : "=r"(sum), "=z"(carry) : "r"(a), "r"(b)); > asm("adde %0, %0, %2" : "+r"(sum), "+z"(carry) : "r"(c)); > asm("addze %0, %0" : "+r"(sum) : "z"(carry)); > > return sum; > } > > > > csum.c: In function 'cksum': > csum.c:6:2: error: inconsistent operand constraints in an 'asm' > asm("addc %0, %2, %3" : "=r"(sum), "=z"(carry) : "r"(a), "r"(b)); > ^ > csum.c:7:2: error: inconsistent operand constraints in an 'asm' > asm("adde %0, %0, %2" : "+r"(sum), "+z"(carry) : "r"(c)); > ^ > csum.c:8:2: error: inconsistent operand constraints in an 'asm' > asm("addze %0, %0" : "+r"(sum) : "z"(carry)); > ^ > > Thanks > Christophe >
Re: [PATCH v15 23/23] selftests: vm: pkeys: Use the correct page size on powerpc
Hi Michael, On 15/01/20 12:37 pm, Michael Ellerman wrote: > Sandipan Das writes: >> Both 4K and 64K pages are supported on powerpc. Parts of >> the selftest code perform alignment computations based on >> the PAGE_SIZE macro which is currently hardcoded to 64K >> for powerpc. This causes some test failures on kernels >> configured with 4K page size. >> >> This problem is solved by determining the correct page >> size during the build process rather than hardcoding it >> in the header file. > > Doing it at build time is wrong, the test could be built on a 4K system > and then run on a 64K system, or vice versa. > > You should just use getpagesize() at runtime. > > cheers > The reason I chose to do it this way was because PAGE_SIZE also determines the alignment for the function "lots_o_noops_around_write" (which is used by some of the test cases). Since __attribute__((__aligned__(X))) requires X to be a constant, I am not sure if there a way around this. - Sandipan
(PowerPC) PCI driver writeb() and readb() failures with 'machine check error'.
Hello, I am having an important trouble while communicating with my PCI Endpoint devices MMIO. I am using T1042D4RDB-64B. PowerPC e5500 processor with kernel version 4.19 and default PCI driver is 'pcieport'. Kernel is built with Yocto 2.7. I have a FPGA memory controller card which is programmed to light GPIO leds when it's memory is filled with data on PCI. I wrote a driver and tested it with x86 based Ubuntu and it's working as expected. I used same driver with T1042D4RDB-64B. Kernel is giving UNRECOVERABLE MACHINE CHECK error when I try to read the same area I wrote before. Leds are also not lighting so that this means write operation is not working too. Seems like ATMU is not transferring the transactions to PCI endpoint device. I tried same code piece with another endpoint device ( This is a GPU ) and I had same problem again. I am seeking some help about this issue. *Detailed thread is here:* https://community.nxp.com/thread/522267 *Driver code piece* pci_request_regions(dev, "IO-pci"); pci_enable_device_mem(dev); printk(KERN_INFO "Physical address start: %lX",pci_resource_start(dev,BAR_IO)); printk(KERN_INFO "Physical address end: %lX",pci_resource_end(dev,BAR_IO)); iomapped_addr_start = ioremap(pci_resfreescaleource_start(dev,BAR_IO),pci_resource_len(dev,BAR_IO)); printk(KERN_INFO "Virtual address start: %lX",iomapped_addr_start); if(iomapped_addr_start != NULL || iomapped_addr_start != 0) { for(i=0;i
Re: [RFC PATCH v3 08/12] lib: vdso: allow arches to provide vdso data pointer
Thomas, Andy, Le 15/01/2020 à 07:15, Christophe Leroy a écrit : Le 15/01/2020 à 00:06, Thomas Gleixner a écrit : Christophe Leroy writes: static __maybe_unused int +#ifdef VDSO_GETS_VD_PTR_FROM_ARCH +__cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock, + struct __kernel_timespec *ts) +{ +#else __cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts) { const struct vdso_data *vd = __arch_get_vdso_data(); +#endif u32 msk; If we do that, then there is no point in propagating this to the inner functions. It's perfectly fine to have this distinction at the outermost level. In v2, I did it at the arch level (see https://patchwork.ozlabs.org/patch/1214983/). Andy was concerned about it being suboptimal for arches which (unlike powerpc) have PC related data addressing mode. Wouldn't it be the same issue if doing it at the outermost level of generic VDSO ? Any opinion on this ? From your point of view, what should I do: A/ __arch_get_vdso_data() handled entirely at arch level and arches handing over the vdso data pointer to generic C VDSO functions all the time (as in my v2 series) ? B/ Data pointer being handed over all the way up for arches wanting to do so, no changes at all for others (as in my v3 series) ? C/ __arch_get_vdso_data() being called at the outermost generic level for arches not interested in handling data pointer from the caller (as suggested by Thomas) ? Andy, with A/ you were concerned about arches being able to do PC related accesses. Would it be an issue for C/ as well ? If not, I guess C/ would be cleaner than B/ allthought not as clean as A which doesn't add any #ifdefery at all. Thanks Christophe
Re: [PATCH v5] reboot: support offline CPUs before reboot
On Thu, Jan 16, 2020 at 8:30 AM Thomas Gleixner wrote: > > Hsin-Yi Wang writes: > > > Currently system reboots uses architecture specific codes (smp_send_stop) > > to offline non reboot CPUs. Most architecture's implementation is looping > > through all non reboot online CPUs and call ipi function to each of them. > > Some > > architecture like arm64, arm, and x86... would set offline masks to cpu > > without > > really offline them. This causes some race condition and kernel warning > > comes > > out sometimes when system reboots. > > 'some race condition and kernel warning' is pretty useless information. > Please describe exactly which kind of issues are caused by the current > mechanism. Especially the race conditions are the interesting part (the > warnings are just a consequence). > > > This patch adds a config ARCH_OFFLINE_CPUS_ON_REBOOT, which would > > offline cpus in > > Please read Documentation/process/submitting-patches.rst and search for > 'This patch'. > > > migrate_to_reboot_cpu(). If non reboot cpus are all offlined here, the loop > > for > > checking online cpus would be an empty loop. > > This does not make any sense. The issues which you are trying to solve > are going to be still there when CONFIG_HOTPLUG_CPU is disabled. > > > If architecture don't enable this config, or some cpus somehow fails > > to offline, it would fallback to ipi function. > > This is really a half baken solution which keeps the various pointlessly > different pseudo reboot/kexec offlining implementations around. So with > this we have yet more code which only works depending on kernel > configuration and has the issue of potentially not being able to offline > a CPU. IOW this is going to fail completely in cases where a system is > in a state which prevents regular hotplug. > > The existing pseudo-offline functions have timeouts and eventually a > fallback, e.g. the NMI fallback on x86. With this proposed regular > offline solution this will just get stuck w/o a chance to force > recovery. > > While I like the idea and surely agree that the ideal solution is to > properly shutdown the CPUs on reboot, we need to take a step back and > look at the minimum requirements for a regular shutdown/reboot and at > the same time have a look at the requirements for emergency shutdown and > kexec/kcrash. Having proper information about the race conditions and > warnings you mentioned would be a good starting point. > We saw this issue on regular reboot (not panic) on arm64: If tick broadcast and smp_send_stop() happen together and the first broadcast arrives to some idled CPU that hasn't already executed reboot ipi to run in spinloop, it would try to broadcast to another CPU, but that target CPU is already marked as offline by set_cpu_online() in reboot ipi, and a warning comes out since tick_handle_oneshot_broadcast() would check if it tries to broadcast to offline cpus. Most of the time the CPU getting the broadcast interrupt is already in the spinloop and thus isn't going to receive interrupts from the broadcast timer. [ 27.032080] Set kernel.core_pattern before fs.suid_dumpable. [ 27.978628] reboot: Restarting system [ 27.978919] WARNING: CPU: 3 PID: 0 at /mnt/host/source/src/third_party/kernel/v4.19/kernel/time/tick-broadcast.c:652 tick_handle_oneshot_broadcast+0x1f8/0x214 [ 27.978932] Modules linked in: rfcomm uinput bridge stp llc nf_nat_tftp nf_conntrack_tftp nf_nat_ftp nf_conntrack_ftp esp6 ah6 xfrm6_mode_tunnel xfrm6_mode_transport xfrm4_mode_tunnel xfrm4_mode_transport ip6t_REJECT ip6t_ipv6header hci_uart btqca bluetooth ipt_MASQUERADE ecdh_generic lzo_rle lzo_compress zram fuse cros_ec_sensors_sync cros_ec_sensors_ring cros_ec_light_prox cros_ec_sensors industrialio_triggered_buffer kfifo_buf cros_ec_sensors_core ath10k_sdio ath10k_core ath mac80211 cfg80211 asix usbnet mii joydev [ 27.979102] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G S 4.19.56 #79 [ 27.979113] Hardware name: MediaTek krane sku176 board (DT) [ 27.979127] pstate: 0085 (nzcv daIf -PAN -UAO) [ 27.979140] pc : tick_handle_oneshot_broadcast+0x1f8/0x214 [ 27.979154] lr : tick_handle_oneshot_broadcast+0x108/0x214 [ 27.979162] sp : fff85c851610 [ 27.979171] x29: fff85c851670 x28: ff9082785510 [ 27.979187] x27: ff90822da700 x26: ff90826169c8 [ 27.979202] x25: ff9082616000 x24: 0001 [ 27.979217] x23: ff90827854f8 x22: 00067a6599b8 [ 27.979232] x21: x20: 7fff [ 27.979248] x19: ff9082785508 x18: [ 27.979263] x17: x16: [ 27.979278] x15: x14: fff85bf08040 [ 27.979293] x13: ff9082785000 x12: 0069 [ 27.979308] x11: ff9082785000 x10: 0018 [ 27.979323] x9 : 0010 x8 : ff9082615000 [ 27.979338] x7 : x6 : 003f [ 27.979353] x5 : 0040 x4 : 0102 [ 27.979367] x3 : 00
[Bug 205283] BUG: KASAN: global-out-of-bounds in _copy_to_iter+0x3d4/0x5a8
https://bugzilla.kernel.org/show_bug.cgi?id=205283 --- Comment #11 from Christophe Leroy (christophe.le...@c-s.fr) --- Series at https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=153133 drops the buggy module_alloc() and forces CONFIG_KASAN_VMALLOC when CONFIG_MODULES is selected. -- You are receiving this mail because: You are watching someone on the CC list of the bug.
Re: [PATCH v5] reboot: support offline CPUs before reboot
On Wed, Jan 15, 2020 at 7:41 PM Sudeep Holla wrote: > > On Wed, Jan 15, 2020 at 02:34:10PM +0800, Hsin-Yi Wang wrote: > > Currently system reboots uses architecture specific codes (smp_send_stop) > > to offline non reboot CPUs. Most architecture's implementation is looping > > through all non reboot online CPUs and call ipi function to each of them. > > Some > > architecture like arm64, arm, and x86... would set offline masks to cpu > > without > > really offline them. This causes some race condition and kernel warning > > comes > > out sometimes when system reboots. > > > > This patch adds a config ARCH_OFFLINE_CPUS_ON_REBOOT, which would offline > > cpus in > > migrate_to_reboot_cpu(). If non reboot cpus are all offlined here, the loop > > for > > checking online cpus would be an empty loop. If architecture don't enable > > this > > config, or some cpus somehow fails to offline, it would fallback to ipi > > function. > > > > What's the timing impact on systems with large number of CPUs(say 256 or > more) ? I remember we added some change to reduce the wait times for > offlining CPUs in system suspend path on arm64, still not negligible. > This is not the final solution, but I would still provided some data points here: Tested on my arm64 with 4 cpu: 2 a53 and 2 a72. Offlining 3 cpu takes about 60~65 ms Offlining 2 cpu(a53+a72 or a72+a72) takes about 42~47 ms Offlining 1 cpu(a53 or a72) takes about 23~25 ms. It would take longer time for systems with large number of CPUs.
Re: [PATCH v5 0/4] KASAN for powerpc64 radix
Le 09/01/2020 à 08:08, Daniel Axtens a écrit : Building on the work of Christophe, Aneesh and Balbir, I've ported KASAN to 64-bit Book3S kernels running on the Radix MMU. This provides full inline instrumentation on radix, but does require that you be able to specify the amount of physically contiguous memory on the system at compile time. More details in patch 4. This might be a stupid idea as I don't know ppc64 much. IIUC, PPC64 kernel can be relocated, there is no requirement to have it at address 0. Therefore, would it be possible to put the KASAN shadow mem at the begining of the physical memory, instead of putting it at the end ? That way, you wouldn't need to know the amount of memory at compile time because KASAN shadow mem would always be at address 0. Christophe
Re: [PATCH v12 04/22] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On Wed, Jan 15, 2020 at 01:19:41PM -0800, John Hubbard wrote: > On 1/15/20 7:23 AM, Christoph Hellwig wrote: > ... > > > > I'm really not sold on this scheme. Note that I think it is > > particularly bad, but it also doesn't seem any better than what > > we had before, and it introduced quite a bit more code. > > > > Hi Christoph, > > All by itself, yes. But the very next patch (which needs a little > rework for other reasons, so not included here) needs to reuse some of > these functions within __unpin_devmap_managed_user_page(): Well, then combine it with the series that actually does the change. Also my vaguely recollection is that we had some idea on how to get rid of the off by one refcounting for the zone device pages, which would be a much better outcome.
Re: [PATCH] powerpc/xive: discard ESB load value when interrupt is invalid
>> You might want to use 'git tag --contains': >> >> [greg@bahia kernel-linus]$ git tag --contains da15c03b047d >> for-linus >> kvm-5.4-2 >> next-20191118 >> next-20191126 >> tags/kvm-5.4-1 >> tags/kvm-5.4-2 >> v5.4 >> v5.4-rc1 > > Or: > > $ git describe --match "v[0-9]*" --contains da15c03b047d > v5.4-rc1~99^2~134^2~17 Nice. I am adding this command to my git aliases. Thanks, C.
Re: [RFC PATCH v3 08/12] lib: vdso: allow arches to provide vdso data pointer
Christophe Leroy writes: > Le 15/01/2020 à 07:15, Christophe Leroy a écrit : > From your point of view, what should I do: > A/ __arch_get_vdso_data() handled entirely at arch level and arches > handing over the vdso data pointer to generic C VDSO functions all the > time (as in my v2 series) ? No. That's again moving the same code to all architectures. > B/ Data pointer being handed over all the way up for arches wanting to > do so, no changes at all for others (as in my v3 series) ? Too much ifdeffery > C/ __arch_get_vdso_data() being called at the outermost generic level > for arches not interested in handling data pointer from the caller (as > suggested by Thomas) ? > > Andy, with A/ you were concerned about arches being able to do PC > related accesses. Would it be an issue for C/ as well ? If not, I guess > C/ would be cleaner than B/ allthought not as clean as A which doesn't > add any #ifdefery at all. You can avoid ifdeffery with C if you do: static __maybe_unused int __cvdso_data_clock_gettime(clockid_t clock, struct __kernel_timespec *ts, const struct vdso_data *vd) { . } static __maybe_unused int __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) { const struct vdso_data *vd = __arch_get_vdso_data(); return __cvdso_data_clock_gettime(clock, ts, vd); } and then use __cvdso_data_clock_gettime on PPC and let the other archs unmodified. Thanks, tglx
[PATCH] powerpc: drmem: avoid NULL pointer dereference when drmem is unavailable
In KVM guests drmem structure is only zero initialized. Trying to manipulate DLPAR parameters results in a crash in this environment. $ echo "memory add count 1" > /sys/kernel/dlpar Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries Modules linked in: af_packet(E) rfkill(E) nvram(E) vmx_crypto(E) gf128mul(E) e1000(E) virtio_balloon(E) rtc_generic(E) crct10dif_vpmsum(E) btrfs(E) blake2b_generic(E) libcrc32c(E) xor(E) raid6_pq(E) virtio_rng(E) virtio_blk(E) ohci_pci(E) ehci_pci(E) ohci_hcd(E) ehci_hcd(E) crc32c_vpmsum(E) usbcore(E) virtio_pci(E) virtio_ring(E) virtio(E) sg(E) dm_multipath(E) dm_mod(E) scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) scsi_mod(E) CPU: 1 PID: 4114 Comm: bash Kdump: loaded Tainted: GE 5.5.0-rc6-2-default #1 NIP: c00ff294 LR: c00ff248 CTR: REGS: c000fb9d3880 TRAP: 0300 Tainted: GE (5.5.0-rc6-2-default) MSR: 80009033 CR: 28242428 XER: 2000 CFAR: c09a6c10 DAR: 0010 DSISR: 4000 IRQMASK: 0 GPR00: c00ff248 c000fb9d3b10 c1682e00 0033 GPR04: c000ff30bf90 c000ff394800 5110 ffe8 GPR08: fe1c GPR12: 2200 c0003fffee00 00011cbc37c0 GPR16: 00011cb27ed0 00011cb6dd10 GPR20: 00011cb7db28 01003ce035f0 00011cbc7828 00011cbc6c70 GPR24: 01003cf01210 c000ffade4e0 c2d7216b GPR28: 0001 c2d78560 c15458d0 NIP [c00ff294] dlpar_memory+0x6e4/0xd00 LR [c00ff248] dlpar_memory+0x698/0xd00 Call Trace: [c000fb9d3b10] [c00ff248] dlpar_memory+0x698/0xd00 (unreliable) [c000fb9d3ba0] [c00f5990] handle_dlpar_errorlog+0xc0/0x190 [c000fb9d3c10] [c00f5c58] dlpar_store+0x198/0x4a0 [c000fb9d3cd0] [c0c4cb00] kobj_attr_store+0x30/0x50 [c000fb9d3cf0] [c05a37b4] sysfs_kf_write+0x64/0x90 [c000fb9d3d10] [c05a2c90] kernfs_fop_write+0x1b0/0x290 [c000fb9d3d60] [c04a2bec] __vfs_write+0x3c/0x70 [c000fb9d3d80] [c04a6560] vfs_write+0xd0/0x260 [c000fb9d3dd0] [c04a69ac] ksys_write+0xdc/0x130 [c000fb9d3e20] [c000b478] system_call+0x5c/0x68 Instruction dump: ebc9 1ce70018 38e7ffe8 7cfe3a14 7fbe3840 419dff14 fb610068 7fc9f378 3900 480c 6000 4195fef4 <81490010> 39290018 38c80001 7ea93840 ---[ end trace cc2dd8152608c295 ]--- Taking closer look at the code, I can see that for_each_drmem_lmb is a macro expanding into `for (lmb = &drmem_info->lmbs[0]; lmb <= &drmem_info->lmbs[drmem_info->n_lmbs - 1]; lmb++)`. When drmem_info->lmbs is NULL, the loop would iterate through the whole address range if it weren't stopped by the NULL pointer dereference on the next line. This patch aligns for_each_drmem_lmb and for_each_drmem_lmb_in_range macro behavior with the common C semantics, where the end marker does not belong to the scanned range, and alters get_lmb_range() semantics. As a side effect, the wraparound observed in the crash is prevented. Fixes: 6c6ea53725b3 ("powerpc/mm: Separate ibm, dynamic-memory data from DT format") Cc: Michal Suchanek Cc: sta...@vger.kernel.org Signed-off-by: Libor Pechacek --- arch/powerpc/include/asm/drmem.h| 4 ++-- arch/powerpc/platforms/pseries/hotplug-memory.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h index 3d76e1c388c2..28c3d936fdf3 100644 --- a/arch/powerpc/include/asm/drmem.h +++ b/arch/powerpc/include/asm/drmem.h @@ -27,12 +27,12 @@ struct drmem_lmb_info { extern struct drmem_lmb_info *drmem_info; #define for_each_drmem_lmb_in_range(lmb, start, end) \ - for ((lmb) = (start); (lmb) <= (end); (lmb)++) + for ((lmb) = (start); (lmb) < (end); (lmb)++) #define for_each_drmem_lmb(lmb)\ for_each_drmem_lmb_in_range((lmb), \ &drmem_info->lmbs[0], \ - &drmem_info->lmbs[drmem_info->n_lmbs - 1]) + &drmem_info->lmbs[drmem_info->n_lmbs]) /* * The of_drconf_cell_v1 struct defines the layout of the LMB data diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index c126b94d1943..4ea6af002e27 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -236,9 +236,9 @@ static int get_lmb_range(u32 drc_index, int n_lmbs, if (!start) return -EINVAL; - end = &start[n_lmbs - 1]; + end = &start[n_lmbs]; - last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1]; + last_lmb = &drme
[FSL P5020 P5040 PPC] Onboard SD card doesn't work anymore after the 'mmc-v5.4-2' updates
Hi All, We still need the attached patch for our onboard SD card interface [1,2]. Could you please add this patch to the tree? Thanks, Christian [1] https://www.spinics.net/lists/linux-mmc/msg56211.html [2] http://forum.hyperion-entertainment.com/viewtopic.php?f=58&t=4349&start=20#p49012 diff -rupN a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c --- a/arch/powerpc/kernel/setup-common.c 2019-12-03 18:05:52.436070217 +0100 +++ b/arch/powerpc/kernel/setup-common.c 2019-12-03 18:03:20.316629696 +0100 @@ -780,6 +780,22 @@ static int __init check_cache_coherency( late_initcall(check_cache_coherency); #endif /* CONFIG_CHECK_CACHE_COHERENCY */ +#ifndef CONFIG_NOT_COHERENT_CACHE +/* + * For historical reasons powerpc kernels are built with hard wired knowledge of + * whether or not DMA accesses are cache coherent. Additionally device trees on + * powerpc do not typically support the dma-coherent property. + * + * So when we know that DMA is coherent, override arch_of_dma_is_coherent() to + * tell the drivers/of code that all devices are coherent regardless of whether + * they have a dma-coherent property. + */ +bool arch_of_dma_is_coherent(struct device_node *np) +{ + return true; +} +#endif + #ifdef CONFIG_DEBUG_FS struct dentry *powerpc_debugfs_root; EXPORT_SYMBOL(powerpc_debugfs_root); diff -rupN a/drivers/of/address.c b/drivers/of/address.c --- a/drivers/of/address.c 2019-12-03 18:05:57.332052212 +0100 +++ b/drivers/of/address.c 2019-12-03 18:03:20.320629681 +0100 @@ -990,6 +990,14 @@ out: return ret; } +/* + * arch_of_dma_is_coherent - Arch hook to determine if device is coherent for DMA + */ +bool __weak arch_of_dma_is_coherent(struct device_node *np) +{ + return false; +} + /** * of_dma_is_coherent - Check if device is coherent * @np: device node @@ -999,8 +1007,12 @@ out: */ bool of_dma_is_coherent(struct device_node *np) { - struct device_node *node = of_node_get(np); + struct device_node *node; + + if (arch_of_dma_is_coherent(np)) + return true; + np = of_node_get(np); while (node) { if (of_property_read_bool(node, "dma-coherent")) { of_node_put(node);
Re: [PATCH v5] reboot: support offline CPUs before reboot
Hsin-Yi Wang writes: > On Thu, Jan 16, 2020 at 8:30 AM Thomas Gleixner wrote: > We saw this issue on regular reboot (not panic) on arm64: If tick > broadcast and smp_send_stop() happen together and the first broadcast > arrives to some idled CPU that hasn't already executed reboot ipi to > run in spinloop, it would try to broadcast to another CPU, but that > target CPU is already marked as offline by set_cpu_online() in reboot > ipi, and a warning comes out since tick_handle_oneshot_broadcast() > would check if it tries to broadcast to offline cpus. Most of the time > the CPU getting the broadcast interrupt is already in the spinloop and > thus isn't going to receive interrupts from the broadcast timer. The timer broadcasting is obviously broken by the existing reboot unplug mechanism as the outgoing CPU should remove itself from the broadcast. Just addressing the broadcast issue is not sufficient as there are tons of other places which rely on consistency of the various cpu masks. > If system supports hotplug, _cpu_down() would properly handle tasks > termination such as remove CPU from timer broadcasting by > tick_offline_cpu()...etc, as well as some interrupt handling. Well, emphasis on 'if system supports hotplug'. If not, then you are back to square one. On ARM64 hotplug is selectable by a config option. So either we mandate HOTPLUG_CPU for SMP and get rid of all the ifdeffery or we need to have a mechanism which works on !HOTPLUG_CPU as well. That whole reboot/shutdown stuff is an unpenetrable mess of notifiers and architecture hackery, so something generic and understandable is really required. Thanks, tglx
Re: z constraint in powerpc inline assembly ?
On Thu, Jan 16, 2020 at 09:06:08AM +0100, Gabriel Paubert wrote: > On Thu, Jan 16, 2020 at 07:11:36AM +0100, Christophe Leroy wrote: > > Hi Segher, > > > > I'm trying to see if we could enhance TCP checksum calculations by splitting > > inline assembly blocks to give GCC the opportunity to mix it with other > > stuff, but I'm getting difficulties with the carry. > > > > As far as I can read in the documentation, the z constraint represents > > '‘XER[CA]’ carry bit (part of the XER register)' > > Well, the documentation is very optimisitic. From the GCC source code > (thanks for switching to git last week-end ;-)), it is clear that the > carry is not, for the time being, properly modeled. What? It certainly *is*, I spent ages on that back in 2014 and before. See gcc.gnu.org/PR64180 etc. You can not put the carry as input or output to an asm, of course: no C variable can be assigned to it. We don't do the "flag outputs" thing, either, as it is largely useless for Power (and using it would often make *worse* code). If you want to access a carry, write C code that does that operation. The compiler knows how to optimise it well. > Right now, in the machine description, all setters and users of the carry > are in the same block of generated instructions. No, they are not. For over five years now. (Since GCC 5). > For a start, all single instructions patterns that set the carry (and > do not use it) as a side effect should mention the they clobber the > carry, otherwise inserting one between a setter and a user of the carry > would break. And they do. All asms that change the carry should mention that, too, but this is automatically done for all inline asms, because there was a lot of code in the wild that does not clobber it. > This includes all arithmetic right shift (sra[wd]{,i}, > subfic, addic{,\.} and I may have forgotten some. {add,subf}{ic,c,e,ze,me} and sra[wd][i] and their dots. Sure. And mcrxr and mcrxrx and mfxer and mtxer. That's about it. We don't model the second carry at all yet btw, in GCC. Not too many people know it exists even, so no big loss there. (One nasty was that addi. does not exist, so we used addic. where it was wanted before, so that had to change.) Segher
Re: z constraint in powerpc inline assembly ?
Hi! On Thu, Jan 16, 2020 at 07:11:36AM +0100, Christophe Leroy wrote: > I'm trying to see if we could enhance TCP checksum calculations by > splitting inline assembly blocks to give GCC the opportunity to mix it > with other stuff, but I'm getting difficulties with the carry. > > As far as I can read in the documentation, the z constraint represents > '‘XER[CA]’ carry bit (part of the XER register)' > > I've tried the following, but I get errors. Can you help ? > > unsigned long cksum(unsigned long a, unsigned long b, unsigned long c) > { > unsigned long sum; > unsigned long carry; > > asm("addc %0, %2, %3" : "=r"(sum), "=z"(carry) : "r"(a), "r"(b)); > asm("adde %0, %0, %2" : "+r"(sum), "+z"(carry) : "r"(c)); > asm("addze %0, %0" : "+r"(sum) : "z"(carry)); > > return sum; > } The only register allowed by "z" is a fixed register. You cannot use "z" in inline asm. Just write this as C? It should do a reasonable job of it. If you want *good* code, you need to write it in *actual* assembler code, anyway (hand scheduled and everything). Segher
Re: [FSL P5020 P5040 PPC] Onboard SD card doesn't work anymore after the 'mmc-v5.4-2' updates
On Thu, 16 Jan 2020 at 12:18, Christian Zigotzky wrote: > > Hi All, > > We still need the attached patch for our onboard SD card interface > [1,2]. Could you please add this patch to the tree? No, because according to previous discussion that isn't the correct solution and more importantly it will break other archs (if I recall correctly). Looks like someone from the ppc community needs to pick up the ball. > > Thanks, > Christian > > [1] https://www.spinics.net/lists/linux-mmc/msg56211.html I think this discussion even suggested some viable solutions, so it just be a matter of sending a patch :-) > [2] > http://forum.hyperion-entertainment.com/viewtopic.php?f=58&t=4349&start=20#p49012 > Kind regards Uffe
RE: z constraint in powerpc inline assembly ?
From: Christophe Leroy > Sent: 16 January 2020 06:12 > > I'm trying to see if we could enhance TCP checksum calculations by > splitting inline assembly blocks to give GCC the opportunity to mix it > with other stuff, but I'm getting difficulties with the carry. if you are trying to 'loop carry' the 'carry flag' with 'add with carry' instructions you'll almost certainly need to write the loop in asm. Since the loop itself is simple, this probably doesn't matter. However a loop of 'add with carry' instructions may not be the fastest code by any means. Because the carry flag is needed for every 'adc' you can't do more that one adc per clock. This limits you to 8 bytes/clock on a 64bit system - even one that can schedule multiple memory reads and lots of instructions every clock. I don't know ppc, but on x86 you don't even get 1 adc per clock until very recent (Haswell I think) cpus. Sandy/Ivy bridge will do so if you add to alternate registers. For earlier cpu it is actually difficult to beat the 4 bytes/clock you get by adding 32bit values to a 64bit register in C code. One possibility is to do a normal add then shift the carry into a separate register. After 64 words use 'popcnt' to sum the carry bits. With 2 accumulators (and carry shifts) you'd need to break the loop every 1024 bytes. This should beat 8 bytes/clock if you can exeute more than 1 memory read, one add and one shift each clock. I've not tried this on an old x86 cpu - which would need a software 'popcnt'. It got close to 8 bytes/clock on Ivy bridge. It almost certainly beats the 4 bytes/clock of the current x86-64 code on such systems. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: z constraint in powerpc inline assembly ?
Hi! On Thu, Jan 16, 2020 at 03:54:58PM +, David Laight wrote: > if you are trying to 'loop carry' the 'carry flag' with 'add with carry' > instructions you'll almost certainly need to write the loop in asm. > Since the loop itself is simple, this probably doesn't matter. Agreed. > However a loop of 'add with carry' instructions may not be the > fastest code by any means. > Because the carry flag is needed for every 'adc' you can't do more > that one adc per clock. > This limits you to 8 bytes/clock on a 64bit system - even one > that can schedule multiple memory reads and lots of instructions > every clock. > > I don't know ppc, but on x86 you don't even get 1 adc per clock > until very recent (Haswell I think) cpus. > Sandy/Ivy bridge will do so if you add to alternate registers. The carry bit is renamed just fine on all modern Power cpus. On Power9 there is an extra carry bit, precisely so you can do two interleaved chains. And you can run lots of these insns at once, every cycle. On older cpus there were other limitations as well, but those have been solved essentially. > For earlier cpu it is actually difficult to beat the 4 bytes/clock > you get by adding 32bit values to a 64bit register in C code. Christophe uses a very primitive 32-bit cpu, not even superscalar. A loop doing adde is pretty much optimal, probably wants some unrolling though. > One possibility is to do a normal add then shift the carry > into a separate register. > After 64 words use 'popcnt' to sum the carry bits. > With 2 accumulators (and carry shifts) you'd need to > break the loop every 1024 bytes. > This should beat 8 bytes/clock if you can exeute more than > 1 memory read, one add and one shift each clock. Do normal 64-bit adds, and in parallel also accumulate the values shifted right by 32 bits. You can add 4G of them this way, and restore the 96-bit actual sum from these two accumulators, so that you can fold it to a proper ones' complement sum after the loop. But you can easily beat 8B/clock using vectors, or doing multiple addition chains (interleaved) in parallel. Not that it helps, your limiting factor is the memory bandwidth anyway, if anything in the memory pipeline stalls all your optimisations are for nothing. Segher
[PATCH AUTOSEL 5.4 072/205] ASoC: fsl_esai: Add spin lock to protect reset, stop and start
From: Shengjiu Wang [ Upstream commit 35dac627471938eda89fa39ee4ead1f7667e0f57 ] xrun may happen at the end of stream, the trigger->fsl_esai_trigger_stop maybe called in the middle of fsl_esai_hw_reset, this may cause esai in wrong state after stop, and there may be endless xrun interrupt. This issue may also happen with trigger->fsl_esai_trigger_start. So Add spin lock to lock those functions. Fixes: 7ccafa2b3879 ("ASoC: fsl_esai: recover the channel swap after xrun") Signed-off-by: Shengjiu Wang Acked-by: Nicolin Chen Link: https://lore.kernel.org/r/52e92c4221a83e39a84a6cd92fc3d5479b44894c.1572252321.git.shengjiu.w...@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/fsl_esai.c | 12 1 file changed, 12 insertions(+) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index a78e4ab478df..c7a49d03463a 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -33,6 +33,7 @@ * @fsysclk: system clock source to derive HCK, SCK and FS * @spbaclk: SPBA clock (optional, depending on SoC design) * @task: tasklet to handle the reset operation + * @lock: spin lock between hw_reset() and trigger() * @fifo_depth: depth of tx/rx FIFO * @slot_width: width of each DAI slot * @slots: number of slots @@ -56,6 +57,7 @@ struct fsl_esai { struct clk *fsysclk; struct clk *spbaclk; struct tasklet_struct task; + spinlock_t lock; /* Protect hw_reset and trigger */ u32 fifo_depth; u32 slot_width; u32 slots; @@ -676,8 +678,10 @@ static void fsl_esai_hw_reset(unsigned long arg) { struct fsl_esai *esai_priv = (struct fsl_esai *)arg; bool tx = true, rx = false, enabled[2]; + unsigned long lock_flags; u32 tfcr, rfcr; + spin_lock_irqsave(&esai_priv->lock, lock_flags); /* Save the registers */ regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr); regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr); @@ -715,6 +719,8 @@ static void fsl_esai_hw_reset(unsigned long arg) fsl_esai_trigger_start(esai_priv, tx); if (enabled[rx]) fsl_esai_trigger_start(esai_priv, rx); + + spin_unlock_irqrestore(&esai_priv->lock, lock_flags); } static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, @@ -722,6 +728,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, { struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + unsigned long lock_flags; esai_priv->channels[tx] = substream->runtime->channels; @@ -729,12 +736,16 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock_irqsave(&esai_priv->lock, lock_flags); fsl_esai_trigger_start(esai_priv, tx); + spin_unlock_irqrestore(&esai_priv->lock, lock_flags); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock_irqsave(&esai_priv->lock, lock_flags); fsl_esai_trigger_stop(esai_priv, tx); + spin_unlock_irqrestore(&esai_priv->lock, lock_flags); break; default: return -EINVAL; @@ -1002,6 +1013,7 @@ static int fsl_esai_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, esai_priv); + spin_lock_init(&esai_priv->lock); ret = fsl_esai_hw_init(esai_priv); if (ret) return ret; -- 2.20.1
[PATCH AUTOSEL 5.4 099/205] powerpc/security: Fix debugfs data leak on 32-bit
From: Geert Uytterhoeven [ Upstream commit 3b05a1e517e1a8cfda4866ec31d28b2bc4fee4c4 ] "powerpc_security_features" is "unsigned long", i.e. 32-bit or 64-bit, depending on the platform (PPC_FSL_BOOK3E or PPC_BOOK3S_64). Hence casting its address to "u64 *", and calling debugfs_create_x64() is wrong, and leaks 32-bit of nearby data to userspace on 32-bit platforms. While all currently defined SEC_FTR_* security feature flags fit in 32-bit, they all have "ULL" suffixes to make them 64-bit constants. Hence fix the leak by changing the type of "powerpc_security_features" (and the parameter types of its accessors) to "u64". This also allows to drop the cast. Fixes: 398af571128fe75f ("powerpc/security: Show powerpc_security_features in debugfs") Signed-off-by: Geert Uytterhoeven Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191021142309.28105-1-geert+rene...@glider.be Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/security_features.h | 8 arch/powerpc/kernel/security.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/security_features.h b/arch/powerpc/include/asm/security_features.h index ccf44c135389..7c05e95a5c44 100644 --- a/arch/powerpc/include/asm/security_features.h +++ b/arch/powerpc/include/asm/security_features.h @@ -9,7 +9,7 @@ #define _ASM_POWERPC_SECURITY_FEATURES_H -extern unsigned long powerpc_security_features; +extern u64 powerpc_security_features; extern bool rfi_flush; /* These are bit flags */ @@ -24,17 +24,17 @@ void setup_stf_barrier(void); void do_stf_barrier_fixups(enum stf_barrier_type types); void setup_count_cache_flush(void); -static inline void security_ftr_set(unsigned long feature) +static inline void security_ftr_set(u64 feature) { powerpc_security_features |= feature; } -static inline void security_ftr_clear(unsigned long feature) +static inline void security_ftr_clear(u64 feature) { powerpc_security_features &= ~feature; } -static inline bool security_ftr_enabled(unsigned long feature) +static inline bool security_ftr_enabled(u64 feature) { return !!(powerpc_security_features & feature); } diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index d341b464f23c..1740a66cea84 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -16,7 +16,7 @@ #include -unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT; +u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT; enum count_cache_flush_type { COUNT_CACHE_FLUSH_NONE = 0x1, @@ -109,7 +109,7 @@ device_initcall(barrier_nospec_debugfs_init); static __init int security_feature_debugfs_init(void) { debugfs_create_x64("security_features", 0400, powerpc_debugfs_root, - (u64 *)&powerpc_security_features); + &powerpc_security_features); return 0; } device_initcall(security_feature_debugfs_init); -- 2.20.1
RE: z constraint in powerpc inline assembly ?
From: Segher Boessenkool > Sent: 16 January 2020 16:22 ... > > However a loop of 'add with carry' instructions may not be the > > fastest code by any means. > > Because the carry flag is needed for every 'adc' you can't do more > > that one adc per clock. > > This limits you to 8 bytes/clock on a 64bit system - even one > > that can schedule multiple memory reads and lots of instructions > > every clock. > > > > I don't know ppc, but on x86 you don't even get 1 adc per clock > > until very recent (Haswell I think) cpus. > > Sandy/Ivy bridge will do so if you add to alternate registers. > > The carry bit is renamed just fine on all modern Power cpus. On Power9 > there is an extra carry bit, precisely so you can do two interleaved > chains. And you can run lots of these insns at once, every cycle. The limitation on old x86 was that each u-op could only have 2 inputs. Since adc needs 3 it always took 2 clocks. The first 'fix' still had an extra delay on the result register. There is also a big problem of false dependencies against the flags. PPC may not have this problem, but it makes it very difficult to loop carry any of the flags. Using 'dec' (which doesn't affect carry, but does set zero) is really slow. Even though the latest x86 cpu have ADOX and ADCX (that use the overflow and carry flags) and can run in parallel the LOOP 'dec jump non-zero' instruction is microcoded and serialising! I have got 12 bytes/clock without too much unrolling, but it is hard work and probably not worth the effort. ... > Christophe uses a very primitive 32-bit cpu, not even superscalar. A > loop doing adde is pretty much optimal, probably wants some unrolling > though. Or interleaving so it does read_a, [read_b, adc_a, read_a, adc_b]* adc_a. That might be enough to get the loop 'for free' if there are memory stalls. > Do normal 64-bit adds, and in parallel also accumulate the values shifted > right by 32 bits. You can add 4G of them this way, and restore the 96-bit > actual sum from these two accumulators, so that you can fold it to a proper > ones' complement sum after the loop. That is probably too many instructions per word - unless you are using simd ones. > But you can easily beat 8B/clock using vectors, or doing multiple addition > chains (interleaved) in parallel. Not that it helps, your limiting factor > is the memory bandwidth anyway, if anything in the memory pipeline stalls > all your optimisations are for nothing. Yep, if the data isn't in the L1 cache anything complex is a waste of time. Unrolling too much just makes the top/bottom code take too long and then it dominates for a lot of 'real world' buffers. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
[PATCH AUTOSEL 5.4 162/205] powerpc/powernv: Disable native PCIe port management
From: Oliver O'Halloran [ Upstream commit 9d72dcef891030545f39ad386a30cf91df517fb2 ] On PowerNV the PCIe topology is (currently) managed by the powernv platform code in Linux in cooperation with the platform firmware. Linux's native PCIe port service drivers operate independently of both and this can cause problems. The main issue is that the portbus driver will conflict with the platform specific hotplug driver (pnv_php) over ownership of the MSI used to notify the host when a hotplug event occurs. The portbus driver claims this MSI on behalf of the individual port services because the same interrupt is used for hotplug events, PMEs (on root ports), and link bandwidth change notifications. The portbus driver will always claim the interrupt even if the individual port service drivers, such as pciehp, are compiled out. The second, bigger, problem is that the hotplug port service driver fundamentally does not work on PowerNV. The platform assumes that all PCI devices have a corresponding arch-specific handle derived from the DT node for the device (pci_dn) and without one the platform will not allow a PCI device to be enabled. This problem is largely due to historical baggage, but it can't be resolved without significant re-factoring of the platform PCI support. We can fix these problems in the interim by setting the "pcie_ports_disabled" flag during platform initialisation. The flag indicates the platform owns the PCIe ports which stops the portbus driver from being registered. This does have the side effect of disabling all port services drivers that is: AER, PME, BW notifications, hotplug, and DPC. However, this is not a huge disadvantage on PowerNV since these services are either unused or handled through other means. Fixes: 66725152fb9f ("PCI/hotplug: PowerPC PowerNV PCI hotplug driver") Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191118065553.30362-1-ooh...@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/pci.c | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 2825d004dece..c0bea75ac27b 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -945,6 +945,23 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; +#ifdef CONFIG_PCIEPORTBUS + /* +* On PowerNV PCIe devices are (currently) managed in cooperation +* with firmware. This isn't *strictly* required, but there's enough +* assumptions baked into both firmware and the platform code that +* it's unwise to allow the portbus services to be used. +* +* We need to fix this eventually, but for now set this flag to disable +* the portbus driver. The AER service isn't required since that AER +* events are handled via EEH. The pciehp hotplug driver can't work +* without kernel changes (and portbus binding breaks pnv_php). The +* other services also require some thinking about how we're going +* to integrate them. +*/ + pcie_ports_disabled = true; +#endif + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); -- 2.20.1
[PATCH AUTOSEL 5.4 189/205] powerpc/kasan: Fix boot failure with RELOCATABLE && FSL_BOOKE
From: Christophe Leroy [ Upstream commit 71eb40fc53371bc247c8066ae76ad9e22ae1e18d ] When enabling CONFIG_RELOCATABLE and CONFIG_KASAN on FSL_BOOKE, the kernel doesn't boot. relocate_init() requires KASAN early shadow area to be set up because it needs access to the device tree through generic functions. Call kasan_early_init() before calling relocate_init() Reported-by: Lexi Shao Fixes: 2edb16efc899 ("powerpc/32: Add KASAN support") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/b58426f1664a4b344ff696d18cacf3b3e8962111.1575036985.git.christophe.le...@c-s.fr Signed-off-by: Sasha Levin --- arch/powerpc/kernel/head_fsl_booke.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index adf0505dbe02..519d49547e2f 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -238,6 +238,9 @@ set_ivor: bl early_init +#ifdef CONFIG_KASAN + bl kasan_early_init +#endif #ifdef CONFIG_RELOCATABLE mr r3,r30 mr r4,r31 @@ -264,9 +267,6 @@ set_ivor: /* * Decide what sort of machine this is and initialize the MMU. */ -#ifdef CONFIG_KASAN - bl kasan_early_init -#endif mr r3,r30 mr r4,r31 bl machine_init -- 2.20.1
[PATCH AUTOSEL 5.4 190/205] powerpc/archrandom: fix arch_get_random_seed_int()
From: Ard Biesheuvel [ Upstream commit b6afd1234cf93aa0d71b4be4788c47534905f0be ] Commit 01c9348c7620ec65 powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* updated arch_get_random_[int|long]() to be NOPs, and moved the hardware RNG backing to arch_get_random_seed_[int|long]() instead. However, it failed to take into account that arch_get_random_int() was implemented in terms of arch_get_random_long(), and so we ended up with a version of the former that is essentially a NOP as well. Fix this by calling arch_get_random_seed_long() from arch_get_random_seed_int() instead. Fixes: 01c9348c7620ec65 ("powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*") Signed-off-by: Ard Biesheuvel Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191204115015.18015-1-a...@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/archrandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 9c63b596e6ce..a09595f00cab 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -28,7 +28,7 @@ static inline int arch_get_random_seed_int(unsigned int *v) unsigned long val; int rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; -- 2.20.1
[PATCH AUTOSEL 4.19 023/671] usb: gadget: fsl_udc_core: check allocation return value and cleanup on failure
From: Nicholas Mc Guire [ Upstream commit 4ab2b48c98f2ec9712452d520a381917f91ac3d2 ] The allocation with fsl_alloc_request() and kmalloc() were unchecked fixed this up with a NULL check and appropriate cleanup. Additionally udc->ep_qh_size was reset to 0 on failure of allocation. Similar udc->phy_mode is initially 0 (as udc_controller was allocated with kzalloc in fsl_udc_probe()) so reset it to 0 as well so that this function is side-effect free on failure. Not clear if this is necessary or sensible as fsl_udc_release() probably can not be called if fsl_udc_probe() failed - but it should not hurt. Signed-off-by: Nicholas Mc Guire Fixes: b504882da5 ("USB: add Freescale high-speed USB SOC device controller driver") Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/fsl_udc_core.c | 30 +++ 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index d44b26d5b2a2..367697144cda 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2247,8 +2247,10 @@ static int struct_udc_setup(struct fsl_udc *udc, udc->phy_mode = pdata->phy_mode; udc->eps = kcalloc(udc->max_ep, sizeof(struct fsl_ep), GFP_KERNEL); - if (!udc->eps) - return -1; + if (!udc->eps) { + ERR("kmalloc udc endpoint status failed\n"); + goto eps_alloc_failed; + } /* initialized QHs, take care of alignment */ size = udc->max_ep * sizeof(struct ep_queue_head); @@ -2262,8 +2264,7 @@ static int struct_udc_setup(struct fsl_udc *udc, &udc->ep_qh_dma, GFP_KERNEL); if (!udc->ep_qh) { ERR("malloc QHs for udc failed\n"); - kfree(udc->eps); - return -1; + goto ep_queue_alloc_failed; } udc->ep_qh_size = size; @@ -2272,8 +2273,17 @@ static int struct_udc_setup(struct fsl_udc *udc, /* FIXME: fsl_alloc_request() ignores ep argument */ udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), struct fsl_req, req); + if (!udc->status_req) { + ERR("kzalloc for udc status request failed\n"); + goto udc_status_alloc_failed; + } + /* allocate a small amount of memory to get valid address */ udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); + if (!udc->status_req->req.buf) { + ERR("kzalloc for udc request buffer failed\n"); + goto udc_req_buf_alloc_failed; + } udc->resume_state = USB_STATE_NOTATTACHED; udc->usb_state = USB_STATE_POWERED; @@ -2281,6 +2291,18 @@ static int struct_udc_setup(struct fsl_udc *udc, udc->remote_wakeup = 0; /* default to 0 on reset */ return 0; + +udc_req_buf_alloc_failed: + kfree(udc->status_req); +udc_status_alloc_failed: + kfree(udc->ep_qh); + udc->ep_qh_size = 0; +ep_queue_alloc_failed: + kfree(udc->eps); +eps_alloc_failed: + udc->phy_mode = 0; + return -1; + } /* -- 2.20.1
[PATCH AUTOSEL 4.19 034/671] powerpc/pseries/memory-hotplug: Fix return value type of find_aa_index
From: YueHaibing [ Upstream commit b45e9d761ba2d60044b610297e3ef9f947ac157f ] The variable 'aa_index' is defined as an unsigned value in update_lmb_associativity_index(), but find_aa_index() may return -1 when dlpar_clone_property() fails. So change find_aa_index() to return a bool, which indicates whether 'aa_index' was found or not. Fixes: c05a5a40969e ("powerpc/pseries: Dynamic add entires to associativity lookup array") Signed-off-by: YueHaibing Reviewed-by: Nathan Fontenot nf...@linux.vnet.ibm.com> [mpe: Tweak changelog, rename is_found to just found] Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- .../platforms/pseries/hotplug-memory.c| 61 +-- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 7f86bc3eaade..62d3c72cd931 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -101,11 +101,12 @@ static struct property *dlpar_clone_property(struct property *prop, return new_prop; } -static u32 find_aa_index(struct device_node *dr_node, -struct property *ala_prop, const u32 *lmb_assoc) +static bool find_aa_index(struct device_node *dr_node, +struct property *ala_prop, +const u32 *lmb_assoc, u32 *aa_index) { - u32 *assoc_arrays; - u32 aa_index; + u32 *assoc_arrays, new_prop_size; + struct property *new_prop; int aa_arrays, aa_array_entries, aa_array_sz; int i, index; @@ -121,46 +122,39 @@ static u32 find_aa_index(struct device_node *dr_node, aa_array_entries = be32_to_cpu(assoc_arrays[1]); aa_array_sz = aa_array_entries * sizeof(u32); - aa_index = -1; for (i = 0; i < aa_arrays; i++) { index = (i * aa_array_entries) + 2; if (memcmp(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz)) continue; - aa_index = i; - break; + *aa_index = i; + return true; } - if (aa_index == -1) { - struct property *new_prop; - u32 new_prop_size; - - new_prop_size = ala_prop->length + aa_array_sz; - new_prop = dlpar_clone_property(ala_prop, new_prop_size); - if (!new_prop) - return -1; - - assoc_arrays = new_prop->value; + new_prop_size = ala_prop->length + aa_array_sz; + new_prop = dlpar_clone_property(ala_prop, new_prop_size); + if (!new_prop) + return false; - /* increment the number of entries in the lookup array */ - assoc_arrays[0] = cpu_to_be32(aa_arrays + 1); + assoc_arrays = new_prop->value; - /* copy the new associativity into the lookup array */ - index = aa_arrays * aa_array_entries + 2; - memcpy(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz); + /* increment the number of entries in the lookup array */ + assoc_arrays[0] = cpu_to_be32(aa_arrays + 1); - of_update_property(dr_node, new_prop); + /* copy the new associativity into the lookup array */ + index = aa_arrays * aa_array_entries + 2; + memcpy(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz); - /* -* The associativity lookup array index for this lmb is -* number of entries - 1 since we added its associativity -* to the end of the lookup array. -*/ - aa_index = be32_to_cpu(assoc_arrays[0]) - 1; - } + of_update_property(dr_node, new_prop); - return aa_index; + /* +* The associativity lookup array index for this lmb is +* number of entries - 1 since we added its associativity +* to the end of the lookup array. +*/ + *aa_index = be32_to_cpu(assoc_arrays[0]) - 1; + return true; } static int update_lmb_associativity_index(struct drmem_lmb *lmb) @@ -169,6 +163,7 @@ static int update_lmb_associativity_index(struct drmem_lmb *lmb) struct property *ala_prop; const u32 *lmb_assoc; u32 aa_index; + bool found; parent = of_find_node_by_path("/"); if (!parent) @@ -200,12 +195,12 @@ static int update_lmb_associativity_index(struct drmem_lmb *lmb) return -ENODEV; } - aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc); + found = find_aa_index(dr_node, ala_prop, lmb_assoc, &aa_index); of_node_put(dr_node); dlpar_free_cc_nodes(lmb_node); - if (aa_index < 0) { + if (!found) { pr_err("Could not find LMB associativity\n"); return -1; } -- 2.20.1
[PATCH AUTOSEL 4.19 038/671] powerpc/kgdb: add kgdb_arch_set/remove_breakpoint()
From: Christophe Leroy [ Upstream commit fb978ca207743badfe7efd9eebe68bcbb4969f79 ] Generic implementation fails to remove breakpoints after init when CONFIG_STRICT_KERNEL_RWX is selected: [ 13.251285] KGDB: BP remove failed: c001c338 [ 13.259587] kgdbts: ERROR PUT: end of test buffer on 'do_fork_test' line 8 expected OK got $E14#aa [ 13.268969] KGDB: re-enter exception: ALL breakpoints killed [ 13.275099] CPU: 0 PID: 1 Comm: init Not tainted 4.18.0-g82bbb913ffd8 #860 [ 13.282836] Call Trace: [ 13.285313] [c60e1ba0] [c0080ef0] kgdb_handle_exception+0x6f4/0x720 (unreliable) [ 13.292618] [c60e1c30] [c000e97c] kgdb_handle_breakpoint+0x3c/0x98 [ 13.298709] [c60e1c40] [c000af54] program_check_exception+0x104/0x700 [ 13.305083] [c60e1c60] [c000e45c] ret_from_except_full+0x0/0x4 [ 13.310845] [c60e1d20] [c02a22ac] run_simple_test+0x2b4/0x2d4 [ 13.316532] [c60e1d30] [c0081698] put_packet+0xb8/0x158 [ 13.321694] [c60e1d60] [c00820b4] gdb_serial_stub+0x230/0xc4c [ 13.327374] [c60e1dc0] [c0080af8] kgdb_handle_exception+0x2fc/0x720 [ 13.333573] [c60e1e50] [c000e928] kgdb_singlestep+0xb4/0xcc [ 13.339068] [c60e1e70] [c000ae1c] single_step_exception+0x90/0xac [ 13.345100] [c60e1e80] [c000e45c] ret_from_except_full+0x0/0x4 [ 13.350865] [c60e1f40] [c000e11c] ret_from_syscall+0x0/0x38 [ 13.356346] Kernel panic - not syncing: Recursive entry to debugger This patch creates powerpc specific version of kgdb_arch_set_breakpoint() and kgdb_arch_remove_breakpoint() using patch_instruction() Fixes: 1e0fc9d1eb2b ("powerpc/Kconfig: Enable STRICT_KERNEL_RWX for some configs") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/kgdb.h | 5 +++- arch/powerpc/kernel/kgdb.c | 43 +++-- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/kgdb.h b/arch/powerpc/include/asm/kgdb.h index 9db24e77b9f4..a9e098a3b881 100644 --- a/arch/powerpc/include/asm/kgdb.h +++ b/arch/powerpc/include/asm/kgdb.h @@ -26,9 +26,12 @@ #define BREAK_INSTR_SIZE 4 #define BUFMAX ((NUMREGBYTES * 2) + 512) #define OUTBUFMAX ((NUMREGBYTES * 2) + 512) + +#define BREAK_INSTR0x7d821008 /* twge r2, r2 */ + static inline void arch_kgdb_breakpoint(void) { - asm(".long 0x7d821008"); /* twge r2, r2 */ + asm(stringify_in_c(.long BREAK_INSTR)); } #define CACHE_FLUSH_IS_SAFE1 #define DBG_MAX_REG_NUM 70 diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 35e240a0a408..59c578f865aa 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* @@ -144,7 +145,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) return 0; - if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) + if (*(u32 *)regs->nip == BREAK_INSTR) regs->nip += BREAK_INSTR_SIZE; return 1; @@ -441,16 +442,42 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, return -1; } +int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) +{ + int err; + unsigned int instr; + unsigned int *addr = (unsigned int *)bpt->bpt_addr; + + err = probe_kernel_address(addr, instr); + if (err) + return err; + + err = patch_instruction(addr, BREAK_INSTR); + if (err) + return -EFAULT; + + *(unsigned int *)bpt->saved_instr = instr; + + return 0; +} + +int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) +{ + int err; + unsigned int instr = *(unsigned int *)bpt->saved_instr; + unsigned int *addr = (unsigned int *)bpt->bpt_addr; + + err = patch_instruction(addr, instr); + if (err) + return -EFAULT; + + return 0; +} + /* * Global data */ -struct kgdb_arch arch_kgdb_ops = { -#ifdef __LITTLE_ENDIAN__ - .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d}, -#else - .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, -#endif -}; +struct kgdb_arch arch_kgdb_ops; static int kgdb_not_implemented(struct pt_regs *regs) { -- 2.20.1
Re: [PATCH vdsotest] Use vdso wrapper for gettimeofday()
Hi Christophe, Christophe Leroy writes: > To properly handle errors returned by gettimeofday(), the > DO_VDSO_CALL() macro has to be used, otherwise vdsotest > misinterpret VDSO function return on error. > > This has gone unnoticed until now because the powerpc VDSO > gettimeofday() always succeed, but while porting powerpc to > generic C VDSO, the following has been encountered: Thanks for this, I'll review it soon. Can you point me to patches for the powerpc generic vdso work?
[PATCH AUTOSEL 4.19 122/671] ASoC: imx-sgtl5000: put of nodes if finding codec fails
From: Stefan Agner [ Upstream commit d9866572486802bc598a3e8576a5231378d190de ] Make sure to properly put the of node in case finding the codec fails. Fixes: 81e8e4926167 ("ASoC: fsl: add sgtl5000 clock support for imx-sgtl5000") Signed-off-by: Stefan Agner Reviewed-by: Daniel Baluta Acked-by: Nicolin Chen Reviewed-by: Fabio Estevam Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/imx-sgtl5000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 9b9a7ec52905..4bd8da3a5f5b 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -112,7 +112,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev) { dev_err(&pdev->dev, "failed to find codec platform device\n"); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto fail; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -- 2.20.1
[PATCH AUTOSEL 4.19 192/671] KVM: PPC: Release all hardware TCE tables attached to a group
From: Alexey Kardashevskiy [ Upstream commit a67614cc05a5052b265ea48196dab2fce11f5f2e ] The SPAPR TCE KVM device references all hardware IOMMU tables assigned to some IOMMU group to ensure that in-kernel KVM acceleration of H_PUT_TCE can work. The tables are references when an IOMMU group gets registered with the VFIO KVM device by the KVM_DEV_VFIO_GROUP_ADD ioctl; KVM_DEV_VFIO_GROUP_DEL calls into the dereferencing code in kvm_spapr_tce_release_iommu_group() which walks through the list of LIOBNs, finds a matching IOMMU table and calls kref_put() when found. However that code stops after the very first successful derefencing leaving other tables referenced till the SPAPR TCE KVM device is destroyed which normally happens on guest reboot or termination so if we do hotplug and unplug in a loop, we are leaking IOMMU tables here. This removes a premature return to let kvm_spapr_tce_release_iommu_group() find and dereference all attached tables. Fixes: 121f80ba68f ("KVM: PPC: VFIO: Add in-kernel acceleration for VFIO") Signed-off-by: Alexey Kardashevskiy Signed-off-by: Paul Mackerras Signed-off-by: Sasha Levin --- arch/powerpc/kvm/book3s_64_vio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 65486c3d029b..26b03af71abd 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -133,7 +133,6 @@ extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm, continue; kref_put(&stit->kref, kvm_spapr_tce_liobn_put); - return; } } } -- 2.20.1
[PATCH AUTOSEL 4.19 210/671] powerpc/64s: Fix logic when handling unknown CPU features
From: Michael Ellerman [ Upstream commit 8cfaf106918a8c13abb24c641556172afbb9545c ] In cpufeatures_process_feature(), if a provided CPU feature is unknown and enable_unknown is false, we erroneously print that the feature is being enabled and return true, even though no feature has been enabled, and may also set feature bits based on the last entry in the match table. Fix this so that we only set feature bits from the match table if we have actually enabled a feature from that table, and when failing to enable an unknown feature, always print the "not enabling" message and return false. Coincidentally, some older gccs (cpu_ftr_bit_mask) An upcoming patch will enable support for kcov, which requires this option. This patch avoids the warning. Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for discovering CPU features") Reported-by: Segher Boessenkool Signed-off-by: Michael Ellerman [ajd: add commit message] Signed-off-by: Andrew Donnellan Signed-off-by: Sasha Levin --- arch/powerpc/kernel/dt_cpu_ftrs.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index c6f41907f0d7..a4b31e17492d 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -666,8 +666,10 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) m = &dt_cpu_feature_match_table[i]; if (!strcmp(f->name, m->name)) { known = true; - if (m->enable(f)) + if (m->enable(f)) { + cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask; break; + } pr_info("not enabling: %s (disabled or unsupported by kernel)\n", f->name); @@ -675,17 +677,12 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) } } - if (!known && enable_unknown) { - if (!feat_try_enable_unknown(f)) { - pr_info("not enabling: %s (unknown and unsupported by kernel)\n", - f->name); - return false; - } + if (!known && (!enable_unknown || !feat_try_enable_unknown(f))) { + pr_info("not enabling: %s (unknown and unsupported by kernel)\n", + f->name); + return false; } - if (m->cpu_ftr_bit_mask) - cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask; - if (known) pr_debug("enabling: %s\n", f->name); else -- 2.20.1
[PATCH AUTOSEL 4.19 233/671] powerpc/mm: Check secondary hash page table
From: Rashmica Gupta [ Upstream commit 790845e2f12709d273d08ea7a2af7c2593689519 ] We were always calling base_hpte_find() with primary = true, even when we wanted to check the secondary table. mpe: I broke this when refactoring Rashmica's original patch. Fixes: 1515ab932156 ("powerpc/mm: Dump hash table") Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/mm/dump_hashpagetable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/dump_hashpagetable.c index 869294695048..b430e4e08af6 100644 --- a/arch/powerpc/mm/dump_hashpagetable.c +++ b/arch/powerpc/mm/dump_hashpagetable.c @@ -342,7 +342,7 @@ static unsigned long hpte_find(struct pg_state *st, unsigned long ea, int psize) /* Look in secondary table */ if (slot == -1) - slot = base_hpte_find(ea, psize, true, &v, &r); + slot = base_hpte_find(ea, psize, false, &v, &r); /* No entry found */ if (slot == -1) -- 2.20.1
[PATCH AUTOSEL 4.19 273/671] soc/fsl/qe: Fix an error code in qe_pin_request()
From: Dan Carpenter [ Upstream commit 5674a92ca4b7e5a6a19231edd10298d30324cd27 ] We forgot to set "err" on this error path. Fixes: 1a2d397a6eb5 ("gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()") Signed-off-by: Dan Carpenter Signed-off-by: Li Yang Signed-off-by: Sasha Levin --- drivers/soc/fsl/qe/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 819bed0f5667..51b3a47b5a55 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -179,8 +179,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) if (err < 0) goto err0; gc = gpio_to_chip(err); - if (WARN_ON(!gc)) + if (WARN_ON(!gc)) { + err = -ENODEV; goto err0; + } if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { pr_debug("%s: tried to get a non-qe pin\n", __func__); -- 2.20.1
[PATCH AUTOSEL 4.19 304/671] powerpc: vdso: Make vdso32 installation conditional in vdso_install
From: Ben Hutchings [ Upstream commit ff6d27823f619892ab96f7461764840e0d786b15 ] The 32-bit vDSO is not needed and not normally built for 64-bit little-endian configurations. However, the vdso_install target still builds and installs it. Add the same config condition as is normally used for the build. Fixes: e0d005916994 ("powerpc/vdso: Disable building the 32-bit VDSO ...") Signed-off-by: Ben Hutchings Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e43321f46a3b..8954108df457 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -412,7 +412,9 @@ vdso_install: ifdef CONFIG_PPC64 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ endif +ifdef CONFIG_VDSO32 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ +endif archclean: $(Q)$(MAKE) $(clean)=$(boot) -- 2.20.1
[PATCH AUTOSEL 4.19 319/671] KVM: PPC: Book3S HV: Fix lockdep warning when entering the guest
From: Alexey Kardashevskiy [ Upstream commit 3309bec85e60d60d6394802cb8e183a4f4a72def ] The trace_hardirqs_on() sets current->hardirqs_enabled and from here the lockdep assumes interrupts are enabled although they are remain disabled until the context switches to the guest. Consequent srcu_read_lock() checks the flags in rcu_lock_acquire(), observes disabled interrupts and prints a warning (see below). This moves trace_hardirqs_on/off closer to __kvmppc_vcore_entry to prevent lockdep from being confused. DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled) WARNING: CPU: 16 PID: 8038 at kernel/locking/lockdep.c:4128 check_flags.part.25+0x224/0x280 [...] NIP [c0185b84] check_flags.part.25+0x224/0x280 LR [c0185b80] check_flags.part.25+0x220/0x280 Call Trace: [c03fec253710] [c0185b80] check_flags.part.25+0x220/0x280 (unreliable) [c03fec253780] [c0187ea4] lock_acquire+0x94/0x260 [c03fec253840] [c0081a1e9768] kvmppc_run_core+0xa60/0x1ab0 [kvm_hv] [c03fec253a10] [c0081a1ed944] kvmppc_vcpu_run_hv+0x73c/0xec0 [kvm_hv] [c03fec253ae0] [c0081a1095dc] kvmppc_vcpu_run+0x34/0x48 [kvm] [c03fec253b00] [c0081a1056bc] kvm_arch_vcpu_ioctl_run+0x2f4/0x400 [kvm] [c03fec253b90] [c0081a0f3618] kvm_vcpu_ioctl+0x460/0x850 [kvm] [c03fec253d00] [c041c4f4] do_vfs_ioctl+0xe4/0x930 [c03fec253db0] [c041ce04] ksys_ioctl+0xc4/0x110 [c03fec253e00] [c041ce78] sys_ioctl+0x28/0x80 [c03fec253e20] [c000b5a4] system_call+0x5c/0x70 Instruction dump: 419e0034 3d220004 39291730 8129 2f89 409e0020 3c82ffc6 3c62ffc5 3884be70 386329c0 4bf6ea71 6000 <0fe0> 3c62ffc6 3863be90 4801273d irq event stamp: 1025 hardirqs last enabled at (1025): [] kvmppc_run_core+0xa20/0x1ab0 [kvm_hv] hardirqs last disabled at (1024): [] kvmppc_run_core+0x650/0x1ab0 [kvm_hv] softirqs last enabled at (0): [] copy_process.isra.4.part.5+0x5f0/0x1d00 softirqs last disabled at (0): [<>] (null) ---[ end trace 31180adcc848993e ]--- possible reason: unannotated irqs-off. irq event stamp: 1025 hardirqs last enabled at (1025): [] kvmppc_run_core+0xa20/0x1ab0 [kvm_hv] hardirqs last disabled at (1024): [] kvmppc_run_core+0x650/0x1ab0 [kvm_hv] softirqs last enabled at (0): [] copy_process.isra.4.part.5+0x5f0/0x1d00 softirqs last disabled at (0): [<>] (null) Fixes: 8b24e69fc47e ("KVM: PPC: Book3S HV: Close race with testing for signals on guest entry", 2017-06-26) Signed-off-by: Alexey Kardashevskiy Signed-off-by: Paul Mackerras Signed-off-by: Sasha Levin --- arch/powerpc/kvm/book3s_hv.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 3ae3e8d141e3..dbfe32327212 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2993,25 +2993,26 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) } } - /* -* Interrupts will be enabled once we get into the guest, -* so tell lockdep that we're about to enable interrupts. -*/ - trace_hardirqs_on(); - guest_enter_irqoff(); srcu_idx = srcu_read_lock(&vc->kvm->srcu); this_cpu_disable_ftrace(); + /* +* Interrupts will be enabled once we get into the guest, +* so tell lockdep that we're about to enable interrupts. +*/ + trace_hardirqs_on(); + trap = __kvmppc_vcore_entry(); + trace_hardirqs_off(); + this_cpu_enable_ftrace(); srcu_read_unlock(&vc->kvm->srcu, srcu_idx); - trace_hardirqs_off(); set_irq_happened(trap); spin_lock(&vc->lock); -- 2.20.1
[PATCH AUTOSEL 4.19 415/671] powerpc/cacheinfo: add cacheinfo_teardown, cacheinfo_rebuild
From: Nathan Lynch [ Upstream commit d4aa219a074a5abaf95a756b9f0d190b5c03a945 ] Allow external callers to force the cacheinfo code to release all its references to cache nodes, e.g. before processing device tree updates post-migration, and to rebuild the hierarchy afterward. CPU online/offline must be blocked by callers; enforce this. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/cacheinfo.c | 21 + arch/powerpc/kernel/cacheinfo.h | 4 2 files changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index a8f20e5928e1..9edb45430133 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -865,4 +865,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) if (cache) cache_cpu_clear(cache, cpu_id); } + +void cacheinfo_teardown(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_offline(cpu); +} + +void cacheinfo_rebuild(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_online(cpu); +} + #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index 955f5e999f1b..52bd3fc6642d 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -6,4 +6,8 @@ extern void cacheinfo_cpu_online(unsigned int cpu_id); extern void cacheinfo_cpu_offline(unsigned int cpu_id); +/* Allow migration/suspend to tear down and rebuild the hierarchy. */ +extern void cacheinfo_teardown(void); +extern void cacheinfo_rebuild(void); + #endif /* _PPC_CACHEINFO_H */ -- 2.20.1
[PATCH AUTOSEL 4.19 416/671] powerpc/pseries/mobility: rebuild cacheinfo hierarchy post-migration
From: Nathan Lynch [ Upstream commit e610a466d16a086e321f0bd421e2fc75cff28605 ] It's common for the platform to replace the cache device nodes after a migration. Since the cacheinfo code is never informed about this, it never drops its references to the source system's cache nodes, causing it to wind up in an inconsistent state resulting in warnings and oopses as soon as CPU online/offline occurs after the migration, e.g. cache for /cpus/l3-cache@3113(Unified) refers to cache for /cpus/l2-cache@200d(Unified) WARNING: CPU: 15 PID: 86 at arch/powerpc/kernel/cacheinfo.c:176 release_cache+0x1bc/0x1d0 [...] NIP release_cache+0x1bc/0x1d0 LR release_cache+0x1b8/0x1d0 Call Trace: release_cache+0x1b8/0x1d0 (unreliable) cacheinfo_cpu_offline+0x1c4/0x2c0 unregister_cpu_online+0x1b8/0x260 cpuhp_invoke_callback+0x114/0xf40 cpuhp_thread_fun+0x270/0x310 smpboot_thread_fn+0x2c8/0x390 kthread+0x1b8/0x1c0 ret_from_kernel_thread+0x5c/0x68 Using device tree notifiers won't work since we want to rebuild the hierarchy only after all the removals and additions have occurred and the device tree is in a consistent state. Call cacheinfo_teardown() before processing device tree updates, and rebuild the hierarchy afterward. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/platforms/pseries/mobility.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index e4ea71383383..70744b4fbd9e 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -24,6 +24,7 @@ #include #include #include "pseries.h" +#include "../../kernel/cacheinfo.h" static struct kobject *mobility_kobj; @@ -360,11 +361,20 @@ void post_mobility_fixup(void) */ cpus_read_lock(); + /* +* It's common for the destination firmware to replace cache +* nodes. Release all of the cacheinfo hierarchy's references +* before updating the device tree. +*/ + cacheinfo_teardown(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc); + cacheinfo_rebuild(); + cpus_read_unlock(); /* Possibly switch to a new RFI flush type */ -- 2.20.1
[PATCH AUTOSEL 4.19 432/671] perf/ioctl: Add check for the sample_period value
From: Ravi Bangoria [ Upstream commit 913a90bc5a3a06b1f04c337320e9aeee2328dd77 ] perf_event_open() limits the sample_period to 63 bits. See: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Make ioctl() consistent with it. Also on PowerPC, negative sample_period could cause a recursive PMIs leading to a hang (reported when running perf-fuzzer). Signed-off-by: Ravi Bangoria Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: a...@kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: ma...@linux.vnet.ibm.com Cc: m...@ellerman.id.au Fixes: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Link: https://lkml.kernel.org/r/20190604042953.914-1-ravi.bango...@linux.ibm.com Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/events/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index 751888cbed5c..16af86ab24c4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5012,6 +5012,9 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg) if (perf_event_check_period(event, value)) return -EINVAL; + if (!event->attr.freq && (value & (1ULL << 63))) + return -EINVAL; + event_function_call(event, __perf_event_period, &value); return 0; -- 2.20.1
[PATCH AUTOSEL 4.19 475/671] ALSA: aoa: onyx: always initialize register read value
From: Johannes Berg [ Upstream commit f474808acb3c4b30552d9c59b181244e0300d218 ] A lot of places in the driver use onyx_read_register() without checking the return value, and it's been working OK for ~10 years or so, so probably never fails ... Rather than trying to check the return value everywhere, which would be relatively intrusive, at least make sure we don't use an uninitialized value. Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa") Reported-by: Stephen Rothwell Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/aoa/codecs/onyx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index d2d96ca082b7..6224fd3bbf7c 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -74,8 +74,10 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) return 0; } v = i2c_smbus_read_byte_data(onyx->i2c, reg); - if (v < 0) + if (v < 0) { + *value = 0; return -1; + } *value = (u8)v; onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value; return 0; -- 2.20.1
[PATCH AUTOSEL 4.19 499/671] powerpc/64s/radix: Fix memory hot-unplug page table split
From: Nicholas Piggin [ Upstream commit 31f210cf42d4b308eacef89b6cb0b1459338b8de ] create_physical_mapping expects physical addresses, but splitting these mapping on hot unplug is supplying virtual (effective) addresses. Fixes: 4dd5f8a99e791 ("powerpc/mm/radix: Split linear mapping on hot-unplug") Signed-off-by: Nicholas Piggin Reviewed-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190724084638.24982-2-npig...@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/mm/pgtable-radix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index 69caeb5bccb2..5404a631d583 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -717,8 +717,8 @@ static int __meminit stop_machine_change_mapping(void *data) spin_unlock(&init_mm.page_table_lock); pte_clear(&init_mm, params->aligned_start, params->pte); - create_physical_mapping(params->aligned_start, params->start, -1); - create_physical_mapping(params->end, params->aligned_end, -1); + create_physical_mapping(__pa(params->aligned_start), __pa(params->start), -1); + create_physical_mapping(__pa(params->end), __pa(params->aligned_end), -1); spin_lock(&init_mm.page_table_lock); return 0; } -- 2.20.1
Re: z constraint in powerpc inline assembly ?
Le 16/01/2020 à 17:21, Segher Boessenkool a écrit : Christophe uses a very primitive 32-bit cpu, not even superscalar. A loop doing adde is pretty much optimal, probably wants some unrolling though. You mean the mpc8xx , but I'm also using the mpc832x which has a e300c2 core and is capable of executing 2 insns in parallel if not in the same Unit. Christophe
[PATCH AUTOSEL 4.19 557/671] powerpc/mm/mce: Keep irqs disabled during lockless page table walk
From: "Aneesh Kumar K.V" [ Upstream commit d9101bfa6adc831bda8836c4d774820553c14942 ] __find_linux_mm_pte() returns a page table entry pointer after walking the page table without holding locks. To make it safe against a THP split and/or collapse, we disable interrupts around the lockless page table walk. However we need to keep interrupts disabled as long as we use the page table entry pointer that is returned. Fix addr_to_pfn() to do that. Fixes: ba41e1e1ccb9 ("powerpc/mce: Hookup derror (load/store) UE errors") Signed-off-by: Aneesh Kumar K.V [mpe: Rearrange code slightly and tweak change log wording] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190918145328.28602-1-aneesh.ku...@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/mce_power.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 37a110b8e7e1..ecb375040637 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -40,7 +40,7 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr) { pte_t *ptep; unsigned int shift; - unsigned long flags; + unsigned long pfn, flags; struct mm_struct *mm; if (user_mode(regs)) @@ -50,18 +50,22 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr) local_irq_save(flags); ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift); - local_irq_restore(flags); - if (!ptep || pte_special(*ptep)) - return ULONG_MAX; + if (!ptep || pte_special(*ptep)) { + pfn = ULONG_MAX; + goto out; + } - if (shift > PAGE_SHIFT) { + if (shift <= PAGE_SHIFT) + pfn = pte_pfn(*ptep); + else { unsigned long rpnmask = (1ul << shift) - PAGE_SIZE; - - return pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask))); + pfn = pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask))); } - return pte_pfn(*ptep); +out: + local_irq_restore(flags); + return pfn; } /* flush SLBs and reload */ -- 2.20.1
[PATCH AUTOSEL 4.19 655/671] powerpc/powernv: Disable native PCIe port management
From: Oliver O'Halloran [ Upstream commit 9d72dcef891030545f39ad386a30cf91df517fb2 ] On PowerNV the PCIe topology is (currently) managed by the powernv platform code in Linux in cooperation with the platform firmware. Linux's native PCIe port service drivers operate independently of both and this can cause problems. The main issue is that the portbus driver will conflict with the platform specific hotplug driver (pnv_php) over ownership of the MSI used to notify the host when a hotplug event occurs. The portbus driver claims this MSI on behalf of the individual port services because the same interrupt is used for hotplug events, PMEs (on root ports), and link bandwidth change notifications. The portbus driver will always claim the interrupt even if the individual port service drivers, such as pciehp, are compiled out. The second, bigger, problem is that the hotplug port service driver fundamentally does not work on PowerNV. The platform assumes that all PCI devices have a corresponding arch-specific handle derived from the DT node for the device (pci_dn) and without one the platform will not allow a PCI device to be enabled. This problem is largely due to historical baggage, but it can't be resolved without significant re-factoring of the platform PCI support. We can fix these problems in the interim by setting the "pcie_ports_disabled" flag during platform initialisation. The flag indicates the platform owns the PCIe ports which stops the portbus driver from being registered. This does have the side effect of disabling all port services drivers that is: AER, PME, BW notifications, hotplug, and DPC. However, this is not a huge disadvantage on PowerNV since these services are either unused or handled through other means. Fixes: 66725152fb9f ("PCI/hotplug: PowerPC PowerNV PCI hotplug driver") Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191118065553.30362-1-ooh...@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/pci.c | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index db230a35609b..c846300b7836 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -1095,6 +1095,23 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; +#ifdef CONFIG_PCIEPORTBUS + /* +* On PowerNV PCIe devices are (currently) managed in cooperation +* with firmware. This isn't *strictly* required, but there's enough +* assumptions baked into both firmware and the platform code that +* it's unwise to allow the portbus services to be used. +* +* We need to fix this eventually, but for now set this flag to disable +* the portbus driver. The AER service isn't required since that AER +* events are handled via EEH. The pciehp hotplug driver can't work +* without kernel changes (and portbus binding breaks pnv_php). The +* other services also require some thinking about how we're going +* to integrate them. +*/ + pcie_ports_disabled = true; +#endif + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); -- 2.20.1
[PATCH AUTOSEL 4.19 665/671] powerpc/archrandom: fix arch_get_random_seed_int()
From: Ard Biesheuvel [ Upstream commit b6afd1234cf93aa0d71b4be4788c47534905f0be ] Commit 01c9348c7620ec65 powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* updated arch_get_random_[int|long]() to be NOPs, and moved the hardware RNG backing to arch_get_random_seed_[int|long]() instead. However, it failed to take into account that arch_get_random_int() was implemented in terms of arch_get_random_long(), and so we ended up with a version of the former that is essentially a NOP as well. Fix this by calling arch_get_random_seed_long() from arch_get_random_seed_int() instead. Fixes: 01c9348c7620ec65 ("powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*") Signed-off-by: Ard Biesheuvel Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191204115015.18015-1-a...@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/archrandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 9c63b596e6ce..a09595f00cab 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -28,7 +28,7 @@ static inline int arch_get_random_seed_int(unsigned int *v) unsigned long val; int rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; -- 2.20.1
[PATCH AUTOSEL 4.14 013/371] powerpc/kgdb: add kgdb_arch_set/remove_breakpoint()
From: Christophe Leroy [ Upstream commit fb978ca207743badfe7efd9eebe68bcbb4969f79 ] Generic implementation fails to remove breakpoints after init when CONFIG_STRICT_KERNEL_RWX is selected: [ 13.251285] KGDB: BP remove failed: c001c338 [ 13.259587] kgdbts: ERROR PUT: end of test buffer on 'do_fork_test' line 8 expected OK got $E14#aa [ 13.268969] KGDB: re-enter exception: ALL breakpoints killed [ 13.275099] CPU: 0 PID: 1 Comm: init Not tainted 4.18.0-g82bbb913ffd8 #860 [ 13.282836] Call Trace: [ 13.285313] [c60e1ba0] [c0080ef0] kgdb_handle_exception+0x6f4/0x720 (unreliable) [ 13.292618] [c60e1c30] [c000e97c] kgdb_handle_breakpoint+0x3c/0x98 [ 13.298709] [c60e1c40] [c000af54] program_check_exception+0x104/0x700 [ 13.305083] [c60e1c60] [c000e45c] ret_from_except_full+0x0/0x4 [ 13.310845] [c60e1d20] [c02a22ac] run_simple_test+0x2b4/0x2d4 [ 13.316532] [c60e1d30] [c0081698] put_packet+0xb8/0x158 [ 13.321694] [c60e1d60] [c00820b4] gdb_serial_stub+0x230/0xc4c [ 13.327374] [c60e1dc0] [c0080af8] kgdb_handle_exception+0x2fc/0x720 [ 13.333573] [c60e1e50] [c000e928] kgdb_singlestep+0xb4/0xcc [ 13.339068] [c60e1e70] [c000ae1c] single_step_exception+0x90/0xac [ 13.345100] [c60e1e80] [c000e45c] ret_from_except_full+0x0/0x4 [ 13.350865] [c60e1f40] [c000e11c] ret_from_syscall+0x0/0x38 [ 13.356346] Kernel panic - not syncing: Recursive entry to debugger This patch creates powerpc specific version of kgdb_arch_set_breakpoint() and kgdb_arch_remove_breakpoint() using patch_instruction() Fixes: 1e0fc9d1eb2b ("powerpc/Kconfig: Enable STRICT_KERNEL_RWX for some configs") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/kgdb.h | 5 +++- arch/powerpc/kernel/kgdb.c | 43 +++-- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/kgdb.h b/arch/powerpc/include/asm/kgdb.h index 9db24e77b9f4..a9e098a3b881 100644 --- a/arch/powerpc/include/asm/kgdb.h +++ b/arch/powerpc/include/asm/kgdb.h @@ -26,9 +26,12 @@ #define BREAK_INSTR_SIZE 4 #define BUFMAX ((NUMREGBYTES * 2) + 512) #define OUTBUFMAX ((NUMREGBYTES * 2) + 512) + +#define BREAK_INSTR0x7d821008 /* twge r2, r2 */ + static inline void arch_kgdb_breakpoint(void) { - asm(".long 0x7d821008"); /* twge r2, r2 */ + asm(stringify_in_c(.long BREAK_INSTR)); } #define CACHE_FLUSH_IS_SAFE1 #define DBG_MAX_REG_NUM 70 diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 35e240a0a408..59c578f865aa 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* @@ -144,7 +145,7 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs) if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) return 0; - if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr)) + if (*(u32 *)regs->nip == BREAK_INSTR) regs->nip += BREAK_INSTR_SIZE; return 1; @@ -441,16 +442,42 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, return -1; } +int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) +{ + int err; + unsigned int instr; + unsigned int *addr = (unsigned int *)bpt->bpt_addr; + + err = probe_kernel_address(addr, instr); + if (err) + return err; + + err = patch_instruction(addr, BREAK_INSTR); + if (err) + return -EFAULT; + + *(unsigned int *)bpt->saved_instr = instr; + + return 0; +} + +int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) +{ + int err; + unsigned int instr = *(unsigned int *)bpt->saved_instr; + unsigned int *addr = (unsigned int *)bpt->bpt_addr; + + err = patch_instruction(addr, instr); + if (err) + return -EFAULT; + + return 0; +} + /* * Global data */ -struct kgdb_arch arch_kgdb_ops = { -#ifdef __LITTLE_ENDIAN__ - .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d}, -#else - .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, -#endif -}; +struct kgdb_arch arch_kgdb_ops; static int kgdb_not_implemented(struct pt_regs *regs) { -- 2.20.1
RE: z constraint in powerpc inline assembly ?
> You mean the mpc8xx , but I'm also using the mpc832x which has a e300c2 > core and is capable of executing 2 insns in parallel if not in the same > Unit. That should let you do a memory read and an add. (I can't remember if the ppc has 'add from memory' but that is likely to use both units anyway.) An infinitely unrolled loop will then be 4 clocks/byte (for 32bit). If you get to 3 for a real loop you are doing ok. Remember, unroll too much and you displace other code from the i-cache. Also the i-cache loads themselves kill you. (A hot-cache benchmark won't see this...) David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
[PATCH AUTOSEL 4.14 062/371] ASoC: imx-sgtl5000: put of nodes if finding codec fails
From: Stefan Agner [ Upstream commit d9866572486802bc598a3e8576a5231378d190de ] Make sure to properly put the of node in case finding the codec fails. Fixes: 81e8e4926167 ("ASoC: fsl: add sgtl5000 clock support for imx-sgtl5000") Signed-off-by: Stefan Agner Reviewed-by: Daniel Baluta Acked-by: Nicolin Chen Reviewed-by: Fabio Estevam Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/imx-sgtl5000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 8e525f7ac08d..3d99a8579c99 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -119,7 +119,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev) { dev_err(&pdev->dev, "failed to find codec platform device\n"); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto fail; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -- 2.20.1
[PATCH AUTOSEL 4.14 103/371] KVM: PPC: Release all hardware TCE tables attached to a group
From: Alexey Kardashevskiy [ Upstream commit a67614cc05a5052b265ea48196dab2fce11f5f2e ] The SPAPR TCE KVM device references all hardware IOMMU tables assigned to some IOMMU group to ensure that in-kernel KVM acceleration of H_PUT_TCE can work. The tables are references when an IOMMU group gets registered with the VFIO KVM device by the KVM_DEV_VFIO_GROUP_ADD ioctl; KVM_DEV_VFIO_GROUP_DEL calls into the dereferencing code in kvm_spapr_tce_release_iommu_group() which walks through the list of LIOBNs, finds a matching IOMMU table and calls kref_put() when found. However that code stops after the very first successful derefencing leaving other tables referenced till the SPAPR TCE KVM device is destroyed which normally happens on guest reboot or termination so if we do hotplug and unplug in a loop, we are leaking IOMMU tables here. This removes a premature return to let kvm_spapr_tce_release_iommu_group() find and dereference all attached tables. Fixes: 121f80ba68f ("KVM: PPC: VFIO: Add in-kernel acceleration for VFIO") Signed-off-by: Alexey Kardashevskiy Signed-off-by: Paul Mackerras Signed-off-by: Sasha Levin --- arch/powerpc/kvm/book3s_64_vio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 5e4446296021..ef6a58838e7c 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -134,7 +134,6 @@ extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm, continue; kref_put(&stit->kref, kvm_spapr_tce_liobn_put); - return; } } } -- 2.20.1
[PATCH AUTOSEL 4.14 116/371] powerpc/64s: Fix logic when handling unknown CPU features
From: Michael Ellerman [ Upstream commit 8cfaf106918a8c13abb24c641556172afbb9545c ] In cpufeatures_process_feature(), if a provided CPU feature is unknown and enable_unknown is false, we erroneously print that the feature is being enabled and return true, even though no feature has been enabled, and may also set feature bits based on the last entry in the match table. Fix this so that we only set feature bits from the match table if we have actually enabled a feature from that table, and when failing to enable an unknown feature, always print the "not enabling" message and return false. Coincidentally, some older gccs (cpu_ftr_bit_mask) An upcoming patch will enable support for kcov, which requires this option. This patch avoids the warning. Fixes: 5a61ef74f269 ("powerpc/64s: Support new device tree binding for discovering CPU features") Reported-by: Segher Boessenkool Signed-off-by: Michael Ellerman [ajd: add commit message] Signed-off-by: Andrew Donnellan Signed-off-by: Sasha Levin --- arch/powerpc/kernel/dt_cpu_ftrs.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 2357df60de95..7ed2b1b6643c 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -705,8 +705,10 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) m = &dt_cpu_feature_match_table[i]; if (!strcmp(f->name, m->name)) { known = true; - if (m->enable(f)) + if (m->enable(f)) { + cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask; break; + } pr_info("not enabling: %s (disabled or unsupported by kernel)\n", f->name); @@ -714,17 +716,12 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) } } - if (!known && enable_unknown) { - if (!feat_try_enable_unknown(f)) { - pr_info("not enabling: %s (unknown and unsupported by kernel)\n", - f->name); - return false; - } + if (!known && (!enable_unknown || !feat_try_enable_unknown(f))) { + pr_info("not enabling: %s (unknown and unsupported by kernel)\n", + f->name); + return false; } - if (m->cpu_ftr_bit_mask) - cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask; - if (known) pr_debug("enabling: %s\n", f->name); else -- 2.20.1
[PATCH AUTOSEL 4.14 129/371] powerpc/mm: Check secondary hash page table
From: Rashmica Gupta [ Upstream commit 790845e2f12709d273d08ea7a2af7c2593689519 ] We were always calling base_hpte_find() with primary = true, even when we wanted to check the secondary table. mpe: I broke this when refactoring Rashmica's original patch. Fixes: 1515ab932156 ("powerpc/mm: Dump hash table") Signed-off-by: Rashmica Gupta Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/mm/dump_hashpagetable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/dump_hashpagetable.c index 5c4c93dcff19..f666d74f05f5 100644 --- a/arch/powerpc/mm/dump_hashpagetable.c +++ b/arch/powerpc/mm/dump_hashpagetable.c @@ -343,7 +343,7 @@ static unsigned long hpte_find(struct pg_state *st, unsigned long ea, int psize) /* Look in secondary table */ if (slot == -1) - slot = base_hpte_find(ea, psize, true, &v, &r); + slot = base_hpte_find(ea, psize, false, &v, &r); /* No entry found */ if (slot == -1) -- 2.20.1
[PATCH AUTOSEL 4.14 155/371] soc/fsl/qe: Fix an error code in qe_pin_request()
From: Dan Carpenter [ Upstream commit 5674a92ca4b7e5a6a19231edd10298d30324cd27 ] We forgot to set "err" on this error path. Fixes: 1a2d397a6eb5 ("gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()") Signed-off-by: Dan Carpenter Signed-off-by: Li Yang Signed-off-by: Sasha Levin --- drivers/soc/fsl/qe/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 3b27075c21a7..5cbc5ce5ac15 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -152,8 +152,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) if (err < 0) goto err0; gc = gpio_to_chip(err); - if (WARN_ON(!gc)) + if (WARN_ON(!gc)) { + err = -ENODEV; goto err0; + } if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { pr_debug("%s: tried to get a non-qe pin\n", __func__); -- 2.20.1
[PATCH AUTOSEL 4.14 166/371] powerpc: vdso: Make vdso32 installation conditional in vdso_install
From: Ben Hutchings [ Upstream commit ff6d27823f619892ab96f7461764840e0d786b15 ] The 32-bit vDSO is not needed and not normally built for 64-bit little-endian configurations. However, the vdso_install target still builds and installs it. Add the same config condition as is normally used for the build. Fixes: e0d005916994 ("powerpc/vdso: Disable building the 32-bit VDSO ...") Signed-off-by: Ben Hutchings Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 0f04c878113e..9c78ef298257 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -385,7 +385,9 @@ vdso_install: ifeq ($(CONFIG_PPC64),y) $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ endif +ifdef CONFIG_VDSO32 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ +endif archclean: $(Q)$(MAKE) $(clean)=$(boot) -- 2.20.1
[PATCH AUTOSEL 4.14 228/371] powerpc/cacheinfo: add cacheinfo_teardown, cacheinfo_rebuild
From: Nathan Lynch [ Upstream commit d4aa219a074a5abaf95a756b9f0d190b5c03a945 ] Allow external callers to force the cacheinfo code to release all its references to cache nodes, e.g. before processing device tree updates post-migration, and to rebuild the hierarchy afterward. CPU online/offline must be blocked by callers; enforce this. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/cacheinfo.c | 21 + arch/powerpc/kernel/cacheinfo.h | 4 2 files changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index a8f20e5928e1..9edb45430133 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -865,4 +865,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) if (cache) cache_cpu_clear(cache, cpu_id); } + +void cacheinfo_teardown(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_offline(cpu); +} + +void cacheinfo_rebuild(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_online(cpu); +} + #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index 955f5e999f1b..52bd3fc6642d 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -6,4 +6,8 @@ extern void cacheinfo_cpu_online(unsigned int cpu_id); extern void cacheinfo_cpu_offline(unsigned int cpu_id); +/* Allow migration/suspend to tear down and rebuild the hierarchy. */ +extern void cacheinfo_teardown(void); +extern void cacheinfo_rebuild(void); + #endif /* _PPC_CACHEINFO_H */ -- 2.20.1
[PATCH AUTOSEL 4.14 229/371] powerpc/pseries/mobility: rebuild cacheinfo hierarchy post-migration
From: Nathan Lynch [ Upstream commit e610a466d16a086e321f0bd421e2fc75cff28605 ] It's common for the platform to replace the cache device nodes after a migration. Since the cacheinfo code is never informed about this, it never drops its references to the source system's cache nodes, causing it to wind up in an inconsistent state resulting in warnings and oopses as soon as CPU online/offline occurs after the migration, e.g. cache for /cpus/l3-cache@3113(Unified) refers to cache for /cpus/l2-cache@200d(Unified) WARNING: CPU: 15 PID: 86 at arch/powerpc/kernel/cacheinfo.c:176 release_cache+0x1bc/0x1d0 [...] NIP release_cache+0x1bc/0x1d0 LR release_cache+0x1b8/0x1d0 Call Trace: release_cache+0x1b8/0x1d0 (unreliable) cacheinfo_cpu_offline+0x1c4/0x2c0 unregister_cpu_online+0x1b8/0x260 cpuhp_invoke_callback+0x114/0xf40 cpuhp_thread_fun+0x270/0x310 smpboot_thread_fn+0x2c8/0x390 kthread+0x1b8/0x1c0 ret_from_kernel_thread+0x5c/0x68 Using device tree notifiers won't work since we want to rebuild the hierarchy only after all the removals and additions have occurred and the device tree is in a consistent state. Call cacheinfo_teardown() before processing device tree updates, and rebuild the hierarchy afterward. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/platforms/pseries/mobility.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 9739a055e5f7..2d3668acb6ef 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -23,6 +23,7 @@ #include #include #include "pseries.h" +#include "../../kernel/cacheinfo.h" static struct kobject *mobility_kobj; @@ -359,11 +360,20 @@ void post_mobility_fixup(void) */ cpus_read_lock(); + /* +* It's common for the destination firmware to replace cache +* nodes. Release all of the cacheinfo hierarchy's references +* before updating the device tree. +*/ + cacheinfo_teardown(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc); + cacheinfo_rebuild(); + cpus_read_unlock(); /* Possibly switch to a new RFI flush type */ -- 2.20.1
[PATCH AUTOSEL 4.14 237/371] perf/ioctl: Add check for the sample_period value
From: Ravi Bangoria [ Upstream commit 913a90bc5a3a06b1f04c337320e9aeee2328dd77 ] perf_event_open() limits the sample_period to 63 bits. See: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Make ioctl() consistent with it. Also on PowerPC, negative sample_period could cause a recursive PMIs leading to a hang (reported when running perf-fuzzer). Signed-off-by: Ravi Bangoria Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: a...@kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: ma...@linux.vnet.ibm.com Cc: m...@ellerman.id.au Fixes: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Link: https://lkml.kernel.org/r/20190604042953.914-1-ravi.bango...@linux.ibm.com Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/events/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index ea4f3f7a0c6f..2ac73b4cb8a9 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4762,6 +4762,9 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg) if (perf_event_check_period(event, value)) return -EINVAL; + if (!event->attr.freq && (value & (1ULL << 63))) + return -EINVAL; + event_function_call(event, __perf_event_period, &value); return 0; -- 2.20.1
[PATCH AUTOSEL 4.14 257/371] ALSA: aoa: onyx: always initialize register read value
From: Johannes Berg [ Upstream commit f474808acb3c4b30552d9c59b181244e0300d218 ] A lot of places in the driver use onyx_read_register() without checking the return value, and it's been working OK for ~10 years or so, so probably never fails ... Rather than trying to check the return value everywhere, which would be relatively intrusive, at least make sure we don't use an uninitialized value. Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa") Reported-by: Stephen Rothwell Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/aoa/codecs/onyx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index d2d96ca082b7..6224fd3bbf7c 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -74,8 +74,10 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) return 0; } v = i2c_smbus_read_byte_data(onyx->i2c, reg); - if (v < 0) + if (v < 0) { + *value = 0; return -1; + } *value = (u8)v; onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value; return 0; -- 2.20.1
[PATCH AUTOSEL 4.14 360/371] powerpc/powernv: Disable native PCIe port management
From: Oliver O'Halloran [ Upstream commit 9d72dcef891030545f39ad386a30cf91df517fb2 ] On PowerNV the PCIe topology is (currently) managed by the powernv platform code in Linux in cooperation with the platform firmware. Linux's native PCIe port service drivers operate independently of both and this can cause problems. The main issue is that the portbus driver will conflict with the platform specific hotplug driver (pnv_php) over ownership of the MSI used to notify the host when a hotplug event occurs. The portbus driver claims this MSI on behalf of the individual port services because the same interrupt is used for hotplug events, PMEs (on root ports), and link bandwidth change notifications. The portbus driver will always claim the interrupt even if the individual port service drivers, such as pciehp, are compiled out. The second, bigger, problem is that the hotplug port service driver fundamentally does not work on PowerNV. The platform assumes that all PCI devices have a corresponding arch-specific handle derived from the DT node for the device (pci_dn) and without one the platform will not allow a PCI device to be enabled. This problem is largely due to historical baggage, but it can't be resolved without significant re-factoring of the platform PCI support. We can fix these problems in the interim by setting the "pcie_ports_disabled" flag during platform initialisation. The flag indicates the platform owns the PCIe ports which stops the portbus driver from being registered. This does have the side effect of disabling all port services drivers that is: AER, PME, BW notifications, hotplug, and DPC. However, this is not a huge disadvantage on PowerNV since these services are either unused or handled through other means. Fixes: 66725152fb9f ("PCI/hotplug: PowerPC PowerNV PCI hotplug driver") Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191118065553.30362-1-ooh...@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/pci.c | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index e2d031a3ec15..961c131a5b7e 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -1118,6 +1118,23 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; +#ifdef CONFIG_PCIEPORTBUS + /* +* On PowerNV PCIe devices are (currently) managed in cooperation +* with firmware. This isn't *strictly* required, but there's enough +* assumptions baked into both firmware and the platform code that +* it's unwise to allow the portbus services to be used. +* +* We need to fix this eventually, but for now set this flag to disable +* the portbus driver. The AER service isn't required since that AER +* events are handled via EEH. The pciehp hotplug driver can't work +* without kernel changes (and portbus binding breaks pnv_php). The +* other services also require some thinking about how we're going +* to integrate them. +*/ + pcie_ports_disabled = true; +#endif + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); -- 2.20.1
[PATCH AUTOSEL 4.14 369/371] powerpc/archrandom: fix arch_get_random_seed_int()
From: Ard Biesheuvel [ Upstream commit b6afd1234cf93aa0d71b4be4788c47534905f0be ] Commit 01c9348c7620ec65 powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* updated arch_get_random_[int|long]() to be NOPs, and moved the hardware RNG backing to arch_get_random_seed_[int|long]() instead. However, it failed to take into account that arch_get_random_int() was implemented in terms of arch_get_random_long(), and so we ended up with a version of the former that is essentially a NOP as well. Fix this by calling arch_get_random_seed_long() from arch_get_random_seed_int() instead. Fixes: 01c9348c7620ec65 ("powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*") Signed-off-by: Ard Biesheuvel Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191204115015.18015-1-a...@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/archrandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 9c63b596e6ce..a09595f00cab 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -28,7 +28,7 @@ static inline int arch_get_random_seed_int(unsigned int *v) unsigned long val; int rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; -- 2.20.1
[PATCH AUTOSEL 4.9 043/251] ASoC: imx-sgtl5000: put of nodes if finding codec fails
From: Stefan Agner [ Upstream commit d9866572486802bc598a3e8576a5231378d190de ] Make sure to properly put the of node in case finding the codec fails. Fixes: 81e8e4926167 ("ASoC: fsl: add sgtl5000 clock support for imx-sgtl5000") Signed-off-by: Stefan Agner Reviewed-by: Daniel Baluta Acked-by: Nicolin Chen Reviewed-by: Fabio Estevam Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/imx-sgtl5000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 8e525f7ac08d..3d99a8579c99 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -119,7 +119,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev) { dev_err(&pdev->dev, "failed to find codec platform device\n"); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto fail; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -- 2.20.1
[PATCH AUTOSEL 4.9 110/251] soc/fsl/qe: Fix an error code in qe_pin_request()
From: Dan Carpenter [ Upstream commit 5674a92ca4b7e5a6a19231edd10298d30324cd27 ] We forgot to set "err" on this error path. Fixes: 1a2d397a6eb5 ("gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()") Signed-off-by: Dan Carpenter Signed-off-by: Li Yang Signed-off-by: Sasha Levin --- drivers/soc/fsl/qe/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 0aaf429f31d5..b5a7107a9c0a 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -152,8 +152,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) if (err < 0) goto err0; gc = gpio_to_chip(err); - if (WARN_ON(!gc)) + if (WARN_ON(!gc)) { + err = -ENODEV; goto err0; + } if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { pr_debug("%s: tried to get a non-qe pin\n", __func__); -- 2.20.1
[PATCH AUTOSEL 4.9 117/251] powerpc: vdso: Make vdso32 installation conditional in vdso_install
From: Ben Hutchings [ Upstream commit ff6d27823f619892ab96f7461764840e0d786b15 ] The 32-bit vDSO is not needed and not normally built for 64-bit little-endian configurations. However, the vdso_install target still builds and installs it. Add the same config condition as is normally used for the build. Fixes: e0d005916994 ("powerpc/vdso: Disable building the 32-bit VDSO ...") Signed-off-by: Ben Hutchings Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index a60c9c6e5cc1..de29b88c0e70 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -373,7 +373,9 @@ vdso_install: ifeq ($(CONFIG_PPC64),y) $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ endif +ifdef CONFIG_VDSO32 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ +endif archclean: $(Q)$(MAKE) $(clean)=$(boot) -- 2.20.1
[PATCH AUTOSEL 4.9 152/251] powerpc/cacheinfo: add cacheinfo_teardown, cacheinfo_rebuild
From: Nathan Lynch [ Upstream commit d4aa219a074a5abaf95a756b9f0d190b5c03a945 ] Allow external callers to force the cacheinfo code to release all its references to cache nodes, e.g. before processing device tree updates post-migration, and to rebuild the hierarchy afterward. CPU online/offline must be blocked by callers; enforce this. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/cacheinfo.c | 21 + arch/powerpc/kernel/cacheinfo.h | 4 2 files changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index c641983bbdd6..0122d5ce0637 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -867,4 +867,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) if (cache) cache_cpu_clear(cache, cpu_id); } + +void cacheinfo_teardown(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_offline(cpu); +} + +void cacheinfo_rebuild(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_online(cpu); +} + #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index a7b74d36acd7..2cdee87a482c 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -5,4 +5,8 @@ extern void cacheinfo_cpu_online(unsigned int cpu_id); extern void cacheinfo_cpu_offline(unsigned int cpu_id); +/* Allow migration/suspend to tear down and rebuild the hierarchy. */ +extern void cacheinfo_teardown(void); +extern void cacheinfo_rebuild(void); + #endif /* _PPC_CACHEINFO_H */ -- 2.20.1
[PATCH AUTOSEL 4.9 159/251] perf/ioctl: Add check for the sample_period value
From: Ravi Bangoria [ Upstream commit 913a90bc5a3a06b1f04c337320e9aeee2328dd77 ] perf_event_open() limits the sample_period to 63 bits. See: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Make ioctl() consistent with it. Also on PowerPC, negative sample_period could cause a recursive PMIs leading to a hang (reported when running perf-fuzzer). Signed-off-by: Ravi Bangoria Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: a...@kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: ma...@linux.vnet.ibm.com Cc: m...@ellerman.id.au Fixes: 0819b2e30ccb ("perf: Limit perf_event_attr::sample_period to 63 bits") Link: https://lkml.kernel.org/r/20190604042953.914-1-ravi.bango...@linux.ibm.com Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/events/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index 5bbf7537a612..64ace5e9af2a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4624,6 +4624,9 @@ static int perf_event_period(struct perf_event *event, u64 __user *arg) if (perf_event_check_period(event, value)) return -EINVAL; + if (!event->attr.freq && (value & (1ULL << 63))) + return -EINVAL; + event_function_call(event, __perf_event_period, &value); return 0; -- 2.20.1
[PATCH AUTOSEL 4.9 174/251] ALSA: aoa: onyx: always initialize register read value
From: Johannes Berg [ Upstream commit f474808acb3c4b30552d9c59b181244e0300d218 ] A lot of places in the driver use onyx_read_register() without checking the return value, and it's been working OK for ~10 years or so, so probably never fails ... Rather than trying to check the return value everywhere, which would be relatively intrusive, at least make sure we don't use an uninitialized value. Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa") Reported-by: Stephen Rothwell Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/aoa/codecs/onyx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index a04edff8b729..ae50d59fb810 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -74,8 +74,10 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) return 0; } v = i2c_smbus_read_byte_data(onyx->i2c, reg); - if (v < 0) + if (v < 0) { + *value = 0; return -1; + } *value = (u8)v; onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value; return 0; -- 2.20.1
[PATCH AUTOSEL 4.9 246/251] powerpc/powernv: Disable native PCIe port management
From: Oliver O'Halloran [ Upstream commit 9d72dcef891030545f39ad386a30cf91df517fb2 ] On PowerNV the PCIe topology is (currently) managed by the powernv platform code in Linux in cooperation with the platform firmware. Linux's native PCIe port service drivers operate independently of both and this can cause problems. The main issue is that the portbus driver will conflict with the platform specific hotplug driver (pnv_php) over ownership of the MSI used to notify the host when a hotplug event occurs. The portbus driver claims this MSI on behalf of the individual port services because the same interrupt is used for hotplug events, PMEs (on root ports), and link bandwidth change notifications. The portbus driver will always claim the interrupt even if the individual port service drivers, such as pciehp, are compiled out. The second, bigger, problem is that the hotplug port service driver fundamentally does not work on PowerNV. The platform assumes that all PCI devices have a corresponding arch-specific handle derived from the DT node for the device (pci_dn) and without one the platform will not allow a PCI device to be enabled. This problem is largely due to historical baggage, but it can't be resolved without significant re-factoring of the platform PCI support. We can fix these problems in the interim by setting the "pcie_ports_disabled" flag during platform initialisation. The flag indicates the platform owns the PCIe ports which stops the portbus driver from being registered. This does have the side effect of disabling all port services drivers that is: AER, PME, BW notifications, hotplug, and DPC. However, this is not a huge disadvantage on PowerNV since these services are either unused or handled through other means. Fixes: 66725152fb9f ("PCI/hotplug: PowerPC PowerNV PCI hotplug driver") Signed-off-by: Oliver O'Halloran Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191118065553.30362-1-ooh...@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/pci.c | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 98cc8ba07c23..00dbf1e895a9 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -923,6 +923,23 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; +#ifdef CONFIG_PCIEPORTBUS + /* +* On PowerNV PCIe devices are (currently) managed in cooperation +* with firmware. This isn't *strictly* required, but there's enough +* assumptions baked into both firmware and the platform code that +* it's unwise to allow the portbus services to be used. +* +* We need to fix this eventually, but for now set this flag to disable +* the portbus driver. The AER service isn't required since that AER +* events are handled via EEH. The pciehp hotplug driver can't work +* without kernel changes (and portbus binding breaks pnv_php). The +* other services also require some thinking about how we're going +* to integrate them. +*/ + pcie_ports_disabled = true; +#endif + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); -- 2.20.1
[PATCH AUTOSEL 4.9 250/251] powerpc/archrandom: fix arch_get_random_seed_int()
From: Ard Biesheuvel [ Upstream commit b6afd1234cf93aa0d71b4be4788c47534905f0be ] Commit 01c9348c7620ec65 powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* updated arch_get_random_[int|long]() to be NOPs, and moved the hardware RNG backing to arch_get_random_seed_[int|long]() instead. However, it failed to take into account that arch_get_random_int() was implemented in terms of arch_get_random_long(), and so we ended up with a version of the former that is essentially a NOP as well. Fix this by calling arch_get_random_seed_long() from arch_get_random_seed_int() instead. Fixes: 01c9348c7620ec65 ("powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*") Signed-off-by: Ard Biesheuvel Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191204115015.18015-1-a...@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/archrandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 85e88f7a59c0..9ff848e3c4a6 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -27,7 +27,7 @@ static inline int arch_get_random_seed_int(unsigned int *v) unsigned long val; int rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; -- 2.20.1
Re: [PosibleSpam] Re: z constraint in powerpc inline assembly ?
On Thu, Jan 16, 2020 at 07:57:29AM -0600, Segher Boessenkool wrote: > On Thu, Jan 16, 2020 at 09:06:08AM +0100, Gabriel Paubert wrote: > > On Thu, Jan 16, 2020 at 07:11:36AM +0100, Christophe Leroy wrote: > > > Hi Segher, > > > > > > I'm trying to see if we could enhance TCP checksum calculations by > > > splitting > > > inline assembly blocks to give GCC the opportunity to mix it with other > > > stuff, but I'm getting difficulties with the carry. > > > > > > As far as I can read in the documentation, the z constraint represents > > > '‘XER[CA]’ carry bit (part of the XER register)' > > > > Well, the documentation is very optimisitic. From the GCC source code > > (thanks for switching to git last week-end ;-)), it is clear that the > > carry is not, for the time being, properly modeled. > > What? It certainly *is*, I spent ages on that back in 2014 and before. > See gcc.gnu.org/PR64180 etc. > > You can not put the carry as input or output to an asm, of course: no C > variable can be assigned to it. > > We don't do the "flag outputs" thing, either, as it is largely useless > for Power (and using it would often make *worse* code). > > If you want to access a carry, write C code that does that operation. > The compiler knows how to optimise it well. > > > Right now, in the machine description, all setters and users of the carry > > are in the same block of generated instructions. > > No, they are not. For over five years now. (Since GCC 5). > > > For a start, all single instructions patterns that set the carry (and > > do not use it) as a side effect should mention the they clobber the > > carry, otherwise inserting one between a setter and a user of the carry > > would break. > > And they do. > Apologies, I don't know how I could misread the .md files this badly. Indeed I see everything now that you mention it. I'm still a bit surprised that I have found zero "z" constraints in the whole gcc/config/rs6000 directory. Everything seems to be CA_REGNO. > All asms that change the carry should mention that, too, but this is > automatically done for all inline asms, because there was a lot of code > in the wild that does not clobber it. I was not aware of this, anyway I would always put as correct as possible clobbers for my inline assembly code. > > > This includes all arithmetic right shift (sra[wd]{,i}, > > subfic, addic{,\.} and I may have forgotten some. > > {add,subf}{ic,c,e,ze,me} and sra[wd][i] and their dots. Sure. And > mcrxr and mcrxrx and mfxer and mtxer. That's about it. Yes, but are last ones (the moves) are ever generated by the compiler? Looking at the source (again) it seems that even lswi has disappeared. > > We don't model the second carry at all yet btw, in GCC. Not too many > people know it exists even, so no big loss there. > Anyway, I couldn't use it. I tried to buy a Talos II at work but management made it too complex to negotiate. The problem was not the money, but the paperwork :-(. Now my most powerful PPC machine is a 17" Powerbook G4. > (One nasty was that addi. does not exist, so we used addic. where it was > wanted before, so that had to change.) > > > Segher Regards, Gabriel
[PATCH AUTOSEL 4.4 034/174] ASoC: imx-sgtl5000: put of nodes if finding codec fails
From: Stefan Agner [ Upstream commit d9866572486802bc598a3e8576a5231378d190de ] Make sure to properly put the of node in case finding the codec fails. Fixes: 81e8e4926167 ("ASoC: fsl: add sgtl5000 clock support for imx-sgtl5000") Signed-off-by: Stefan Agner Reviewed-by: Daniel Baluta Acked-by: Nicolin Chen Reviewed-by: Fabio Estevam Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/imx-sgtl5000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 8e525f7ac08d..3d99a8579c99 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -119,7 +119,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) codec_dev = of_find_i2c_device_by_node(codec_np); if (!codec_dev) { dev_err(&pdev->dev, "failed to find codec platform device\n"); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto fail; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -- 2.20.1
[PATCH AUTOSEL 4.4 070/174] soc/fsl/qe: Fix an error code in qe_pin_request()
From: Dan Carpenter [ Upstream commit 5674a92ca4b7e5a6a19231edd10298d30324cd27 ] We forgot to set "err" on this error path. Fixes: 1a2d397a6eb5 ("gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()") Signed-off-by: Dan Carpenter Signed-off-by: Li Yang Signed-off-by: Sasha Levin --- arch/powerpc/sysdev/qe_lib/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 521e67a49dc4..4052e3d7edbd 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -155,8 +155,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) if (err < 0) goto err0; gc = gpio_to_chip(err); - if (WARN_ON(!gc)) + if (WARN_ON(!gc)) { + err = -ENODEV; goto err0; + } if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) { pr_debug("%s: tried to get a non-qe pin\n", __func__); -- 2.20.1
[PATCH AUTOSEL 4.4 077/174] powerpc: vdso: Make vdso32 installation conditional in vdso_install
From: Ben Hutchings [ Upstream commit ff6d27823f619892ab96f7461764840e0d786b15 ] The 32-bit vDSO is not needed and not normally built for 64-bit little-endian configurations. However, the vdso_install target still builds and installs it. Add the same config condition as is normally used for the build. Fixes: e0d005916994 ("powerpc/vdso: Disable building the 32-bit VDSO ...") Signed-off-by: Ben Hutchings Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index d7eb035a9c96..65cb22541c66 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -350,7 +350,9 @@ vdso_install: ifeq ($(CONFIG_PPC64),y) $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@ endif +ifdef CONFIG_VDSO32 $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@ +endif archclean: $(Q)$(MAKE) $(clean)=$(boot) -- 2.20.1
Re: [linux-next/mainline][bisected 3acac06][ppc] Oops when unloading mpt3sas driver
Hi Abdul, I think the problem is that mpt3sas has some convoluted logic to do some DMA allocations with a 32-bit coherent mask, and then switches to a 63 or 64 bit mask, which is not supported by the DMA API. Can you try the patch below? --- >From 0738b1704ed528497b41b0408325f6828a8e51f6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 16 Jan 2020 18:31:38 +0100 Subject: mpt3sas: don't change the dma coherent mask after allocations The DMA layer does not allow changing the DMA coherent mask after there are outstanding allocations. Stop doing that and always use a 32-bit coherent DMA mask in mpt3sas. Signed-off-by: Christoph Hellwig --- drivers/scsi/mpt3sas/mpt3sas_base.c | 67 - drivers/scsi/mpt3sas/mpt3sas_base.h | 2 - 2 files changed, 19 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index fea3cb6a090b..3b51bed05008 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2706,58 +2706,38 @@ _base_build_sg_ieee(struct MPT3SAS_ADAPTER *ioc, void *psge, static int _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) { - u64 required_mask, coherent_mask; struct sysinfo s; - /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ - int dma_mask = (ioc->hba_mpi_version_belonged > MPI2_VERSION) ? 63 : 64; - - if (ioc->is_mcpu_endpoint) - goto try_32bit; + int dma_mask; - required_mask = dma_get_required_mask(&pdev->dev); - if (sizeof(dma_addr_t) == 4 || required_mask == 32) - goto try_32bit; - - if (ioc->dma_mask) - coherent_mask = DMA_BIT_MASK(dma_mask); + if (ioc->is_mcpu_endpoint || + sizeof(dma_addr_t) == 4 || + dma_get_required_mask(&pdev->dev) <= 32) + dma_mask = 32; + /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ + else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) + dma_mask = 63; else - coherent_mask = DMA_BIT_MASK(32); + dma_mask = 64; if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)) || - dma_set_coherent_mask(&pdev->dev, coherent_mask)) - goto try_32bit; - - ioc->base_add_sg_single = &_base_add_sg_single_64; - ioc->sge_size = sizeof(Mpi2SGESimple64_t); - ioc->dma_mask = dma_mask; - goto out; - - try_32bit: - if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) return -ENODEV; - ioc->base_add_sg_single = &_base_add_sg_single_32; - ioc->sge_size = sizeof(Mpi2SGESimple32_t); - ioc->dma_mask = 32; - out: + if (dma_mask > 32) { + ioc->base_add_sg_single = &_base_add_sg_single_64; + ioc->sge_size = sizeof(Mpi2SGESimple64_t); + } else { + ioc->base_add_sg_single = &_base_add_sg_single_32; + ioc->sge_size = sizeof(Mpi2SGESimple32_t); + } + si_meminfo(&s); ioc_info(ioc, "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", -ioc->dma_mask, convert_to_kb(s.totalram)); +dma_mask, convert_to_kb(s.totalram)); return 0; } -static int -_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc, - struct pci_dev *pdev) -{ - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(ioc->dma_mask))) { - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) - return -ENODEV; - } - return 0; -} - /** * _base_check_enable_msix - checks MSIX capabable. * @ioc: per adapter object @@ -5030,14 +5010,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) total_sz += sz; } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); - if (ioc->dma_mask > 32) { - if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { - ioc_warn(ioc, "no suitable consistent DMA mask for %s\n", -pci_name(ioc->pdev)); - goto out; - } - } - ioc->scsiio_depth = ioc->hba_queue_depth - ioc->hi_priority_depth - ioc->internal_depth; @@ -6965,7 +6937,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ioc->smp_affinity_enable = smp_affinity_enable; ioc->rdpq_array_enable_assigned = 0; - ioc->dma_mask = 0; if (ioc->is_aero_ioc) ioc->base_readl = &_base_readl_aero; else diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index faca0a5e71f8..e57cade1155c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1011,7 +1011,6 @@ ty
[PATCH AUTOSEL 4.4 100/174] powerpc/cacheinfo: add cacheinfo_teardown, cacheinfo_rebuild
From: Nathan Lynch [ Upstream commit d4aa219a074a5abaf95a756b9f0d190b5c03a945 ] Allow external callers to force the cacheinfo code to release all its references to cache nodes, e.g. before processing device tree updates post-migration, and to rebuild the hierarchy afterward. CPU online/offline must be blocked by callers; enforce this. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Signed-off-by: Sasha Levin --- arch/powerpc/kernel/cacheinfo.c | 21 + arch/powerpc/kernel/cacheinfo.h | 4 2 files changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index c641983bbdd6..0122d5ce0637 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -867,4 +867,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) if (cache) cache_cpu_clear(cache, cpu_id); } + +void cacheinfo_teardown(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_offline(cpu); +} + +void cacheinfo_rebuild(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_online(cpu); +} + #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index a7b74d36acd7..2cdee87a482c 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -5,4 +5,8 @@ extern void cacheinfo_cpu_online(unsigned int cpu_id); extern void cacheinfo_cpu_offline(unsigned int cpu_id); +/* Allow migration/suspend to tear down and rebuild the hierarchy. */ +extern void cacheinfo_teardown(void); +extern void cacheinfo_rebuild(void); + #endif /* _PPC_CACHEINFO_H */ -- 2.20.1
[PATCH AUTOSEL 4.4 115/174] ALSA: aoa: onyx: always initialize register read value
From: Johannes Berg [ Upstream commit f474808acb3c4b30552d9c59b181244e0300d218 ] A lot of places in the driver use onyx_read_register() without checking the return value, and it's been working OK for ~10 years or so, so probably never fails ... Rather than trying to check the return value everywhere, which would be relatively intrusive, at least make sure we don't use an uninitialized value. Fixes: f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa") Reported-by: Stephen Rothwell Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/aoa/codecs/onyx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index a04edff8b729..ae50d59fb810 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -74,8 +74,10 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value) return 0; } v = i2c_smbus_read_byte_data(onyx->i2c, reg); - if (v < 0) + if (v < 0) { + *value = 0; return -1; + } *value = (u8)v; onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value; return 0; -- 2.20.1
[PATCH AUTOSEL 4.4 174/174] powerpc/archrandom: fix arch_get_random_seed_int()
From: Ard Biesheuvel [ Upstream commit b6afd1234cf93aa0d71b4be4788c47534905f0be ] Commit 01c9348c7620ec65 powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_* updated arch_get_random_[int|long]() to be NOPs, and moved the hardware RNG backing to arch_get_random_seed_[int|long]() instead. However, it failed to take into account that arch_get_random_int() was implemented in terms of arch_get_random_long(), and so we ended up with a version of the former that is essentially a NOP as well. Fix this by calling arch_get_random_seed_long() from arch_get_random_seed_int() instead. Fixes: 01c9348c7620ec65 ("powerpc: Use hardware RNG for arch_get_random_seed_* not arch_get_random_*") Signed-off-by: Ard Biesheuvel Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191204115015.18015-1-a...@kernel.org Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/archrandom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 85e88f7a59c0..9ff848e3c4a6 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -27,7 +27,7 @@ static inline int arch_get_random_seed_int(unsigned int *v) unsigned long val; int rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; -- 2.20.1
[RFC PATCH v4 00/11] powerpc: switch VDSO to C implementation.
This is a fourth tentative to switch powerpc VDSO to generic C implementation. This version should work on PPC64 (untested). VDSO32 for PPC64 is impossible to build and has been de-activated, because the powerpc ASM header files for C are not prepared to build 32 bits code with CONFIG_PPC64. powerpc is a bit special for VDSO as well as system calls in the way that it requires setting CR SO bit which cannot be done in C. Therefore, entry/exit and fallback need to be performed in ASM. Note that on previous patches, a buggy version of vdsotest was used which was underestimating the time in gettimeofday compared to clock-get... functions. This series applies on a merge of powerpc/merge and tip/timers/core branches, series "lib/vdso: Bugfix and consolidation" (https://lore.kernel.org/patchwork/project/lkml/list/?series=425784) applied after the above merge. On a powerpc8xx, with current powerpc/32 ASM VDSO: gettimeofday:vdso: 907 nsec/call clock-getres-realtime:vdso: 484 nsec/call clock-gettime-realtime:vdso: 899 nsec/call The first patch adds VDSO generic C support without any changes to common code. Performance is as follows: gettimeofday:vdso: 1211 nsec/call clock-getres-realtime:vdso: 722 nsec/call clock-gettime-realtime:vdso: 1216 nsec/call Then a few changes in the common code have allowed performance improvement. At the end of the series we have: gettimeofday:vdso: 974 nsec/call clock-getres-realtime:vdso: 545 nsec/call clock-gettime-realtime:vdso: 941 nsec/call The final result is rather close to pure ASM VDSO: * 7% more on gettimeofday (9 cycles) * 5% more on clock-gettime-realtime (6 cycles) * 12% more on clock-getres-realtime (8 cycles) Due to the unavoidable ASM trampoline, we won't get much closer but that should be acceptable for a port from ASM to a generic C code (here, 1 cycle is about 7,5 ns) Christophe Leroy (11): powerpc/64: Don't provide time functions in compat VDSO32 powerpc/vdso: Switch VDSO to generic C implementation. lib: vdso: only read hrtimer_res when needed in __cvdso_clock_getres() powerpc/vdso: simplify __get_datapage() lib: vdso: allow arches to provide vdso data pointer powerpc/vdso: provide inline alternative to __get_datapage() powerpc/vdso: provide vdso data pointer from the ASM caller. lib: vdso: allow fixed clock mode powerpc/vdso: override __arch_vdso_capable() lib: vdso: Allow arches to override the ns shift operation powerpc/32: provide vdso_shift_ns() arch/powerpc/Kconfig | 2 + arch/powerpc/include/asm/clocksource.h | 6 + arch/powerpc/include/asm/vdso/gettimeofday.h | 117 arch/powerpc/include/asm/vdso/vsyscall.h | 25 +++ arch/powerpc/include/asm/vdso_datapage.h | 52 +++--- arch/powerpc/kernel/asm-offsets.c| 46 + arch/powerpc/kernel/time.c | 91 +- arch/powerpc/kernel/vdso.c | 58 ++ arch/powerpc/kernel/vdso32/Makefile | 27 ++- arch/powerpc/kernel/vdso32/datapage.S| 10 +- arch/powerpc/kernel/vdso32/gettimeofday.S| 258 --- arch/powerpc/kernel/vdso32/vdso32.lds.S | 9 +- arch/powerpc/kernel/vdso32/vgettimeofday.c | 29 +++ arch/powerpc/kernel/vdso64/Makefile | 23 ++- arch/powerpc/kernel/vdso64/datapage.S| 13 +- arch/powerpc/kernel/vdso64/gettimeofday.S| 257 -- arch/powerpc/kernel/vdso64/vdso64.lds.S | 7 +- arch/powerpc/kernel/vdso64/vgettimeofday.c | 29 +++ lib/vdso/gettimeofday.c | 107 --- 19 files changed, 457 insertions(+), 709 deletions(-) create mode 100644 arch/powerpc/include/asm/clocksource.h create mode 100644 arch/powerpc/include/asm/vdso/gettimeofday.h create mode 100644 arch/powerpc/include/asm/vdso/vsyscall.h create mode 100644 arch/powerpc/kernel/vdso32/vgettimeofday.c create mode 100644 arch/powerpc/kernel/vdso64/vgettimeofday.c -- 2.13.3
[RFC PATCH v4 01/11] powerpc/64: Don't provide time functions in compat VDSO32
In order to allow use of generic C VDSO, remove time functions from the 32 bits VDSO on PPC64. This (temporary) removal is needed because powerpc kernel C headers are not prepared for building 32 bits code on PPC64. Signed-off-by: Christophe Leroy --- arch/powerpc/kernel/vdso32/Makefile | 3 ++- arch/powerpc/kernel/vdso32/vdso32.lds.S | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 06f54d947057..738d52105392 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -3,7 +3,8 @@ # List of files in the vdso, has to be asm only for now obj-vdso32-$(CONFIG_PPC64) = getcpu.o -obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o \ +obj-vdso32-$(CONFIG_PPC32) = gettimeofday.o +obj-vdso32 = sigtramp.o datapage.o cacheflush.o note.o \ $(obj-vdso32-y) # Build rules diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 00c025ba4a92..9400b182e163 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -144,7 +144,7 @@ VERSION __kernel_datapage_offset; __kernel_get_syscall_map; -#ifndef CONFIG_PPC_BOOK3S_601 +#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_BOOK3S_601) __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; -- 2.13.3
[RFC PATCH v4 02/11] powerpc/vdso: Switch VDSO to generic C implementation.
This is a minimalistic conversion to VDSO generic C implementation. On powerpc 8xx, performance is degraded by 40-45% for gettime and by 50% for getres. Optimisations will follow in next patches, some in the core VDSO functions, some in the powerpc arch. powerpc is a bit special for VDSO as well as system calls in the way that it requires setting CR SO bit which cannot be done in C. Therefore, entry/exit needs to be performed in ASM. On a powerpc885 at 132MHz: With current powerpc/32 ASM VDSO: gettimeofday:vdso: 907 nsec/call clock-getres-realtime-coarse:vdso: 3053 nsec/call clock-gettime-realtime-coarse:vdso: 2823 nsec/call clock-getres-realtime:vdso: 484 nsec/call clock-gettime-realtime:vdso: 899 nsec/call clock-getres-boottime:vdso: 2586 nsec/call clock-gettime-boottime:vdso: 3820 nsec/call clock-getres-tai:vdso: 2587 nsec/call clock-gettime-tai:vdso: 3819 nsec/call clock-getres-monotonic-raw:vdso: 2587 nsec/call clock-gettime-monotonic-raw:vdso: 3378 nsec/call clock-getres-monotonic-coarse:vdso: 3054 nsec/call clock-gettime-monotonic-coarse:vdso: 3376 nsec/call clock-getres-monotonic:vdso: 484 nsec/call clock-gettime-monotonic:vdso: 1026 nsec/call Once switched to C implementation: gettimeofday:vdso: 1211 nsec/call clock-getres-realtime-coarse:vdso: 722 nsec/call clock-gettime-realtime-coarse:vdso: 784 nsec/call clock-getres-realtime:vdso: 722 nsec/call clock-gettime-realtime:vdso: 1216 nsec/call clock-getres-boottime:vdso: 722 nsec/call clock-gettime-boottime:vdso: 1216 nsec/call clock-getres-tai:vdso: 722 nsec/call clock-gettime-tai:vdso: 1216 nsec/call clock-getres-monotonic-raw:vdso: 722 nsec/call clock-gettime-monotonic-raw:vdso: 1277 nsec/call clock-getres-monotonic-coarse:vdso: 722 nsec/call clock-gettime-monotonic-coarse:vdso: 783 nsec/call clock-getres-monotonic:vdso: 722 nsec/call clock-gettime-monotonic:vdso: 1217 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/Kconfig | 2 + arch/powerpc/include/asm/clocksource.h | 6 + arch/powerpc/include/asm/vdso/gettimeofday.h | 102 +++ arch/powerpc/include/asm/vdso/vsyscall.h | 25 +++ arch/powerpc/include/asm/vdso_datapage.h | 41 ++--- arch/powerpc/kernel/asm-offsets.c| 46 + arch/powerpc/kernel/time.c | 91 +- arch/powerpc/kernel/vdso.c | 5 +- arch/powerpc/kernel/vdso32/Makefile | 24 +++ arch/powerpc/kernel/vdso32/gettimeofday.S| 255 +++ arch/powerpc/kernel/vdso32/vgettimeofday.c | 26 +++ arch/powerpc/kernel/vdso64/Makefile | 23 ++- arch/powerpc/kernel/vdso64/datapage.S| 3 +- arch/powerpc/kernel/vdso64/gettimeofday.S| 254 +++--- arch/powerpc/kernel/vdso64/vgettimeofday.c | 26 +++ 15 files changed, 312 insertions(+), 617 deletions(-) create mode 100644 arch/powerpc/include/asm/clocksource.h create mode 100644 arch/powerpc/include/asm/vdso/gettimeofday.h create mode 100644 arch/powerpc/include/asm/vdso/vsyscall.h create mode 100644 arch/powerpc/kernel/vdso32/vgettimeofday.c create mode 100644 arch/powerpc/kernel/vdso64/vgettimeofday.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 1ec34e16ed65..bd04c68baf91 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -169,6 +169,7 @@ config PPC select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL + select GENERIC_GETTIMEOFDAY select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU select HAVE_ARCH_JUMP_LABEL @@ -198,6 +199,7 @@ config PPC select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS if GCC_VERSION >= 50200 # plugin support on gcc <= 5.1 is buggy on PPC + select HAVE_GENERIC_VDSO select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) select HAVE_IDE select HAVE_IOREMAP_PROT diff --git a/arch/powerpc/include/asm/clocksource.h b/arch/powerpc/include/asm/clocksource.h new file mode 100644 index ..37423d17af30 --- /dev/null +++ b/arch/powerpc/include/asm/clocksource.h @@ -0,0 +1,6 @@ +#ifndef _ASM_POWERPC_CLOCKSOURCE_H +#define _ASM_POWERPC_CLOCKSOURCE_H + +#define VDSO_ARCH_CLOCKMODES VDSO_CLOCKMODE_ARCHTIMER + +#endif diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h new file mode 100644 index ..c2cafd85d3cb --- /dev/null +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_VDSO_GETTIMEOFDAY_H +#define __ASM_VDSO_GETTIMEOFDAY_H + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include + +#defin
[RFC PATCH v4 03/11] lib: vdso: only read hrtimer_res when needed in __cvdso_clock_getres()
Only perform READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res) for HRES and RAW clocks. Signed-off-by: Christophe Leroy --- lib/vdso/gettimeofday.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c index 9563be3cb5fa..8b3084d9a3ec 100644 --- a/lib/vdso/gettimeofday.c +++ b/lib/vdso/gettimeofday.c @@ -326,7 +326,6 @@ static __maybe_unused int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) { const struct vdso_data *vd = __arch_get_vdso_data(); - u64 hrtimer_res; u32 msk; u64 ns; @@ -338,7 +337,6 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) vd->clock_mode == VDSO_CLOCKMODE_TIMENS) vd = __arch_get_timens_vdso_data(); - hrtimer_res = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res); /* * Convert the clockid to a bitmask and use it to check which * clocks are handled in the VDSO directly. @@ -348,7 +346,7 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) /* * Preserves the behaviour of posix_get_hrtimer_res(). */ - ns = hrtimer_res; + ns = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res); } else if (msk & VDSO_COARSE) { /* * Preserves the behaviour of posix_get_coarse_res(). -- 2.13.3
[RFC PATCH v4 04/11] powerpc/vdso: simplify __get_datapage()
The VDSO datapage and the text pages are always located immediately next to each other, so it can be hardcoded without an indirection through __kernel_datapage_offset In order to ease things, move the data page in front like other arches, that way there is no need to know the size of the library to locate the data page. Before: clock-getres-realtime-coarse:vdso: 714 nsec/call clock-gettime-realtime-coarse:vdso: 792 nsec/call clock-gettime-realtime:vdso: 1243 nsec/call After: clock-getres-realtime-coarse:vdso: 699 nsec/call clock-gettime-realtime-coarse:vdso: 784 nsec/call clock-gettime-realtime:vdso: 1231 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/kernel/vdso.c | 53 + arch/powerpc/kernel/vdso32/datapage.S | 10 +++ arch/powerpc/kernel/vdso32/vdso32.lds.S | 7 ++--- arch/powerpc/kernel/vdso64/datapage.S | 10 +++ arch/powerpc/kernel/vdso64/vdso64.lds.S | 7 ++--- 5 files changed, 19 insertions(+), 68 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 16a44bffe698..c093d90a222a 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -191,7 +191,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * install_special_mapping or the perf counter mmap tracking code * will fail to recognise it as a vDSO (since arch_vma_name fails). */ - current->mm->context.vdso_base = vdso_base; + current->mm->context.vdso_base = vdso_base + PAGE_SIZE; /* * our vma flags don't have VM_WRITE so by default, the process isn't @@ -488,42 +488,6 @@ static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32, vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32"); } -static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64) -{ -#ifdef CONFIG_VDSO32 - Elf32_Sym *sym32; -#endif -#ifdef CONFIG_PPC64 - Elf64_Sym *sym64; - - sym64 = find_symbol64(v64, "__kernel_datapage_offset"); - if (sym64 == NULL) { - printk(KERN_ERR "vDSO64: Can't find symbol " - "__kernel_datapage_offset !\n"); - return -1; - } - *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) = - (vdso64_pages << PAGE_SHIFT) - - (sym64->st_value - VDSO64_LBASE); -#endif /* CONFIG_PPC64 */ - -#ifdef CONFIG_VDSO32 - sym32 = find_symbol32(v32, "__kernel_datapage_offset"); - if (sym32 == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol " - "__kernel_datapage_offset !\n"); - return -1; - } - *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) = - (vdso32_pages << PAGE_SHIFT) - - (sym32->st_value - VDSO32_LBASE); -#endif - - return 0; -} - - static __init int vdso_fixup_features(struct lib32_elfinfo *v32, struct lib64_elfinfo *v64) { @@ -624,9 +588,6 @@ static __init int vdso_setup(void) if (vdso_do_find_sections(&v32, &v64)) return -1; - if (vdso_fixup_datapage(&v32, &v64)) - return -1; - if (vdso_fixup_features(&v32, &v64)) return -1; @@ -771,26 +732,26 @@ static int __init vdso_init(void) vdso32_pagelist = kcalloc(vdso32_pages + 2, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso32_pagelist == NULL); + vdso32_pagelist[0] = virt_to_page(vdso_data); for (i = 0; i < vdso32_pages; i++) { struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); get_page(pg); - vdso32_pagelist[i] = pg; + vdso32_pagelist[i + 1] = pg; } - vdso32_pagelist[i++] = virt_to_page(vdso_data); - vdso32_pagelist[i] = NULL; + vdso32_pagelist[i + 1] = NULL; #endif #ifdef CONFIG_PPC64 vdso64_pagelist = kcalloc(vdso64_pages + 2, sizeof(struct page *), GFP_KERNEL); BUG_ON(vdso64_pagelist == NULL); + vdso64_pagelist[0] = virt_to_page(vdso_data); for (i = 0; i < vdso64_pages; i++) { struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); get_page(pg); - vdso64_pagelist[i] = pg; + vdso64_pagelist[i + 1] = pg; } - vdso64_pagelist[i++] = virt_to_page(vdso_data); - vdso64_pagelist[i] = NULL; + vdso64_pagelist[i + 1] = NULL; #endif /* CONFIG_PPC64 */ get_page(virt_to_page(vdso_data)); diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S index 6c7401bd284e..d839aa1a4f01 100644 --- a/arch/powerpc/kernel/vdso32/datapage.S +++ b/arch/powerpc/kernel/vdso32/datapage.S @@ -12,9 +12,
[RFC PATCH v4 05/11] lib: vdso: allow arches to provide vdso data pointer
On powerpc, __arch_get_vdso_data() clobbers the link register, requiring the caller to save it. As the parent function already has to set a stack frame and saves the link register before calling the C vdso function, retriving the vdso data pointer there is lighter. Give arches the opportunity to hand the vdso data pointer to C vdso functions. Signed-off-by: Christophe Leroy --- lib/vdso/gettimeofday.c | 83 +++-- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c index 8b3084d9a3ec..9fa249809399 100644 --- a/lib/vdso/gettimeofday.c +++ b/lib/vdso/gettimeofday.c @@ -219,9 +219,9 @@ static __always_inline int do_coarse(const struct vdso_data *vd, clockid_t clk, } static __maybe_unused int -__cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts) +__cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock, +struct __kernel_timespec *ts) { - const struct vdso_data *vd = __arch_get_vdso_data(); u32 msk; /* Check for negative values or invalid clocks */ @@ -246,23 +246,33 @@ __cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts) } static __maybe_unused int -__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) +__cvdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock, + struct __kernel_timespec *ts) { - int ret = __cvdso_clock_gettime_common(clock, ts); + int ret = __cvdso_clock_gettime_common(vd, clock, ts); if (unlikely(ret)) return clock_gettime_fallback(clock, ts); return 0; } +static __maybe_unused int +__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) +{ + const struct vdso_data *vd = __arch_get_vdso_data(); + + return __cvdso_clock_gettime_data(vd, clock, ts); +} + #ifdef BUILD_VDSO32 static __maybe_unused int -__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res) +__cvdso_clock_gettime32_data(const struct vdso_data *vd, clockid_t clock, +struct old_timespec32 *res) { struct __kernel_timespec ts; int ret; - ret = __cvdso_clock_gettime_common(clock, &ts); + ret = __cvdso_clock_gettime_common(vd, clock, &ts); if (unlikely(ret)) return clock_gettime32_fallback(clock, res); @@ -273,13 +283,21 @@ __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res) return ret; } -#endif /* BUILD_VDSO32 */ static __maybe_unused int -__cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) +__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res) { const struct vdso_data *vd = __arch_get_vdso_data(); + return __cvdso_clock_gettime32_data(vd, clock, res); +} +#endif /* BUILD_VDSO32 */ + +static __maybe_unused int +__cvdso_gettimeofday_data(const struct vdso_data *vd, + struct __kernel_old_timeval *tv, struct timezone *tz) +{ + if (likely(tv != NULL)) { struct __kernel_timespec ts; @@ -302,10 +320,18 @@ __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) return 0; } -#ifdef VDSO_HAS_TIME -static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time) +static __maybe_unused int +__cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) { const struct vdso_data *vd = __arch_get_vdso_data(); + + return __cvdso_gettimeofday_data(vd, tv, tz); +} + +#ifdef VDSO_HAS_TIME +static __maybe_unused __kernel_old_time_t +__cvdso_time_data(const struct vdso_data *vd, __kernel_old_time_t *time) +{ __kernel_old_time_t t; if (IS_ENABLED(CONFIG_TIME_NS) && @@ -319,13 +345,20 @@ static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time return t; } + +static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time) +{ + const struct vdso_data *vd = __arch_get_vdso_data(); + + return __cvdso_time_data(vd, time); +} #endif /* VDSO_HAS_TIME */ #ifdef VDSO_HAS_CLOCK_GETRES static __maybe_unused -int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) +int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock, + struct __kernel_timespec *res) { - const struct vdso_data *vd = __arch_get_vdso_data(); u32 msk; u64 ns; @@ -364,23 +397,33 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) } static __maybe_unused -int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res) +int __cvdso_clock_getres_data(const struct vdso_data *vd, clockid_t clock, + struct __kernel_timespec *res) { - int ret = __cvdso_clock_getres_common(clock, r
[RFC PATCH v4 06/11] powerpc/vdso: provide inline alternative to __get_datapage()
__get_datapage() is only a few instructions to retrieve the address of the page where the kernel stores data to the VDSO. By inlining this function into its users, a bl/blr pair and a mflr/mtlr pair is avoided, plus a few reg moves. The improvement is noticeable (about 55 nsec/call on an 8xx) With current __get_datapage() function: gettimeofday:vdso: 731 nsec/call clock-gettime-realtime-coarse:vdso: 668 nsec/call clock-gettime-monotonic-coarse:vdso: 745 nsec/call Using the __get_datapage macro provided by this patch: gettimeofday:vdso: 677 nsec/call clock-gettime-realtime-coarse:vdso: 613 nsec/call clock-gettime-monotonic-coarse:vdso: 690 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/vdso_datapage.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 4d7965bf369e..7342cc0c1ae4 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -105,6 +105,17 @@ struct vdso_arch_data { extern struct vdso_arch_data *vdso_data; +#else /* __ASSEMBLY__ */ + +.macro get_datapage ptr, offset=0 + bcl 20, 31, .+4 + mflr\ptr +#if CONFIG_PPC_PAGE_SHIFT > 14 + addis \ptr, \ptr, (_vdso_datapage + \offset - (.-4))@ha +#endif + addi\ptr, \ptr, (_vdso_datapage + \offset - (.-4))@l +.endm + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -- 2.13.3
[RFC PATCH v4 07/11] powerpc/vdso: provide vdso data pointer from the ASM caller.
__arch_get_vdso_data() clobbers the link register, requiring the caller to save it. As the ASM calling function already has to set a stack frame and saves the link register before calling the C vdso function, retriving the vdso data pointer there is lighter. The improvement is significant: Before: gettimeofday:vdso: 1212 nsec/call clock-getres-realtime-coarse:vdso: 714 nsec/call clock-gettime-realtime-coarse:vdso: 784 nsec/call clock-getres-realtime:vdso: 714 nsec/call After: gettimeofday:vdso: 1094 nsec/call getcpu:vdso: not tested clock-getres-realtime-coarse:vdso: 545 nsec/call clock-gettime-realtime-coarse:vdso: 584 nsec/call clock-getres-realtime:vdso: 545 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/vdso/gettimeofday.h | 10 +- arch/powerpc/kernel/vdso32/gettimeofday.S| 3 +++ arch/powerpc/kernel/vdso32/vgettimeofday.c | 19 +++ arch/powerpc/kernel/vdso64/gettimeofday.S| 3 +++ arch/powerpc/kernel/vdso64/vgettimeofday.c | 19 +++ 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h index c2cafd85d3cb..0a247f9b9af9 100644 --- a/arch/powerpc/include/asm/vdso/gettimeofday.h +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h @@ -6,7 +6,6 @@ #include #include -#include #include #define VDSO_HAS_CLOCK_GETRES 1 @@ -73,14 +72,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) return get_tb(); } -void *__get_datapage(void); - -static __always_inline const struct vdso_data *__arch_get_vdso_data(void) -{ - struct vdso_arch_data *vdso_data = __get_datapage(); - - return vdso_data->data; -} +const struct vdso_data *__arch_get_vdso_data(void); /* * powerpc specific delta calculation. diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index ba0bd64b3da3..0d43878e462c 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,7 @@ stwur1, -16(r1) mflrr0 stw r0, 20(r1) + get_datapager5, VDSO_DATA_OFFSET bl \funct lwz r0, 20(r1) cmpwi r3, 0 @@ -79,6 +81,7 @@ V_FUNCTION_BEGIN(__kernel_time) stwur1, -16(r1) mflrr0 stw r0, 20(r1) + get_datapager4, VDSO_DATA_OFFSET bl __c_kernel_time lwz r0, 20(r1) crclr cr0*4+so diff --git a/arch/powerpc/kernel/vdso32/vgettimeofday.c b/arch/powerpc/kernel/vdso32/vgettimeofday.c index 4ed1bf2ae30e..9bdc3c435846 100644 --- a/arch/powerpc/kernel/vdso32/vgettimeofday.c +++ b/arch/powerpc/kernel/vdso32/vgettimeofday.c @@ -5,22 +5,25 @@ #include #include -int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts) +int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts, +const struct vdso_data *vd) { - return __cvdso_clock_gettime32(clock, ts); + return __cvdso_clock_gettime32_data(vd, clock, ts); } -int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) +int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz, + const struct vdso_data *vd) { - return __cvdso_gettimeofday(tv, tz); + return __cvdso_gettimeofday_data(vd, tv, tz); } -int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res) +int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res, + const struct vdso_data *vd) { - return __cvdso_clock_getres_time32(clock_id, res); + return __cvdso_clock_getres_time32_data(vd, clock_id, res); } -time_t __c_kernel_time(time_t *time) +time_t __c_kernel_time(time_t *time, const struct vdso_data *vd) { - return __cvdso_time(time); + return __cvdso_time_data(vd, time); } diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 22f4f1f73bbc..f61c53eb6600 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,7 @@ mflrr0 std r0, 16(r1) stdur1, -128(r1) + get_datapager5, VDSO_DATA_OFFSET bl \funct addir1, r1, 128 ld r0, 16(r1) @@ -79,6 +81,7 @@ V_FUNCTION_BEGIN(__kernel_time) mflrr0 std r0, 16(r1) stdur1, -128(r1) + get_datapager4, VDSO_DATA_OFFSET bl __c_kernel_time addir1, r1, 128 ld r0, 16(r1) diff --git a/arch/powerpc/kernel/vdso64/vgettimeofday
[RFC PATCH v4 08/11] lib: vdso: allow fixed clock mode
On arches like POWERPC, the clock is always the timebase, it cannot be changed on the fly and it is always VDSO capable. Therefore, give arches the opportunity to redefine the way clock_mode is checked by moving the check into an overridable __arch_vdso_capable() macro. Signed-off-by: Christophe Leroy --- lib/vdso/gettimeofday.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c index 9fa249809399..724b45c3e8ac 100644 --- a/lib/vdso/gettimeofday.c +++ b/lib/vdso/gettimeofday.c @@ -46,6 +46,13 @@ static inline bool __arch_vdso_hres_capable(void) } #endif +#ifndef __arch_vdso_capable +static inline bool __arch_vdso_capable(const struct vdso_data *vd) +{ + return vd->clock_mode != VDSO_CLOCKMODE_NONE; +} +#endif + #ifdef CONFIG_TIME_NS static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk, struct __kernel_timespec *ts) @@ -66,7 +73,7 @@ static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk, do { seq = vdso_read_begin(vd); - if (unlikely(vd->clock_mode == VDSO_CLOCKMODE_NONE)) + if (unlikely(!__arch_vdso_capable(vd))) return -1; cycles = __arch_get_hw_counter(vd->clock_mode); @@ -134,7 +141,7 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk, } smp_rmb(); - if (unlikely(vd->clock_mode == VDSO_CLOCKMODE_NONE)) + if (unlikely(!__arch_vdso_capable(vd))) return -1; cycles = __arch_get_hw_counter(vd->clock_mode); -- 2.13.3
[RFC PATCH v4 09/11] powerpc/vdso: override __arch_vdso_capable()
When the timebase is used, make __arch_vdso_capable() always return true. When the RTC clock is used, make __arch_vdso_capable() always return false. Before the patch: clock-gettime-realtime:vdso: 1086 nsec/call After the patch: clock-gettime-realtime:vdso: 1033 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/vdso/gettimeofday.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h index 0a247f9b9af9..74b6eef8fbe9 100644 --- a/arch/powerpc/include/asm/vdso/gettimeofday.h +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h @@ -74,6 +74,12 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) const struct vdso_data *__arch_get_vdso_data(void); +static inline bool __arch_vdso_capable(const struct vdso_data *vd) +{ + return !__USE_RTC(); +} +#define __arch_vdso_capable __arch_vdso_capable + /* * powerpc specific delta calculation. * -- 2.13.3
[RFC PATCH v4 10/11] lib: vdso: Allow arches to override the ns shift operation
On powerpc/32, GCC (8.1) generates pretty bad code for the ns >>= vd->shift operation taking into account that the shift is always < 32 and the upper part of the result is likely to be nul. GCC makes reversed assumptions considering the shift to be likely >= 32 and the upper part to be like not nul. unsigned long long shift(unsigned long long x, unsigned char s) { return x >> s; } results in: 0018 : 18: 35 25 ff e0 addic. r9,r5,-32 1c: 41 80 00 10 blt 2c 20: 7c 64 4c 30 srw r4,r3,r9 24: 38 60 00 00 li r3,0 28: 4e 80 00 20 blr 2c: 54 69 08 3c rlwinm r9,r3,1,0,30 30: 21 45 00 1f subfic r10,r5,31 34: 7c 84 2c 30 srw r4,r4,r5 38: 7d 29 50 30 slw r9,r9,r10 3c: 7c 63 2c 30 srw r3,r3,r5 40: 7d 24 23 78 or r4,r9,r4 44: 4e 80 00 20 blr Even when forcing the shift with an &= 31, it still considers the shift as likely >= 32. Define a vdso_shift_ns() macro that can be overriden by arches. Signed-off-by: Christophe Leroy --- lib/vdso/gettimeofday.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c index 724b45c3e8ac..9ba92058cfd7 100644 --- a/lib/vdso/gettimeofday.c +++ b/lib/vdso/gettimeofday.c @@ -39,6 +39,13 @@ u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult) } #endif +#ifndef vdso_shift_ns +static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift) +{ + return ns >> shift; +} +#endif + #ifndef __arch_vdso_hres_capable static inline bool __arch_vdso_hres_capable(void) { @@ -148,7 +155,7 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk, ns = vdso_ts->nsec; last = vd->cycle_last; ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult); - ns >>= vd->shift; + ns = vdso_shift_ns(ns, vd->shift); sec = vdso_ts->sec; } while (unlikely(vdso_read_retry(vd, seq))); -- 2.13.3
[RFC PATCH v4 11/11] powerpc/32: provide vdso_shift_ns()
The generic x >> s gives the following result: 18: 35 25 ff e0 addic. r9,r5,-32 1c: 41 80 00 10 blt 2c 20: 7c 64 4c 30 srw r4,r3,r9 24: 38 60 00 00 li r3,0 ... 2c: 54 69 08 3c rlwinm r9,r3,1,0,30 30: 21 45 00 1f subfic r10,r5,31 34: 7c 84 2c 30 srw r4,r4,r5 38: 7d 29 50 30 slw r9,r9,r10 3c: 7c 63 2c 30 srw r3,r3,r5 40: 7d 24 23 78 or r4,r9,r4 In our case the shift is always < 32. In addition, the upper 32 bits of the result are likely nul. Lets GCC know it, it also optimises the following calculations. With the patch, we get: 0: 21 25 00 20 subfic r9,r5,32 4: 7c 69 48 30 slw r9,r3,r9 8: 7c 84 2c 30 srw r4,r4,r5 c: 7d 24 23 78 or r4,r9,r4 10: 7c 63 2c 30 srw r3,r3,r5 Performance before the patch: clock-gettime-realtime:vdso: 1033 nsec/call After the patch: clock-gettime-realtime:vdso: 941 nsec/call Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/vdso/gettimeofday.h | 17 + 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h index 74b6eef8fbe9..716a137ab166 100644 --- a/arch/powerpc/include/asm/vdso/gettimeofday.h +++ b/arch/powerpc/include/asm/vdso/gettimeofday.h @@ -95,6 +95,23 @@ static __always_inline u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 m } #define vdso_calc_delta vdso_calc_delta +#ifndef __powerpc64__ +static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift) +{ + u32 hi = ns >> 32; + u32 lo = ns; + + lo = (lo >> shift) | (hi << (32 - shift)); + hi >>= shift; + + if (likely(hi == 0)) + return lo; + + return ((u64)hi << 32) | lo; +} +#define vdso_shift_ns vdso_shift_ns +#endif + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ -- 2.13.3
Re: [PATCH vdsotest] Use vdso wrapper for gettimeofday()
Le 16/01/2020 à 17:56, Nathan Lynch a écrit : Hi Christophe, Christophe Leroy writes: To properly handle errors returned by gettimeofday(), the DO_VDSO_CALL() macro has to be used, otherwise vdsotest misinterpret VDSO function return on error. This has gone unnoticed until now because the powerpc VDSO gettimeofday() always succeed, but while porting powerpc to generic C VDSO, the following has been encountered: Thanks for this, I'll review it soon. Can you point me to patches for the powerpc generic vdso work? Sure. v3 is at https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=152867 I added you in v4 destinees. Christophe
Re: [RFC PATCH v4 10/11] lib: vdso: Allow arches to override the ns shift operation
On Thu, Jan 16, 2020 at 9:58 AM Christophe Leroy wrote: > > On powerpc/32, GCC (8.1) generates pretty bad code for the > ns >>= vd->shift operation taking into account that the > shift is always < 32 and the upper part of the result is > likely to be nul. GCC makes reversed assumptions considering > the shift to be likely >= 32 and the upper part to be like not nul. > > unsigned long long shift(unsigned long long x, unsigned char s) > { > return x >> s; > } > > results in: > > 0018 : > 18: 35 25 ff e0 addic. r9,r5,-32 > 1c: 41 80 00 10 blt 2c > 20: 7c 64 4c 30 srw r4,r3,r9 > 24: 38 60 00 00 li r3,0 > 28: 4e 80 00 20 blr > 2c: 54 69 08 3c rlwinm r9,r3,1,0,30 > 30: 21 45 00 1f subfic r10,r5,31 > 34: 7c 84 2c 30 srw r4,r4,r5 > 38: 7d 29 50 30 slw r9,r9,r10 > 3c: 7c 63 2c 30 srw r3,r3,r5 > 40: 7d 24 23 78 or r4,r9,r4 > 44: 4e 80 00 20 blr > > Even when forcing the shift with an &= 31, it still considers > the shift as likely >= 32. > > Define a vdso_shift_ns() macro that can be overriden by > arches. Would mul_u64_u64_shr() be a good alternative? Could we adjust it to assume the shift is less than 32? That function exists to benefit 32-bit arches. --Andy
Re: [PATCH] powerpc: Do not consider weak unresolved symbol relocations as bad
Hi Stephen, On 1/15/20 6:39 PM, Stephen Rothwell wrote: Hi Alexandre, Thanks for sorting this out. Just a few comments below. On Wed, 15 Jan 2020 15:46:48 -0500 Alexandre Ghiti wrote: # Have Kbuild supply the path to objdump so we handle cross compilation. ^ "and nm" +# Remove from the bad relocations those that match an undefined weak symbol +# which will result in an absolute relocation to 0. +# Weak unresolved symbols are of that form in nm output: +# " w _binary__btf_vmlinux_bin_end" +undef_weak_symbols=$($nm "$vmlinux" | awk -e '$1 ~ /w/ { print $2 }') + +while IFS= read -r weak_symbol; do + bad_relocs="$(echo -n "$bad_relocs" | sed "/$weak_symbol/d")" +done <<< "$undef_weak_symbols" This is not a bash script, and the above is a bashism :-( Also, my version of awk (mawk) doesn't have a -e option. How about something like : undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }') if [ "$undef_weak_symbols" ]; then bad_relocs="$(echo "$bad_relocs" | grep -F -w -v "$undef_weak_symbols")" fi Or do this near the top and add the grep to the others. Yes that's quite better, thanks, I'll send a new version tomorrow. Thanks again, Alex
Re: [RFC PATCH v4 10/11] lib: vdso: Allow arches to override the ns shift operation
Andy Lutomirski writes: > On Thu, Jan 16, 2020 at 9:58 AM Christophe Leroy > > Would mul_u64_u64_shr() be a good alternative? Could we adjust it to > assume the shift is less than 32? That function exists to benefit > 32-bit arches. We'd want mul_u64_u32_shr() for this. The rules for mult and shift are: 1 <= mult <= U32_MAX 1 <= shift <= 32 If we want to enforce a shift < 32 we need to limit that conditionally in the calculation/registration function. Thanks, tglx
Re: [RFC PATCH v4 08/11] lib: vdso: allow fixed clock mode
Christophe Leroy writes: Can you please adjust the prefix for future patches to lib/vdso: and start the sentence after the colon with an uppercase letter? > On arches like POWERPC, the clock is always the timebase, it Please spell out architectures. Changelogs are not space constraint. > cannot be changed on the fly and it is always VDSO capable. Also this sentence does not make sense as it might suggests that architectures with a fixed compile time known clocksource have something named timebase. Something like this is more clear: Some architectures have a fixed clocksource which is known at compile time and cannot be replaced or disabled at runtime, e.g. timebase on PowerPC. For such cases the clock mode check in the VDSO code is pointless. Hmm? Thanks, tglx
Re: [RFC PATCH v4 08/11] lib: vdso: allow fixed clock mode
On Thu, Jan 16, 2020 at 12:14 PM Thomas Gleixner wrote: > > Christophe Leroy writes: > > Can you please adjust the prefix for future patches to lib/vdso: and > start the sentence after the colon with an uppercase letter? > > > On arches like POWERPC, the clock is always the timebase, it > > Please spell out architectures. Changelogs are not space constraint. > > > cannot be changed on the fly and it is always VDSO capable. > > Also this sentence does not make sense as it might suggests that > architectures with a fixed compile time known clocksource have something > named timebase. Something like this is more clear: > > Some architectures have a fixed clocksource which is known at compile > time and cannot be replaced or disabled at runtime, e.g. timebase on > PowerPC. For such cases the clock mode check in the VDSO code is > pointless. > I wonder if we should use this on x86 bare-metal if we have sufficiently invariant TSC. (Via static_cpu_has(), not compiled in.) Maybe there is no such x86 machine. I really really want Intel or AMD to introduce machines where the TSC pinky-swears to count in actual nanoseconds. --Andy
Re: [RFC PATCH v4 10/11] lib: vdso: Allow arches to override the ns shift operation
On Thu, Jan 16, 2020 at 11:57 AM Thomas Gleixner wrote: > > Andy Lutomirski writes: > > On Thu, Jan 16, 2020 at 9:58 AM Christophe Leroy > > > > Would mul_u64_u64_shr() be a good alternative? Could we adjust it to > > assume the shift is less than 32? That function exists to benefit > > 32-bit arches. > > We'd want mul_u64_u32_shr() for this. The rules for mult and shift are: > That's what I meant to type... > 1 <= mult <= U32_MAX > > 1 <= shift <= 32 > > If we want to enforce a shift < 32 we need to limit that conditionally > in the calculation/registration function. > > Thanks, > > tglx >
Re: [RFC PATCH v3 08/12] lib: vdso: allow arches to provide vdso data pointer
On Thu, Jan 16, 2020 at 2:35 AM Thomas Gleixner wrote: > > static __maybe_unused int > __cvdso_data_clock_gettime(clockid_t clock, struct __kernel_timespec *ts, >const struct vdso_data *vd) > { > . > } > > static __maybe_unused int > __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) > { > const struct vdso_data *vd = __arch_get_vdso_data(); > > return __cvdso_data_clock_gettime(clock, ts, vd); > } > > and then use __cvdso_data_clock_gettime on PPC and let the other archs > unmodified. > > FWIW, I did some experiments on x86 with gcc 9.2. gcc 9.2 uses rip-relative accesses if I simplify the config enough and otherwise materializes the pointer. Presumably it decides that the code size reduction is worth it if there are a lot of accesses. I suspect that tglx's suggestion will be fine or at worst will add negligible overhead on x86_64.
Re: [PATCH v12 04/22] mm: devmap: refactor 1-based refcounting for ZONE_DEVICE pages
On 1/16/20 1:37 AM, Christoph Hellwig wrote: On Wed, Jan 15, 2020 at 01:19:41PM -0800, John Hubbard wrote: On 1/15/20 7:23 AM, Christoph Hellwig wrote: ... I'm really not sold on this scheme. Note that I think it is particularly bad, but it also doesn't seem any better than what we had before, and it introduced quite a bit more code. Hi Christoph, All by itself, yes. But the very next patch (which needs a little rework for other reasons, so not included here) needs to reuse some of these functions within __unpin_devmap_managed_user_page(): Well, then combine it with the series that actually does the change. OK, that makes sense. I just double-checked with a quick test run, that it doesn't have dependencies with the rest of this series, and it came out clean, so: Andrew, could you please remove just this one patch from mmotm and linux-next? Also my vaguely recollection is that we had some idea on how to get rid of the off by one refcounting for the zone device pages, which would be a much better outcome. Yes, I recall that Dan Williams mentioned it, but I don't think he provided any details yet. thanks, -- John Hubbard NVIDIA
Re: [RFC PATCH v4 08/11] lib: vdso: allow fixed clock mode
Andy Lutomirski writes: > On Thu, Jan 16, 2020 at 12:14 PM Thomas Gleixner wrote: >> Some architectures have a fixed clocksource which is known at compile >> time and cannot be replaced or disabled at runtime, e.g. timebase on >> PowerPC. For such cases the clock mode check in the VDSO code is >> pointless. >> > I wonder if we should use this on x86 bare-metal if we have > sufficiently invariant TSC. (Via static_cpu_has(), not compiled in.) > > Maybe there is no such x86 machine. There might be some, but every time I started to trust the TSC a bit more someone reported the next variant of brokenness. Admittedly it has become better at least up to two sockets. For a start we could do that when the TSC is considered reliable, which is the case when: - The TSC is the only available clocksource - tsc=reliable is on the kernel command line > I really really want Intel or AMD to introduce machines where the TSC > pinky-swears to count in actual nanoseconds. and is guaranteed to be synchronized across any number of sockets/cpus and has an enforcable protection against BIOS writers. Ideally it'd have a writeable MSR attached which allows us to tweak the frequency in the PPM range via NTP/PTP. Guess how long quite some people including Linus and myself are asking for this? I know that Linus started bitching about the TSC before me, but it's already a bit over 20 years on my side when I first talked to Intel and AMD about the requirements for a reliable clocksource. Just to set the time lines straight. Constant frequency TSC surfaced on Intel in 2006 with the Core brand and on AMD in 2007 with Barcelona (Fam 10h). In 2008 the first TSC surfaced which was not affected by C-States and 5 years later in 2013 some Atoms came out where TSC even worked accross S3. The > 2 socket issue is still not resolved AFAICT, but we got at least the TSC ADJUST MSR around 2012 which allowed us for the first time to reliably detect and mitigate BIOS wreckage. All the years I was envy on architectures which had simple designed and just reliably working timers forever. So now you can extrapolate how long it will take until you get your pinky-swearing pony :) Thanks, tglx
Re: [PATCH v2] Fix display of Maximum Memory
On 1/15/20 11:53 PM, Michael Ellerman wrote: > Michael Bringmann writes: >> Correct overflow problem in calculation+display of Maximum Memory >> value to syscfg where 32bits is insufficient. >> >> Signed-off-by: Michael Bringmann >> --- >> arch/powerpc/platforms/pseries/lparcfg.c | 8 >> 1 file changed, 4 insertions(+), 4 deletions(-) >> >> diff --git a/arch/powerpc/platforms/pseries/lparcfg.c >> b/arch/powerpc/platforms/pseries/lparcfg.c >> index e33e8bc..f00411c 100644 >> --- a/arch/powerpc/platforms/pseries/lparcfg.c >> +++ b/arch/powerpc/platforms/pseries/lparcfg.c >> @@ -433,12 +433,12 @@ static void parse_em_data(struct seq_file *m) >> >> static void maxmem_data(struct seq_file *m) >> { >> -unsigned long maxmem = 0; >> +u64 maxmem = 0; > > This is 64-bit only code, so u64 == unsigned long. > >> -maxmem += drmem_info->n_lmbs * drmem_info->lmb_size; >> -maxmem += hugetlb_total_pages() * PAGE_SIZE; >> +maxmem += (u64)drmem_info->n_lmbs * drmem_info->lmb_size; > > The only problem AFAICS is n_lmbs is int and lmb_size is u32, so this > multiplication will overflow. > >> +maxmem += (u64)hugetlb_total_pages() * PAGE_SIZE; > > hugetlb_total_pages() already returns unsigned long. > >> -seq_printf(m, "MaxMem=%ld\n", maxmem); >> +seq_printf(m, "MaxMem=%llu\n", maxmem); >> } > > This should be sufficient? > > diff --git a/arch/powerpc/platforms/pseries/lparcfg.c > b/arch/powerpc/platforms/pseries/lparcfg.c > index e33e8bc4b69b..38c306551f76 100644 > --- a/arch/powerpc/platforms/pseries/lparcfg.c > +++ b/arch/powerpc/platforms/pseries/lparcfg.c > @@ -435,10 +435,10 @@ static void maxmem_data(struct seq_file *m) > { > unsigned long maxmem = 0; > > - maxmem += drmem_info->n_lmbs * drmem_info->lmb_size; > + maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size; > maxmem += hugetlb_total_pages() * PAGE_SIZE; > > - seq_printf(m, "MaxMem=%ld\n", maxmem); > + seq_printf(m, "MaxMem=%lu\n", maxmem); > } > > static int pseries_lparcfg_data(struct seq_file *m, void *v) > > > cheers > Trying it out. -- Michael W. Bringmann Linux Technology Center IBM Corporation Tie-Line 363-5196 External: (512) 286-5196 Cell: (512) 466-0650 m...@linux.ibm.com
[PATCH 2/3] selftests/powerpc: Add tm-signal-pagefault test
This test triggers a TM Bad Thing by raising a signal in transactional state and forcing a pagefault to happen in kernelspace when the kernel signal handling code first touches the user signal stack. This is inspired by the test tm-signal-context-force-tm but uses userfaultfd to make the test deterministic. While this test always triggers the bug in one run, I had to execute tm-signal-context-force-tm several times (the test runs 5000 times each execution) to trigger the same bug. tm-signal-context-force-tm is kept instead of replaced because, while this test is more reliable and triggers the same bug, tm-signal-context-force-tm has a better coverage, in the sense that by running the test several times it might trigger the pagefault and/or be preempted at different places. Signed-off-by: Gustavo Luiz Duarte --- tools/testing/selftests/powerpc/tm/.gitignore | 1 + tools/testing/selftests/powerpc/tm/Makefile | 3 +- .../powerpc/tm/tm-signal-pagefault.c | 272 ++ 3 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/tm/tm-signal-pagefault.c diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore index 98f2708d86cc..e1c72a4a3e91 100644 --- a/tools/testing/selftests/powerpc/tm/.gitignore +++ b/tools/testing/selftests/powerpc/tm/.gitignore @@ -13,6 +13,7 @@ tm-signal-context-chk-vmx tm-signal-context-chk-vsx tm-signal-context-force-tm tm-signal-sigreturn-nt +tm-signal-pagefault tm-vmx-unavail tm-unavailable tm-trap diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index b15a1a325bd0..b1d99736f8b8 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -5,7 +5,7 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \ $(SIGNAL_CONTEXT_CHK_TESTS) tm-sigreturn tm-signal-sigreturn-nt \ - tm-signal-context-force-tm tm-poison + tm-signal-context-force-tm tm-poison tm-signal-pagefault top_srcdir = ../../../../.. include ../../lib.mk @@ -22,6 +22,7 @@ $(OUTPUT)/tm-resched-dscr: ../pmu/lib.c $(OUTPUT)/tm-unavailable: CFLAGS += -O0 -pthread -m64 -Wno-error=uninitialized -mvsx $(OUTPUT)/tm-trap: CFLAGS += -O0 -pthread -m64 $(OUTPUT)/tm-signal-context-force-tm: CFLAGS += -pthread -m64 +$(OUTPUT)/tm-signal-pagefault: CFLAGS += -pthread -m64 SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS)) $(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-pagefault.c b/tools/testing/selftests/powerpc/tm/tm-signal-pagefault.c new file mode 100644 index ..3a2166101d94 --- /dev/null +++ b/tools/testing/selftests/powerpc/tm/tm-signal-pagefault.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020, Gustavo Luiz Duarte, IBM Corp. + * + * This test starts a transaction and triggers a signal, forcing a pagefault to + * happen when the kernel signal handling code touches the user signal stack. + * + * In order to avoid pre-faulting the signal stack memory and to force the + * pagefault to happen precisely in the kernel signal handling code, the + * pagefault handling is done in userspace using the userfaultfd facility. + * + * Further pagefaults are triggered by crafting the signal handler's ucontext + * to point to additional memory regions managed by the userfaultfd, so using + * the same mechanism used to avoid pre-faulting the signal stack memory. + * + * On failure (bug is present) kernel crashes or never returns control back to + * userspace. If bug is not present, tests completes almost immediately. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tm.h" + + +#define UF_MEM_SIZE 655360 /* 10 x 64k pages */ + +/* Memory handled by userfaultfd */ +static char *uf_mem; +static size_t uf_mem_offset = 0; + +/* + * Data that will be copied into the faulting pages (instead of zero-filled + * pages). This is used to make the test more reliable and avoid segfaulting + * when we return from the signal handler. Since we are making the signal + * handler's ucontext point to newly allocated memory, when that memory is + * paged-in it will contain the expected content. + */ +static char backing_mem[UF_MEM_SIZE]; + +static size_t pagesize; + +/* + * Return a chunk of at least 'size' bytes of memory that will be handled by + * userfaultfd. If 'backing_data' is not NULL, its content will be save to + * 'backing_mem' and then copied into the faulting pages when the page fault + * is handled. + */ +void *get_uf_mem(size_t size, void *backing_data) +{ + void *ret; +
[PATCH 3/3] selftests/powerpc: Don't rely on segfault to rerun the test
The test case tm-signal-context-force-tm expects a segfault to happen on returning from signal handler, and then does a setcontext() to run the test again. However, the test doesn't always segfault, causing the test to run a single time. This patch fixes the test by putting it within a loop and jumping, via setcontext, just prior to the loop in case it segfaults. This way we get the desired behavior (run the test COUNT_MAX times) regardless if it segfaults or not. This also reduces the use of setcontext for control flow logic, keeping it only in the segfault handler. Also, since 'count' is changed within the signal handler, it is declared as volatile to prevent any compiler optimization getting confused with asynchronous changes. Signed-off-by: Gustavo Luiz Duarte --- .../powerpc/tm/tm-signal-context-force-tm.c | 79 +-- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c b/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c index 31717625f318..9ff7bdb6d47a 100644 --- a/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c +++ b/tools/testing/selftests/powerpc/tm/tm-signal-context-force-tm.c @@ -42,9 +42,10 @@ #endif /* Setting contexts because the test will crash and we want to recover */ -ucontext_t init_context, main_context; +ucontext_t init_context; -static int count, first_time; +/* count is changed in the signal handler, so it must be volatile */ +static volatile int count; void usr_signal_handler(int signo, siginfo_t *si, void *uc) { @@ -98,11 +99,6 @@ void usr_signal_handler(int signo, siginfo_t *si, void *uc) void seg_signal_handler(int signo, siginfo_t *si, void *uc) { - if (count == COUNT_MAX) { - /* Return to tm_signal_force_msr() and exit */ - setcontext(&main_context); - } - count++; /* Reexecute the test */ @@ -126,37 +122,40 @@ void tm_trap_test(void) */ getcontext(&init_context); - /* Allocated an alternative signal stack area */ - ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - ss.ss_size = SIGSTKSZ; - ss.ss_flags = 0; - - if (ss.ss_sp == (void *)-1) { - perror("mmap error\n"); - exit(-1); - } - - /* Force the allocation through a page fault */ - if (madvise(ss.ss_sp, SIGSTKSZ, MADV_DONTNEED)) { - perror("madvise\n"); - exit(-1); - } - - /* Setting an alternative stack to generate a page fault when -* the signal is raised. -*/ - if (sigaltstack(&ss, NULL)) { - perror("sigaltstack\n"); - exit(-1); + while (count < COUNT_MAX) { + /* Allocated an alternative signal stack area */ + ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + + if (ss.ss_sp == (void *)-1) { + perror("mmap error\n"); + exit(-1); + } + + /* Force the allocation through a page fault */ + if (madvise(ss.ss_sp, SIGSTKSZ, MADV_DONTNEED)) { + perror("madvise\n"); + exit(-1); + } + + /* Setting an alternative stack to generate a page fault when +* the signal is raised. +*/ + if (sigaltstack(&ss, NULL)) { + perror("sigaltstack\n"); + exit(-1); + } + + /* The signal handler will enable MSR_TS */ + sigaction(SIGUSR1, &usr_sa, NULL); + /* If it does not crash, it might segfault, avoid it to retest */ + sigaction(SIGSEGV, &seg_sa, NULL); + + raise(SIGUSR1); + count++; } - - /* The signal handler will enable MSR_TS */ - sigaction(SIGUSR1, &usr_sa, NULL); - /* If it does not crash, it will segfault, avoid it to retest */ - sigaction(SIGSEGV, &seg_sa, NULL); - - raise(SIGUSR1); } int tm_signal_context_force_tm(void) @@ -169,11 +168,7 @@ int tm_signal_context_force_tm(void) */ SKIP_IF(!is_ppc64le()); - /* Will get back here after COUNT_MAX interactions */ - getcontext(&main_context); - - if (!first_time++) - tm_trap_test(); + tm_trap_test(); return EXIT_SUCCESS; } -- 2.21.0