* Re: [PATCH 0/4] arch, mm: improve robustness of direct map manipulation
From: Mike Rapoport @ 2020-10-28 11:30 UTC (permalink / raw)
To: Will Deacon
Cc: david@redhat.com, peterz@infradead.org, catalin.marinas@arm.com,
dave.hansen@linux.intel.com, linux-mm@kvack.org, paulus@samba.org,
pavel@ucw.cz, hpa@zytor.com, sparclinux@vger.kernel.org,
cl@linux.com, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, x86@kernel.org, rppt@linux.ibm.com,
borntraeger@de.ibm.com, mingo@redhat.com, rientjes@google.com,
Brown, Len, aou@eecs.berkeley.edu, gor@linux.ibm.com,
linux-pm@vger.kernel.org, hca@linux.ibm.com, bp@alien8.de,
luto@kernel.org, paul.walmsley@sifive.com, kirill@shutemov.name,
tglx@linutronix.de, iamjoonsoo.kim@lge.com,
linux-arm-kernel@lists.infradead.org, rjw@rjwysocki.net,
linux-kernel@vger.kernel.org, penberg@kernel.org,
palmer@dabbelt.com, akpm@linux-foundation.org, Edgecombe, Rick P,
linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
In-Reply-To: <20201028112011.GB27927@willie-the-truck>
On Wed, Oct 28, 2020 at 11:20:12AM +0000, Will Deacon wrote:
> On Tue, Oct 27, 2020 at 10:38:16AM +0200, Mike Rapoport wrote:
> > On Mon, Oct 26, 2020 at 06:05:30PM +0000, Edgecombe, Rick P wrote:
> > > On Mon, 2020-10-26 at 11:05 +0200, Mike Rapoport wrote:
> > > > On Mon, Oct 26, 2020 at 01:13:52AM +0000, Edgecombe, Rick P wrote:
> > > > > On Sun, 2020-10-25 at 12:15 +0200, Mike Rapoport wrote:
> > > > > > Indeed, for architectures that define
> > > > > > CONFIG_ARCH_HAS_SET_DIRECT_MAP
> > > > > > it is
> > > > > > possible that __kernel_map_pages() would fail, but since this
> > > > > > function is
> > > > > > void, the failure will go unnoticed.
> > > > >
> > > > > Could you elaborate on how this could happen? Do you mean during
> > > > > runtime today or if something new was introduced?
> > > >
> > > > A failure in__kernel_map_pages() may happen today. For instance, on
> > > > x86
> > > > if the kernel is built with DEBUG_PAGEALLOC.
> > > >
> > > > __kernel_map_pages(page, 1, 0);
> > > >
> > > > will need to split, say, 2M page and during the split an allocation
> > > > of
> > > > page table could fail.
> > >
> > > On x86 at least, DEBUG_PAGEALLOC expects to never have to break a page
> > > on the direct map and even disables locking in cpa because it assumes
> > > this. If this is happening somehow anyway then we should probably fix
> > > that. Even if it's a debug feature, it will not be as useful if it is
> > > causing its own crashes.
> > >
> > > I'm still wondering if there is something I'm missing here. It seems
> > > like you are saying there is a bug in some arch's, so let's add a WARN
> > > in cross-arch code to log it as it crashes. A warn and making things
> > > clearer seem like good ideas, but if there is a bug we should fix it.
> > > The code around the callers still functionally assume re-mapping can't
> > > fail.
> >
> > Oh, I've meant x86 kernel *without* DEBUG_PAGEALLOC, and indeed the call
> > that unmaps pages back in safe_copy_page will just reset a 4K page to
> > NP because whatever made it NP at the first place already did the split.
> >
> > Still, on arm64 with DEBUG_PAGEALLOC=n there is a possibility of a race
> > between map/unmap dance in __vunmap() and safe_copy_page() that may
> > cause access to unmapped memory:
> >
> > __vunmap()
> > vm_remove_mappings()
> > set_direct_map_invalid()
> > safe_copy_page()
> > __kernel_map_pages()
> > return
> > do_copy_page() -> fault
> >
> > This is a theoretical bug, but it is still not nice :)
>
> Just to clarify: this patch series fixes this problem, right?
Yes.
> Will
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [PATCH 0/4] arch, mm: improve robustness of direct map manipulation
From: Will Deacon @ 2020-10-28 11:20 UTC (permalink / raw)
To: Mike Rapoport
Cc: david@redhat.com, peterz@infradead.org, catalin.marinas@arm.com,
dave.hansen@linux.intel.com, linux-mm@kvack.org, paulus@samba.org,
pavel@ucw.cz, hpa@zytor.com, sparclinux@vger.kernel.org,
cl@linux.com, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, x86@kernel.org, rppt@linux.ibm.com,
borntraeger@de.ibm.com, mingo@redhat.com, rientjes@google.com,
Brown, Len, aou@eecs.berkeley.edu, gor@linux.ibm.com,
linux-pm@vger.kernel.org, hca@linux.ibm.com, bp@alien8.de,
luto@kernel.org, paul.walmsley@sifive.com, kirill@shutemov.name,
tglx@linutronix.de, iamjoonsoo.kim@lge.com,
linux-arm-kernel@lists.infradead.org, rjw@rjwysocki.net,
linux-kernel@vger.kernel.org, penberg@kernel.org,
palmer@dabbelt.com, akpm@linux-foundation.org, Edgecombe, Rick P,
linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
In-Reply-To: <20201027083816.GG1154158@kernel.org>
On Tue, Oct 27, 2020 at 10:38:16AM +0200, Mike Rapoport wrote:
> On Mon, Oct 26, 2020 at 06:05:30PM +0000, Edgecombe, Rick P wrote:
> > On Mon, 2020-10-26 at 11:05 +0200, Mike Rapoport wrote:
> > > On Mon, Oct 26, 2020 at 01:13:52AM +0000, Edgecombe, Rick P wrote:
> > > > On Sun, 2020-10-25 at 12:15 +0200, Mike Rapoport wrote:
> > > > > Indeed, for architectures that define
> > > > > CONFIG_ARCH_HAS_SET_DIRECT_MAP
> > > > > it is
> > > > > possible that __kernel_map_pages() would fail, but since this
> > > > > function is
> > > > > void, the failure will go unnoticed.
> > > >
> > > > Could you elaborate on how this could happen? Do you mean during
> > > > runtime today or if something new was introduced?
> > >
> > > A failure in__kernel_map_pages() may happen today. For instance, on
> > > x86
> > > if the kernel is built with DEBUG_PAGEALLOC.
> > >
> > > __kernel_map_pages(page, 1, 0);
> > >
> > > will need to split, say, 2M page and during the split an allocation
> > > of
> > > page table could fail.
> >
> > On x86 at least, DEBUG_PAGEALLOC expects to never have to break a page
> > on the direct map and even disables locking in cpa because it assumes
> > this. If this is happening somehow anyway then we should probably fix
> > that. Even if it's a debug feature, it will not be as useful if it is
> > causing its own crashes.
> >
> > I'm still wondering if there is something I'm missing here. It seems
> > like you are saying there is a bug in some arch's, so let's add a WARN
> > in cross-arch code to log it as it crashes. A warn and making things
> > clearer seem like good ideas, but if there is a bug we should fix it.
> > The code around the callers still functionally assume re-mapping can't
> > fail.
>
> Oh, I've meant x86 kernel *without* DEBUG_PAGEALLOC, and indeed the call
> that unmaps pages back in safe_copy_page will just reset a 4K page to
> NP because whatever made it NP at the first place already did the split.
>
> Still, on arm64 with DEBUG_PAGEALLOC=n there is a possibility of a race
> between map/unmap dance in __vunmap() and safe_copy_page() that may
> cause access to unmapped memory:
>
> __vunmap()
> vm_remove_mappings()
> set_direct_map_invalid()
> safe_copy_page()
> __kernel_map_pages()
> return
> do_copy_page() -> fault
>
> This is a theoretical bug, but it is still not nice :)
Just to clarify: this patch series fixes this problem, right?
Will
^ permalink raw reply
* Re: [PATCH 0/4] arch, mm: improve robustness of direct map manipulation
From: David Hildenbrand @ 2020-10-28 11:17 UTC (permalink / raw)
To: Mike Rapoport
Cc: peterz@infradead.org, catalin.marinas@arm.com,
dave.hansen@linux.intel.com, linux-mm@kvack.org, paulus@samba.org,
pavel@ucw.cz, hpa@zytor.com, sparclinux@vger.kernel.org,
cl@linux.com, will@kernel.org, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, x86@kernel.org, rppt@linux.ibm.com,
borntraeger@de.ibm.com, mingo@redhat.com, rientjes@google.com,
Brown, Len, aou@eecs.berkeley.edu, gor@linux.ibm.com,
linux-pm@vger.kernel.org, hca@linux.ibm.com, bp@alien8.de,
luto@kernel.org, paul.walmsley@sifive.com, kirill@shutemov.name,
tglx@linutronix.de, iamjoonsoo.kim@lge.com,
linux-arm-kernel@lists.infradead.org, rjw@rjwysocki.net,
linux-kernel@vger.kernel.org, penberg@kernel.org,
palmer@dabbelt.com, akpm@linux-foundation.org, Edgecombe, Rick P,
linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
In-Reply-To: <20201028110945.GE1428094@kernel.org>
On 28.10.20 12:09, Mike Rapoport wrote:
> On Tue, Oct 27, 2020 at 09:46:35AM +0100, David Hildenbrand wrote:
>> On 27.10.20 09:38, Mike Rapoport wrote:
>>> On Mon, Oct 26, 2020 at 06:05:30PM +0000, Edgecombe, Rick P wrote:
>>>
>>>> Beyond whatever you are seeing, for the latter case of new things
>>>> getting introduced to an interface with hidden dependencies... Another
>>>> edge case could be a new caller to set_memory_np() could result in
>>>> large NP pages. None of the callers today should cause this AFAICT, but
>>>> it's not great to rely on the callers to know these details.
>
>>> A caller of set_memory_*() or set_direct_map_*() should expect a failure
>>> and be ready for that. So adding a WARN to safe_copy_page() is the first
>>> step in that direction :)
>>>
>>
>> I am probably missing something important, but why are we saving/restoring
>> the content of pages that were explicitly removed from the identity mapping
>> such that nobody will access them?
>
> Actually, we should not be saving/restoring free pages during
> hibernation as there are several calls to mark_free_pages() that should
> exclude the free pages from the snapshot. I've tried to find why the fix
> that maps/unmaps a page to save it was required at the first place, but
> I could not find bug reports.
>
> The closest I've got is an email from Rafael that asked to update
> "hibernate: handle DEBUG_PAGEALLOC" patch:
>
> https://lore.kernel.org/linux-pm/200802200133.44098.rjw@sisk.pl/
>
> Could it be that safe_copy_page() tries to workaround a non-existent
> problem?
>
Clould be! Also see
https://lkml.kernel.org/r/38de5bb0-5559-d069-0ce0-daec66ef2746@suse.cz
which restores free page content based on more kernel parameters, not
based on the original content.
--
Thanks,
David / dhildenb
^ permalink raw reply
* Re: [PATCH 0/4] arch, mm: improve robustness of direct map manipulation
From: Mike Rapoport @ 2020-10-28 11:09 UTC (permalink / raw)
To: David Hildenbrand
Cc: peterz@infradead.org, catalin.marinas@arm.com,
dave.hansen@linux.intel.com, linux-mm@kvack.org, paulus@samba.org,
pavel@ucw.cz, hpa@zytor.com, sparclinux@vger.kernel.org,
cl@linux.com, will@kernel.org, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, x86@kernel.org, rppt@linux.ibm.com,
borntraeger@de.ibm.com, mingo@redhat.com, rientjes@google.com,
Brown, Len, aou@eecs.berkeley.edu, gor@linux.ibm.com,
linux-pm@vger.kernel.org, hca@linux.ibm.com, bp@alien8.de,
luto@kernel.org, paul.walmsley@sifive.com, kirill@shutemov.name,
tglx@linutronix.de, iamjoonsoo.kim@lge.com,
linux-arm-kernel@lists.infradead.org, rjw@rjwysocki.net,
linux-kernel@vger.kernel.org, penberg@kernel.org,
palmer@dabbelt.com, akpm@linux-foundation.org, Edgecombe, Rick P,
linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
In-Reply-To: <e5fc62b6-f644-4ed5-de5b-ffd8337861e4@redhat.com>
On Tue, Oct 27, 2020 at 09:46:35AM +0100, David Hildenbrand wrote:
> On 27.10.20 09:38, Mike Rapoport wrote:
> > On Mon, Oct 26, 2020 at 06:05:30PM +0000, Edgecombe, Rick P wrote:
> >
> > > Beyond whatever you are seeing, for the latter case of new things
> > > getting introduced to an interface with hidden dependencies... Another
> > > edge case could be a new caller to set_memory_np() could result in
> > > large NP pages. None of the callers today should cause this AFAICT, but
> > > it's not great to rely on the callers to know these details.
> > A caller of set_memory_*() or set_direct_map_*() should expect a failure
> > and be ready for that. So adding a WARN to safe_copy_page() is the first
> > step in that direction :)
> >
>
> I am probably missing something important, but why are we saving/restoring
> the content of pages that were explicitly removed from the identity mapping
> such that nobody will access them?
Actually, we should not be saving/restoring free pages during
hibernation as there are several calls to mark_free_pages() that should
exclude the free pages from the snapshot. I've tried to find why the fix
that maps/unmaps a page to save it was required at the first place, but
I could not find bug reports.
The closest I've got is an email from Rafael that asked to update
"hibernate: handle DEBUG_PAGEALLOC" patch:
https://lore.kernel.org/linux-pm/200802200133.44098.rjw@sisk.pl/
Could it be that safe_copy_page() tries to workaround a non-existent
problem?
--
Sincerely yours,
Mike.
^ permalink raw reply
* [PATCH v2 2/2] ASoC: fsl_aud2htx: Add aud2htx module driver
From: Shengjiu Wang @ 2020-10-28 9:38 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood, robh+dt, devicetree
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1603877930-10553-1-git-send-email-shengjiu.wang@nxp.com>
The AUD2HTX is a digital module that provides a bridge between
the Audio Subsystem and the HDMI RTX Subsystem. This module
includes intermediate storage to queue SDMA transactions prior
to being synchronized and passed to the HDMI RTX Subsystem over
the Audio Link.
The AUD2HTX contains a DMA request routed to the SDMA module.
This DMA request is controlled based on the watermark level in
the 32-entry sample buffer.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
changes in v2:
- remove hw_params, add operation to dai probe
sound/soc/fsl/Kconfig | 5 +
sound/soc/fsl/Makefile | 2 +
sound/soc/fsl/fsl_aud2htx.c | 313 ++++++++++++++++++++++++++++++++++++
sound/soc/fsl/fsl_aud2htx.h | 67 ++++++++
4 files changed, 387 insertions(+)
create mode 100644 sound/soc/fsl/fsl_aud2htx.c
create mode 100644 sound/soc/fsl/fsl_aud2htx.h
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d04b64d32dc1..52a562215008 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -105,6 +105,11 @@ config SND_SOC_FSL_XCVR
iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
HDMI1.4 ARC and SPDIF.
+config SND_SOC_FSL_AUD2HTX
+ tristate "AUDIO TO HDMI TX module support"
+ help
+ Say Y if you want to add AUDIO TO HDMI TX support for NXP.
+
config SND_SOC_FSL_UTILS
tristate
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 1d2231f9cc47..2181b7f9f677 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -26,6 +26,7 @@ snd-soc-fsl-dma-objs := fsl_dma.o
snd-soc-fsl-mqs-objs := fsl_mqs.o
snd-soc-fsl-easrc-objs := fsl_easrc.o
snd-soc-fsl-xcvr-objs := fsl_xcvr.o
+snd-soc-fsl-aud2htx-objs := fsl_aud2htx.o
obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
@@ -40,6 +41,7 @@ obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o
obj-$(CONFIG_SND_SOC_FSL_EASRC) += snd-soc-fsl-easrc.o
obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
+obj-$(CONFIG_SND_SOC_FSL_AUD2HTX) += snd-soc-fsl-aud2htx.o
# MPC5200 Platform Support
obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c
new file mode 100644
index 000000000000..a6e25195a8df
--- /dev/null
+++ b/sound/soc/fsl/fsl_aud2htx.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright 2020 NXP
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/pm_qos.h>
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/dma-mapping.h>
+
+#include "fsl_aud2htx.h"
+#include "imx-pcm.h"
+
+static int fsl_aud2htx_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_aud2htx *aud2htx = snd_soc_dai_get_drvdata(dai);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL,
+ AUD2HTX_CTRL_EN, AUD2HTX_CTRL_EN);
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
+ AUD2HTX_CTRE_DE, AUD2HTX_CTRE_DE);
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
+ AUD2HTX_CTRE_DE, 0);
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL,
+ AUD2HTX_CTRL_EN, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_aud2htx_dai_ops = {
+ .trigger = fsl_aud2htx_trigger,
+};
+
+static int fsl_aud2htx_dai_probe(struct snd_soc_dai *cpu_dai)
+{
+ struct fsl_aud2htx *aud2htx = dev_get_drvdata(cpu_dai->dev);
+
+ /* DMA request when number of entries < WTMK_LOW */
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
+ AUD2HTX_CTRE_DT_MASK, 0);
+
+ /* Disable interrupts*/
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_IRQ_MASK,
+ AUD2HTX_WM_HIGH_IRQ_MASK |
+ AUD2HTX_WM_LOW_IRQ_MASK |
+ AUD2HTX_OVF_MASK,
+ AUD2HTX_WM_HIGH_IRQ_MASK |
+ AUD2HTX_WM_LOW_IRQ_MASK |
+ AUD2HTX_OVF_MASK);
+
+ /* Configure watermark */
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
+ AUD2HTX_CTRE_WL_MASK,
+ AUD2HTX_WTMK_LOW << AUD2HTX_CTRE_WL_SHIFT);
+ regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
+ AUD2HTX_CTRE_WH_MASK,
+ AUD2HTX_WTMK_HIGH << AUD2HTX_CTRE_WH_SHIFT);
+
+ snd_soc_dai_init_dma_data(cpu_dai, &aud2htx->dma_params_tx,
+ &aud2htx->dma_params_rx);
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver fsl_aud2htx_dai = {
+ .probe = fsl_aud2htx_dai_probe,
+ .playback = {
+ .stream_name = "CPU-Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_32000 |
+ SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_176400 |
+ SNDRV_PCM_RATE_192000,
+ .formats = FSL_AUD2HTX_FORMATS,
+ },
+ .ops = &fsl_aud2htx_dai_ops,
+};
+
+static const struct snd_soc_component_driver fsl_aud2htx_component = {
+ .name = "fsl-aud2htx",
+};
+
+static const struct reg_default fsl_aud2htx_reg_defaults[] = {
+ {AUD2HTX_CTRL, 0x00000000},
+ {AUD2HTX_CTRL_EXT, 0x00000000},
+ {AUD2HTX_WR, 0x00000000},
+ {AUD2HTX_STATUS, 0x00000000},
+ {AUD2HTX_IRQ_NOMASK, 0x00000000},
+ {AUD2HTX_IRQ_MASKED, 0x00000000},
+ {AUD2HTX_IRQ_MASK, 0x00000000},
+};
+
+static bool fsl_aud2htx_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AUD2HTX_CTRL:
+ case AUD2HTX_CTRL_EXT:
+ case AUD2HTX_STATUS:
+ case AUD2HTX_IRQ_NOMASK:
+ case AUD2HTX_IRQ_MASKED:
+ case AUD2HTX_IRQ_MASK:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_aud2htx_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AUD2HTX_CTRL:
+ case AUD2HTX_CTRL_EXT:
+ case AUD2HTX_WR:
+ case AUD2HTX_IRQ_NOMASK:
+ case AUD2HTX_IRQ_MASKED:
+ case AUD2HTX_IRQ_MASK:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_aud2htx_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AUD2HTX_STATUS:
+ case AUD2HTX_IRQ_NOMASK:
+ case AUD2HTX_IRQ_MASKED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config fsl_aud2htx_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+
+ .max_register = AUD2HTX_IRQ_MASK,
+ .reg_defaults = fsl_aud2htx_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(fsl_aud2htx_reg_defaults),
+ .readable_reg = fsl_aud2htx_readable_reg,
+ .volatile_reg = fsl_aud2htx_volatile_reg,
+ .writeable_reg = fsl_aud2htx_writeable_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct of_device_id fsl_aud2htx_dt_ids[] = {
+ { .compatible = "fsl,imx8mp-aud2htx",},
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_aud2htx_dt_ids);
+
+static irqreturn_t fsl_aud2htx_isr(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static int fsl_aud2htx_probe(struct platform_device *pdev)
+{
+ struct fsl_aud2htx *aud2htx;
+ struct resource *res;
+ void __iomem *regs;
+ int ret, irq;
+
+ aud2htx = devm_kzalloc(&pdev->dev, sizeof(*aud2htx), GFP_KERNEL);
+ if (!aud2htx)
+ return -ENOMEM;
+
+ aud2htx->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs)) {
+ dev_err(&pdev->dev, "failed ioremap\n");
+ return PTR_ERR(regs);
+ }
+
+ aud2htx->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+ &fsl_aud2htx_regmap_config);
+ if (IS_ERR(aud2htx->regmap)) {
+ dev_err(&pdev->dev, "failed to init regmap");
+ return PTR_ERR(aud2htx->regmap);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq for node %s\n",
+ dev_name(&pdev->dev));
+ return irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, fsl_aud2htx_isr, 0,
+ dev_name(&pdev->dev), aud2htx);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
+ return ret;
+ }
+
+ aud2htx->bus_clk = devm_clk_get(&pdev->dev, "bus");
+ if (IS_ERR(aud2htx->bus_clk)) {
+ dev_err(&pdev->dev, "failed to get mem clock\n");
+ return PTR_ERR(aud2htx->bus_clk);
+ }
+
+ aud2htx->dma_params_tx.chan_name = "tx";
+ aud2htx->dma_params_tx.maxburst = AUD2HTX_MAXBURST;
+ aud2htx->dma_params_tx.addr = res->start + AUD2HTX_WR;
+
+ platform_set_drvdata(pdev, aud2htx);
+ pm_runtime_enable(&pdev->dev);
+
+ regcache_cache_only(aud2htx->regmap, true);
+
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &fsl_aud2htx_component,
+ &fsl_aud2htx_dai, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register ASoC DAI\n");
+ return ret;
+ }
+
+ ret = imx_pcm_dma_init(pdev, IMX_DEFAULT_DMABUF_SIZE);
+ if (ret)
+ dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
+
+ return ret;
+}
+
+static int fsl_aud2htx_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_aud2htx_runtime_suspend(struct device *dev)
+{
+ struct fsl_aud2htx *aud2htx = dev_get_drvdata(dev);
+
+ regcache_cache_only(aud2htx->regmap, true);
+ clk_disable_unprepare(aud2htx->bus_clk);
+
+ return 0;
+}
+
+static int fsl_aud2htx_runtime_resume(struct device *dev)
+{
+ struct fsl_aud2htx *aud2htx = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(aud2htx->bus_clk);
+ if (ret)
+ return ret;
+
+ regcache_cache_only(aud2htx->regmap, false);
+ regcache_mark_dirty(aud2htx->regmap);
+ regcache_sync(aud2htx->regmap);
+
+ return 0;
+}
+#endif /*CONFIG_PM*/
+
+static const struct dev_pm_ops fsl_aud2htx_pm_ops = {
+ SET_RUNTIME_PM_OPS(fsl_aud2htx_runtime_suspend,
+ fsl_aud2htx_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+static struct platform_driver fsl_aud2htx_driver = {
+ .probe = fsl_aud2htx_probe,
+ .remove = fsl_aud2htx_remove,
+ .driver = {
+ .name = "fsl-aud2htx",
+ .pm = &fsl_aud2htx_pm_ops,
+ .of_match_table = fsl_aud2htx_dt_ids,
+ },
+};
+module_platform_driver(fsl_aud2htx_driver);
+
+MODULE_AUTHOR("Shengjiu Wang <Shengjiu.Wang@nxp.com>");
+MODULE_DESCRIPTION("NXP AUD2HTX driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_aud2htx.h b/sound/soc/fsl/fsl_aud2htx.h
new file mode 100644
index 000000000000..ad70d6a7694c
--- /dev/null
+++ b/sound/soc/fsl/fsl_aud2htx.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020 NXP
+ */
+
+#ifndef _FSL_AUD2HTX_H
+#define _FSL_AUD2HTX_H
+
+#define FSL_AUD2HTX_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+/* AUD2HTX Register Map */
+#define AUD2HTX_CTRL 0x0 /* AUD2HTX Control Register */
+#define AUD2HTX_CTRL_EXT 0x4 /* AUD2HTX Control Extended Register */
+#define AUD2HTX_WR 0x8 /* AUD2HTX Write Register */
+#define AUD2HTX_STATUS 0xC /* AUD2HTX Status Register */
+#define AUD2HTX_IRQ_NOMASK 0x10 /* AUD2HTX Nonmasked Interrupt Flags Register */
+#define AUD2HTX_IRQ_MASKED 0x14 /* AUD2HTX Masked Interrupt Flags Register */
+#define AUD2HTX_IRQ_MASK 0x18 /* AUD2HTX IRQ Masks Register */
+
+/* AUD2HTX Control Register */
+#define AUD2HTX_CTRL_EN BIT(0)
+
+/* AUD2HTX Control Extended Register */
+#define AUD2HTX_CTRE_DE BIT(0)
+#define AUD2HTX_CTRE_DT_SHIFT 0x1
+#define AUD2HTX_CTRE_DT_WIDTH 0x2
+#define AUD2HTX_CTRE_DT_MASK ((BIT(AUD2HTX_CTRE_DT_WIDTH) - 1) \
+ << AUD2HTX_CTRE_DT_SHIFT)
+#define AUD2HTX_CTRE_WL_SHIFT 16
+#define AUD2HTX_CTRE_WL_WIDTH 5
+#define AUD2HTX_CTRE_WL_MASK ((BIT(AUD2HTX_CTRE_WL_WIDTH) - 1) \
+ << AUD2HTX_CTRE_WL_SHIFT)
+#define AUD2HTX_CTRE_WH_SHIFT 24
+#define AUD2HTX_CTRE_WH_WIDTH 5
+#define AUD2HTX_CTRE_WH_MASK ((BIT(AUD2HTX_CTRE_WH_WIDTH) - 1) \
+ << AUD2HTX_CTRE_WH_SHIFT)
+
+/* AUD2HTX IRQ Masks Register */
+#define AUD2HTX_WM_HIGH_IRQ_MASK BIT(2)
+#define AUD2HTX_WM_LOW_IRQ_MASK BIT(1)
+#define AUD2HTX_OVF_MASK BIT(0)
+
+#define AUD2HTX_FIFO_DEPTH 0x20
+#define AUD2HTX_WTMK_LOW 0x10
+#define AUD2HTX_WTMK_HIGH 0x10
+#define AUD2HTX_MAXBURST 0x10
+
+/**
+ * fsl_aud2htx: AUD2HTX private data
+ *
+ * @pdev: platform device pointer
+ * @regmap: regmap handler
+ * @bus_clk: clock source to access register
+ * @dma_params_rx: DMA parameters for receive channel
+ * @dma_params_tx: DMA parameters for transmit channel
+ */
+struct fsl_aud2htx {
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ struct clk *bus_clk;
+
+ struct snd_dmaengine_dai_dma_data dma_params_rx;
+ struct snd_dmaengine_dai_dma_data dma_params_tx;
+};
+
+#endif /* _FSL_AUD2HTX_H */
--
2.27.0
^ permalink raw reply related
* [PATCH v2 1/2] ASoC: dt-bindings: fsl_aud2htx: Add binding doc for aud2htx module
From: Shengjiu Wang @ 2020-10-28 9:38 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, perex, tiwai,
alsa-devel, lgirdwood, robh+dt, devicetree
Cc: linuxppc-dev, linux-kernel
AUD2HTX (Audio Subsystem TO HDMI TX Subsystem) is a new
IP module found on i.MX8MP.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
changes in v2:
- fix indentation issue
- remove nodename
.../bindings/sound/fsl,aud2htx.yaml | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
diff --git a/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml b/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
new file mode 100644
index 000000000000..6d9ba2946bfb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,aud2htx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Audio Subsystem to HDMI RTX Subsystem Controller
+
+maintainers:
+ - Shengjiu Wang <shengjiu.wang@nxp.com>
+
+properties:
+ compatible:
+ const: fsl,imx8mp-aud2htx
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Peripheral clock
+
+ clock-names:
+ items:
+ - const: bus
+
+ dmas:
+ items:
+ - description: DMA controller phandle and request line for TX
+
+ dma-names:
+ items:
+ - const: tx
+
+ power-domains:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - dmas
+ - dma-names
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/imx8mp-clock.h>
+
+ aud2htx: aud2htx@30cb0000 {
+ compatible = "fsl,imx8mp-aud2htx";
+ reg = <0x30cb0000 0x10000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
+ clock-names = "bus";
+ dmas = <&sdma2 26 2 0>;
+ dma-names = "tx";
+ power-domains = <&audiomix_pd>;
+ };
--
2.27.0
^ permalink raw reply related
* Re: [PATCH 2/4] PM: hibernate: improve robustness of mapping pages in the direct map
From: Mike Rapoport @ 2020-10-28 9:41 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: david@redhat.com, peterz@infradead.org, catalin.marinas@arm.com,
dave.hansen@linux.intel.com, linux-mm@kvack.org, paulus@samba.org,
pavel@ucw.cz, hpa@zytor.com, sparclinux@vger.kernel.org,
cl@linux.com, will@kernel.org, linux-riscv@lists.infradead.org,
linux-s390@vger.kernel.org, x86@kernel.org, rppt@linux.ibm.com,
borntraeger@de.ibm.com, mingo@redhat.com, rientjes@google.com,
Brown, Len, aou@eecs.berkeley.edu, gor@linux.ibm.com,
linux-pm@vger.kernel.org, hca@linux.ibm.com, bp@alien8.de,
luto@kernel.org, paul.walmsley@sifive.com, kirill@shutemov.name,
tglx@linutronix.de, iamjoonsoo.kim@lge.com,
linux-arm-kernel@lists.infradead.org, rjw@rjwysocki.net,
linux-kernel@vger.kernel.org, penberg@kernel.org,
palmer@dabbelt.com, akpm@linux-foundation.org,
linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
In-Reply-To: <ce66dcf2bbc17d40bcbe752868edb13976b3f1bb.camel@intel.com>
On Tue, Oct 27, 2020 at 10:44:21PM +0000, Edgecombe, Rick P wrote:
> On Tue, 2020-10-27 at 10:49 +0200, Mike Rapoport wrote:
> > On Mon, Oct 26, 2020 at 06:57:32PM +0000, Edgecombe, Rick P wrote:
> > > On Mon, 2020-10-26 at 11:15 +0200, Mike Rapoport wrote:
> > > > On Mon, Oct 26, 2020 at 12:38:32AM +0000, Edgecombe, Rick P
> > > > wrote:
> > > > > On Sun, 2020-10-25 at 12:15 +0200, Mike Rapoport wrote:
> > > > > > From: Mike Rapoport <rppt@linux.ibm.com>
> > > > > >
> > > > > > When DEBUG_PAGEALLOC or ARCH_HAS_SET_DIRECT_MAP is enabled a
> > > > > > page
> > > > > > may
> > > > > > be
> > > > > > not present in the direct map and has to be explicitly mapped
> > > > > > before
> > > > > > it
> > > > > > could be copied.
> > > > > >
> > > > > > On arm64 it is possible that a page would be removed from the
> > > > > > direct
> > > > > > map
> > > > > > using set_direct_map_invalid_noflush() but
> > > > > > __kernel_map_pages()
> > > > > > will
> > > > > > refuse
> > > > > > to map this page back if DEBUG_PAGEALLOC is disabled.
> > > > >
> > > > > It looks to me that arm64 __kernel_map_pages() will still
> > > > > attempt
> > > > > to
> > > > > map it if rodata_full is true, how does this happen?
> > > >
> > > > Unless I misread the code, arm64 requires both rodata_full and
> > > > debug_pagealloc_enabled() to be true for __kernel_map_pages() to
> > > > do
> > > > anything.
> > > > But rodata_full condition applies to set_direct_map_*_noflush()
> > > > as
> > > > well,
> > > > so with !rodata_full the linear map won't be ever changed.
> > >
> > > Hmm, looks to me that __kernel_map_pages() will only skip it if
> > > both
> > > debug pagealloc and rodata_full are false.
> > >
> > > But now I'm wondering if maybe we could simplify things by just
> > > moving
> > > the hibernate unmapped page logic off of the direct map. On x86,
> > > text_poke() used to use this reserved fixmap pte thing that it
> > > could
> > > rely on to remap memory with. If hibernate had some separate pte
> > > for
> > > remapping like that, then we could not have any direct map
> > > restrictions
> > > caused by it/kernel_map_pages(), and it wouldn't have to worry
> > > about
> > > relying on anything else.
> >
> > Well, there is map_kernel_range() that can be used by hibernation as
> > there is no requirement for particular virtual address, but that
> > would
> > be quite costly if done for every page.
> >
> > Maybe we can do somthing like
> >
> > if (kernel_page_present(s_page)) {
> > do_copy_page(dst, page_address(s_page));
> > } else {
> > map_kernel_range_noflush(page_address(page), PAGE_SIZE,
> > PROT_READ, &page);
> > do_copy_page(dst, page_address(s_page));
> > unmap_kernel_range_noflush(page_address(page),
> > PAGE_SIZE);
> > }
> >
> > But it seems that a prerequisite for changing the way a page is
> > mapped
> > in safe_copy_page() would be to teach hibernation that a mapping here
> > may fail.
> >
> Yea that is what I meant, the direct map could still be used for mapped
> pages.
>
> But for the unmapped case it could have a pre-setup 4k pte for some non
> direct map address. Then just change the pte to point to any unmapped
> direct map page that was encountered. The point would be to give
> hibernate some 4k pte of its own to manipulate so that it can't fail.
>
> Yet another option would be have hibernate_map_page() just map large
> pages if it finds them.
>
> So we could teach hibernate to handle mapping failures, OR we could
> change it so it doesn't rely on direct map page sizes in order to
> succeed. The latter seems better to me since there isn't a reason why
> it should have to fail and the resulting logic might be simpler. Both
> seem like improvements in robustness though.
That's correct, but as the purpose of this series is to prevent usage of
__kernel_map_pages() outside DEBUG_PAGALLOC, for now I'm going to update this
patch changelog and add a comment to hibernate_map_page().
--
Sincerely yours,
Mike.
^ permalink raw reply
* [PATCH] powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe()
From: Qinglang Miao @ 2020-10-28 9:15 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, linux-kernel, Qinglang Miao
I noticed that iounmap() of msgr_block_addr before return from
mpic_msgr_probe() in the error handling case is missing. So use
devm_ioremap() instead of just ioremap() when remapping the message
register block, so the mapping will be automatically released on
probe failure.
Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
---
arch/powerpc/sysdev/mpic_msgr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index f6b253e2b..36ec0bdd8 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -191,7 +191,7 @@ static int mpic_msgr_probe(struct platform_device *dev)
/* IO map the message register block. */
of_address_to_resource(np, 0, &rsrc);
- msgr_block_addr = ioremap(rsrc.start, resource_size(&rsrc));
+ msgr_block_addr = devm_ioremap(&dev->dev, rsrc.start, resource_size(&rsrc));
if (!msgr_block_addr) {
dev_err(&dev->dev, "Failed to iomap MPIC message registers");
return -EFAULT;
--
2.23.0
^ permalink raw reply related
* Re: [PATCH] powerpc: avoid broken GCC __attribute__((optimize))
From: Ard Biesheuvel @ 2020-10-28 8:29 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Daniel Borkmann, Josh Poimboeuf, Peter Zijlstra, Randy Dunlap,
Nick Desaulniers, Alexei Starovoitov, Arvind Sankar,
Paul Mackerras, Geert Uytterhoeven, Thomas Gleixner,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT), Kees Cook
In-Reply-To: <20201028080433.26799-1-ardb@kernel.org>
On Wed, 28 Oct 2020 at 09:04, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> Commit 7053f80d9696 ("powerpc/64: Prevent stack protection in early boot")
> introduced a couple of uses of __attribute__((optimize)) with function
> scope, to disable the stack protector in some early boot code.
>
> Unfortunately, and this is documented in the GCC man pages [0], overriding
> function attributes for optimization is broken, and is only supported for
> debug scenarios, not for production: the problem appears to be that
> setting GCC -f flags using this method will cause it to forget about some
> or all other optimization settings that have been applied.
>
> So the only safe way to disable the stack protector is to disable it for
> the entire source file.
>
> [0] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: Arvind Sankar <nivedita@alum.mit.edu>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Kees Cook <keescook@chromium.org>
> Fixes: 7053f80d9696 ("powerpc/64: Prevent stack protection in early boot")
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> Related discussion here:
> https://lore.kernel.org/lkml/CAMuHMdUg0WJHEcq6to0-eODpXPOywLot6UD2=GFHpzoj_hCoBQ@mail.gmail.com/
>
> TL;DR using __attribute__((optimize("-fno-gcse"))) in the BPF interpreter
> causes the compiler to forget about -fno-asynchronous-unwind-tables passed
> on the command line, resulting in unexpected .eh_frame sections in vmlinux.
>
> arch/powerpc/kernel/Makefile | 3 +++
> arch/powerpc/kernel/paca.c | 2 +-
> arch/powerpc/kernel/setup.h | 6 ------
> arch/powerpc/kernel/setup_64.c | 2 +-
> 4 files changed, 5 insertions(+), 8 deletions(-)
>
FYI i was notified by one of the robots that I missed one occurrence
of __nostackprotector in arch/powerpc/kernel/paca.c
Let me know if I need to resend.
> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
> index bf0bf1b900d2..fe2ef598e2ea 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -173,6 +173,9 @@ KCOV_INSTRUMENT_cputable.o := n
> KCOV_INSTRUMENT_setup_64.o := n
> KCOV_INSTRUMENT_paca.o := n
>
> +CFLAGS_setup_64.o += -fno-stack-protector
> +CFLAGS_paca.o += -fno-stack-protector
> +
> extra-$(CONFIG_PPC_FPU) += fpu.o
> extra-$(CONFIG_ALTIVEC) += vector.o
> extra-$(CONFIG_PPC64) += entry_64.o
> diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
> index 0ad15768d762..fe70834d7283 100644
> --- a/arch/powerpc/kernel/paca.c
> +++ b/arch/powerpc/kernel/paca.c
> @@ -208,7 +208,7 @@ static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
> struct paca_struct **paca_ptrs __read_mostly;
> EXPORT_SYMBOL(paca_ptrs);
>
> -void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu)
> +void __init initialise_paca(struct paca_struct *new_paca, int cpu)
> {
> #ifdef CONFIG_PPC_PSERIES
> new_paca->lppaca_ptr = NULL;
> diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
> index 2ec835574cc9..2dd0d9cb5a20 100644
> --- a/arch/powerpc/kernel/setup.h
> +++ b/arch/powerpc/kernel/setup.h
> @@ -8,12 +8,6 @@
> #ifndef __ARCH_POWERPC_KERNEL_SETUP_H
> #define __ARCH_POWERPC_KERNEL_SETUP_H
>
> -#ifdef CONFIG_CC_IS_CLANG
> -#define __nostackprotector
> -#else
> -#define __nostackprotector __attribute__((__optimize__("no-stack-protector")))
> -#endif
> -
> void initialize_cache_info(void);
> void irqstack_early_init(void);
>
> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index bb9cab3641d7..da447a62ea1e 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -283,7 +283,7 @@ void __init record_spr_defaults(void)
> * device-tree is not accessible via normal means at this point.
> */
>
> -void __init __nostackprotector early_setup(unsigned long dt_ptr)
> +void __init early_setup(unsigned long dt_ptr)
> {
> static __initdata struct paca_struct boot_paca;
>
> --
> 2.17.1
>
^ permalink raw reply
* [PATCH] powerpc: avoid broken GCC __attribute__((optimize))
From: Ard Biesheuvel @ 2020-10-28 8:04 UTC (permalink / raw)
To: linux-kernel
Cc: Daniel Borkmann, Josh Poimboeuf, Peter Zijlstra, Randy Dunlap,
Nick Desaulniers, Alexei Starovoitov, Arvind Sankar,
Paul Mackerras, Geert Uytterhoeven, Thomas Gleixner, linuxppc-dev,
Ard Biesheuvel, Kees Cook
Commit 7053f80d9696 ("powerpc/64: Prevent stack protection in early boot")
introduced a couple of uses of __attribute__((optimize)) with function
scope, to disable the stack protector in some early boot code.
Unfortunately, and this is documented in the GCC man pages [0], overriding
function attributes for optimization is broken, and is only supported for
debug scenarios, not for production: the problem appears to be that
setting GCC -f flags using this method will cause it to forget about some
or all other optimization settings that have been applied.
So the only safe way to disable the stack protector is to disable it for
the entire source file.
[0] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Kees Cook <keescook@chromium.org>
Fixes: 7053f80d9696 ("powerpc/64: Prevent stack protection in early boot")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
Related discussion here:
https://lore.kernel.org/lkml/CAMuHMdUg0WJHEcq6to0-eODpXPOywLot6UD2=GFHpzoj_hCoBQ@mail.gmail.com/
TL;DR using __attribute__((optimize("-fno-gcse"))) in the BPF interpreter
causes the compiler to forget about -fno-asynchronous-unwind-tables passed
on the command line, resulting in unexpected .eh_frame sections in vmlinux.
arch/powerpc/kernel/Makefile | 3 +++
arch/powerpc/kernel/paca.c | 2 +-
arch/powerpc/kernel/setup.h | 6 ------
arch/powerpc/kernel/setup_64.c | 2 +-
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index bf0bf1b900d2..fe2ef598e2ea 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -173,6 +173,9 @@ KCOV_INSTRUMENT_cputable.o := n
KCOV_INSTRUMENT_setup_64.o := n
KCOV_INSTRUMENT_paca.o := n
+CFLAGS_setup_64.o += -fno-stack-protector
+CFLAGS_paca.o += -fno-stack-protector
+
extra-$(CONFIG_PPC_FPU) += fpu.o
extra-$(CONFIG_ALTIVEC) += vector.o
extra-$(CONFIG_PPC64) += entry_64.o
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 0ad15768d762..fe70834d7283 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -208,7 +208,7 @@ static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
struct paca_struct **paca_ptrs __read_mostly;
EXPORT_SYMBOL(paca_ptrs);
-void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int cpu)
+void __init initialise_paca(struct paca_struct *new_paca, int cpu)
{
#ifdef CONFIG_PPC_PSERIES
new_paca->lppaca_ptr = NULL;
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
index 2ec835574cc9..2dd0d9cb5a20 100644
--- a/arch/powerpc/kernel/setup.h
+++ b/arch/powerpc/kernel/setup.h
@@ -8,12 +8,6 @@
#ifndef __ARCH_POWERPC_KERNEL_SETUP_H
#define __ARCH_POWERPC_KERNEL_SETUP_H
-#ifdef CONFIG_CC_IS_CLANG
-#define __nostackprotector
-#else
-#define __nostackprotector __attribute__((__optimize__("no-stack-protector")))
-#endif
-
void initialize_cache_info(void);
void irqstack_early_init(void);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index bb9cab3641d7..da447a62ea1e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -283,7 +283,7 @@ void __init record_spr_defaults(void)
* device-tree is not accessible via normal means at this point.
*/
-void __init __nostackprotector early_setup(unsigned long dt_ptr)
+void __init early_setup(unsigned long dt_ptr)
{
static __initdata struct paca_struct boot_paca;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 1/3] powerpc/uaccess: Switch __put_user_size_allowed() to __put_user_asm_goto()
From: Andreas Schwab @ 2020-10-28 7:59 UTC (permalink / raw)
To: Michael Ellerman; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <87pn53vsep.fsf@mpe.ellerman.id.au>
On Okt 28 2020, Michael Ellerman wrote:
> What config and compiler are you using?
gcc 4.9.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply
* [PATCH kernel v3 2/2] powerpc/dma: Fallback to dma_ops when persistent memory present
From: Alexey Kardashevskiy @ 2020-10-28 7:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexey Kardashevskiy, iommu, Christoph Hellwig, linux-kernel
In-Reply-To: <20201028070030.60643-1-aik@ozlabs.ru>
So far we have been using huge DMA windows to map all the RAM available.
The RAM is normally mapped to the VM address space contiguously, and
there is always a reasonable upper limit for possible future hot plugged
RAM which makes it easy to map all RAM via IOMMU.
Now there is persistent memory ("ibm,pmemory" in the FDT) which (unlike
normal RAM) can map anywhere in the VM space beyond the maximum RAM size
and since it can be used for DMA, it requires extending the huge window
up to MAX_PHYSMEM_BITS which requires hypervisor support for:
1. huge TCE tables;
2. multilevel TCE tables;
3. huge IOMMU pages.
Certain hypervisors cannot do either so the only option left is
restricting the huge DMA window to include only RAM and fallback to
the default DMA window for persistent memory.
This defines arch_dma_map_direct/etc to allow generic DMA code perform
additional checks on whether direct DMA is still possible.
This checks if the system has persistent memory. If it does not,
the DMA bypass mode is selected, i.e.
* dev->bus_dma_limit = 0
* dev->dma_ops_bypass = true <- this avoid calling dma_ops for mapping.
If there is such memory, this creates identity mapping only for RAM and
sets the dev->bus_dma_limit to let the generic code decide whether to
call into the direct DMA or the indirect DMA ops.
This should not change the existing behaviour when no persistent memory
as dev->dma_ops_bypass is expected to be set.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
arch/powerpc/kernel/dma-iommu.c | 70 +++++++++++++++++++++++++-
arch/powerpc/platforms/pseries/iommu.c | 44 ++++++++++++----
arch/powerpc/Kconfig | 1 +
3 files changed, 103 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index a1c744194018..21e2d9f059a9 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -10,6 +10,63 @@
#include <linux/pci.h>
#include <asm/iommu.h>
+#define can_map_direct(dev, addr) \
+ ((dev)->bus_dma_limit >= phys_to_dma((dev), (addr)))
+
+bool arch_dma_map_page_direct(struct device *dev, phys_addr_t addr)
+{
+ if (likely(!dev->bus_dma_limit))
+ return false;
+
+ return can_map_direct(dev, addr);
+}
+EXPORT_SYMBOL_GPL(arch_dma_map_page_direct);
+
+#define is_direct_handle(dev, h) ((h) >= (dev)->archdata.dma_offset)
+
+bool arch_dma_unmap_page_direct(struct device *dev, dma_addr_t dma_handle)
+{
+ if (likely(!dev->bus_dma_limit))
+ return false;
+
+ return is_direct_handle(dev, dma_handle);
+}
+EXPORT_SYMBOL_GPL(arch_dma_unmap_page_direct);
+
+bool arch_dma_map_sg_direct(struct device *dev, struct scatterlist *sg, int nents)
+{
+ struct scatterlist *s;
+ int i;
+
+ if (likely(!dev->bus_dma_limit))
+ return false;
+
+ for_each_sg(sg, s, nents, i) {
+ if (!can_map_direct(dev, sg_phys(s) + s->offset + s->length))
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(arch_dma_map_sg_direct);
+
+bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg, int nents)
+{
+ struct scatterlist *s;
+ int i;
+
+ if (likely(!dev->bus_dma_limit))
+ return false;
+
+ for_each_sg(sg, s, nents, i) {
+ if (!is_direct_handle(dev, s->dma_address + s->length))
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(arch_dma_unmap_sg_direct);
+
/*
* Generic iommu implementation
*/
@@ -90,8 +147,17 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
struct iommu_table *tbl = get_iommu_table_base(dev);
if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) {
- dev->dma_ops_bypass = true;
- dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
+ /*
+ * dma_iommu_bypass_supported() sets dma_max when there is
+ * 1:1 mapping but it is somehow limited.
+ * ibm,pmemory is one example.
+ */
+ dev->dma_ops_bypass = dev->bus_dma_limit == 0;
+ if (!dev->dma_ops_bypass)
+ dev_warn(dev, "iommu: 64-bit OK but direct DMA is limited by %llx\n",
+ dev->bus_dma_limit);
+ else
+ dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
return 1;
}
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index e4198700ed1a..91112e748491 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -839,7 +839,7 @@ static void remove_ddw(struct device_node *np, bool remove_prop)
np, ret);
}
-static u64 find_existing_ddw(struct device_node *pdn)
+static u64 find_existing_ddw(struct device_node *pdn, int *window_shift)
{
struct direct_window *window;
const struct dynamic_dma_window_prop *direct64;
@@ -851,6 +851,7 @@ static u64 find_existing_ddw(struct device_node *pdn)
if (window->device == pdn) {
direct64 = window->prop;
dma_addr = be64_to_cpu(direct64->dma_base);
+ *window_shift = be32_to_cpu(direct64->window_shift);
break;
}
}
@@ -1111,11 +1112,13 @@ static void reset_dma_window(struct pci_dev *dev, struct device_node *par_dn)
*/
static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
{
- int len, ret;
+ int len = 0, ret;
+ bool pmem_present = of_find_node_by_type(NULL, "ibm,pmemory") != NULL;
+ int max_ram_len = order_base_2(ddw_memory_hotplug_max());
struct ddw_query_response query;
struct ddw_create_response create;
int page_shift;
- u64 dma_addr, max_addr;
+ u64 dma_addr;
struct device_node *dn;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
struct direct_window *window;
@@ -1126,7 +1129,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
mutex_lock(&direct_window_init_mutex);
- dma_addr = find_existing_ddw(pdn);
+ dma_addr = find_existing_ddw(pdn, &len);
if (dma_addr != 0)
goto out_unlock;
@@ -1212,14 +1215,26 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
}
/* verify the window * number of ptes will map the partition */
/* check largest block * page size > max memory hotplug addr */
- max_addr = ddw_memory_hotplug_max();
- if (query.largest_available_block < (max_addr >> page_shift)) {
- dev_dbg(&dev->dev, "can't map partition max 0x%llx with %llu "
- "%llu-sized pages\n", max_addr, query.largest_available_block,
- 1ULL << page_shift);
+ /*
+ * The "ibm,pmemory" can appear anywhere in the address space.
+ * Assuming it is still backed by page structs, try MAX_PHYSMEM_BITS
+ * for the upper limit and fallback to max RAM otherwise but this
+ * disables device::dma_ops_bypass.
+ */
+ len = max_ram_len;
+ if (pmem_present) {
+ if (query.largest_available_block >=
+ (1ULL << (MAX_PHYSMEM_BITS - page_shift)))
+ len = MAX_PHYSMEM_BITS - page_shift;
+ else
+ dev_info(&dev->dev, "Skipping ibm,pmemory");
+ }
+
+ if (query.largest_available_block < (1ULL << (len - page_shift))) {
+ dev_dbg(&dev->dev, "can't map partition max 0x%llx with %llu %llu-sized pages\n",
+ 1ULL << len, query.largest_available_block, 1ULL << page_shift);
goto out_failed;
}
- len = order_base_2(max_addr);
win64 = kzalloc(sizeof(struct property), GFP_KERNEL);
if (!win64) {
dev_info(&dev->dev,
@@ -1299,6 +1314,15 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
out_unlock:
mutex_unlock(&direct_window_init_mutex);
+
+ /*
+ * If we have persistent memory and the window size is only as big
+ * as RAM, then we failed to create a window to cover persistent
+ * memory and need to set the DMA limit.
+ */
+ if (pmem_present && dma_addr && (len == max_ram_len))
+ dev->dev.bus_dma_limit = dma_addr + (1ULL << len);
+
return dma_addr;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e9f13fe08492..b2d4580acf79 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -159,6 +159,7 @@ config PPC
select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN
select DMA_OPS if PPC64
select DMA_OPS_BYPASS if PPC64
+ select ARCH_HAS_DMA_MAP_DIRECT if PPC64 && PPC_PSERIES
select DYNAMIC_FTRACE if FUNCTION_TRACER
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
--
2.17.1
^ permalink raw reply related
* [PATCH kernel v3 0/2] DMA, powerpc/dma: Fallback to dma_ops when persistent memory present
From: Alexey Kardashevskiy @ 2020-10-28 7:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexey Kardashevskiy, iommu, Christoph Hellwig, linux-kernel
This allows mixing direct DMA (to/from RAM) and
IOMMU (to/from apersistent memory) on the PPC64/pseries
platform.
This replaces https://lkml.org/lkml/2020/10/27/418
which replaces https://lkml.org/lkml/2020/10/20/1085
This is based on sha1
4525c8781ec0 Linus Torvalds "scsi: qla2xxx: remove incorrect sparse #ifdef".
Please comment. Thanks.
Alexey Kardashevskiy (2):
dma: Allow mixing bypass and mapped DMA operation
powerpc/dma: Fallback to dma_ops when persistent memory present
arch/powerpc/kernel/dma-iommu.c | 70 +++++++++++++++++++++++++-
arch/powerpc/platforms/pseries/iommu.c | 44 ++++++++++++----
kernel/dma/mapping.c | 24 +++++++--
arch/powerpc/Kconfig | 1 +
kernel/dma/Kconfig | 4 ++
5 files changed, 127 insertions(+), 16 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH kernel v3 1/2] dma: Allow mixing bypass and mapped DMA operation
From: Alexey Kardashevskiy @ 2020-10-28 7:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexey Kardashevskiy, iommu, Christoph Hellwig, linux-kernel
In-Reply-To: <20201028070030.60643-1-aik@ozlabs.ru>
At the moment we allow bypassing DMA ops only when we can do this for
the entire RAM. However there are configs with mixed type memory
where we could still allow bypassing IOMMU in most cases;
POWERPC with persistent memory is one example.
This adds an arch hook to determine where bypass can still work and
we invoke direct DMA API. The following patch checks the bus limit
on POWERPC to allow or disallow direct mapping.
This adds a CONFIG_ARCH_HAS_DMA_SET_MASK config option to make arch_xxxx
hooks no-op by default.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
kernel/dma/mapping.c | 24 ++++++++++++++++++++----
kernel/dma/Kconfig | 4 ++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 51bb8fa8eb89..a0bc9eb876ed 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -137,6 +137,18 @@ static inline bool dma_map_direct(struct device *dev,
return dma_go_direct(dev, *dev->dma_mask, ops);
}
+#ifdef CONFIG_ARCH_HAS_DMA_MAP_DIRECT
+bool arch_dma_map_page_direct(struct device *dev, phys_addr_t addr);
+bool arch_dma_unmap_page_direct(struct device *dev, dma_addr_t dma_handle);
+bool arch_dma_map_sg_direct(struct device *dev, struct scatterlist *sg, int nents);
+bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg, int nents);
+#else
+#define arch_dma_map_page_direct(d, a) (0)
+#define arch_dma_unmap_page_direct(d, a) (0)
+#define arch_dma_map_sg_direct(d, s, n) (0)
+#define arch_dma_unmap_sg_direct(d, s, n) (0)
+#endif
+
dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page,
size_t offset, size_t size, enum dma_data_direction dir,
unsigned long attrs)
@@ -149,7 +161,8 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page,
if (WARN_ON_ONCE(!dev->dma_mask))
return DMA_MAPPING_ERROR;
- if (dma_map_direct(dev, ops))
+ if (dma_map_direct(dev, ops) ||
+ arch_dma_map_page_direct(dev, page_to_phys(page) + offset + size))
addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
else
addr = ops->map_page(dev, page, offset, size, dir, attrs);
@@ -165,7 +178,8 @@ void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size,
const struct dma_map_ops *ops = get_dma_ops(dev);
BUG_ON(!valid_dma_direction(dir));
- if (dma_map_direct(dev, ops))
+ if (dma_map_direct(dev, ops) ||
+ arch_dma_unmap_page_direct(dev, addr + size))
dma_direct_unmap_page(dev, addr, size, dir, attrs);
else if (ops->unmap_page)
ops->unmap_page(dev, addr, size, dir, attrs);
@@ -188,7 +202,8 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents,
if (WARN_ON_ONCE(!dev->dma_mask))
return 0;
- if (dma_map_direct(dev, ops))
+ if (dma_map_direct(dev, ops) ||
+ arch_dma_map_sg_direct(dev, sg, nents))
ents = dma_direct_map_sg(dev, sg, nents, dir, attrs);
else
ents = ops->map_sg(dev, sg, nents, dir, attrs);
@@ -207,7 +222,8 @@ void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
BUG_ON(!valid_dma_direction(dir));
debug_dma_unmap_sg(dev, sg, nents, dir);
- if (dma_map_direct(dev, ops))
+ if (dma_map_direct(dev, ops) ||
+ arch_dma_unmap_sg_direct(dev, sg, nents))
dma_direct_unmap_sg(dev, sg, nents, dir, attrs);
else if (ops->unmap_sg)
ops->unmap_sg(dev, sg, nents, dir, attrs);
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index c99de4a21458..43d106598e82 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -20,6 +20,10 @@ config DMA_OPS
config DMA_OPS_BYPASS
bool
+# Lets platform IOMMU driver choose between bypass and IOMMU
+config ARCH_HAS_DMA_MAP_DIRECT
+ bool
+
config NEED_SG_DMA_LENGTH
bool
--
2.17.1
^ permalink raw reply related
* Re: [PATCH kernel v2 1/2] dma: Allow mixing bypass and normal IOMMU operation
From: Alexey Kardashevskiy @ 2020-10-28 6:55 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: iommu, linuxppc-dev, linux-kernel
In-Reply-To: <20201027164858.GA30651@lst.de>
On 28/10/2020 03:48, Christoph Hellwig wrote:
>> +static inline bool dma_handle_direct(struct device *dev, dma_addr_t dma_handle)
>> +{
>> + return dma_handle >= dev->archdata.dma_offset;
>> +}
>
> This won't compile except for powerpc, and directly accesing arch members
> in common code is a bad idea. Maybe both your helpers need to be
> supplied by arch code to better abstract this out.
rats, overlooked it :( bus_dma_limit is generic but dma_offset is in
archdata :-/
>
>> if (dma_map_direct(dev, ops))
>> addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
>> +#ifdef CONFIG_DMA_OPS_BYPASS_BUS_LIMIT
>> + else if (dev->bus_dma_limit &&
>> + can_map_direct(dev, (phys_addr_t) page_to_phys(page) + offset + size))
>> + addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
>> +#endif
>
> I don't think page_to_phys needs a phys_addr_t on the return value.
> I'd also much prefer if we make this a little more beautiful, here
> are a few suggestions:
>
> - hide the bus_dma_limit check inside can_map_direct, and provide a
> stub so that we can avoid the ifdef
> - use a better name for can_map_direct, and maybe also a better calling
> convention by passing the page (the sg code also has the page),
It is passing an address of the end of the mapped area so passing a page
struct means passing page and offset which is an extra parameter and we
do not want to do anything with the page in those hooks anyway so I'd
keep it as is.
> and
> maybe even hide the dma_map_direct inside it.
Call dma_map_direct() from arch_dma_map_page_direct() if
arch_dma_map_page_direct() is defined? Seems suboptimal as it is going
to be bypass=true in most cases and we save one call by avoiding calling
arch_dma_map_page_direct(). Unless I missed something?
>
> if (dma_map_direct(dev, ops) ||
> arch_dma_map_page_direct(dev, page, offset, size))
> addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
>
>> BUG_ON(!valid_dma_direction(dir));
>> if (dma_map_direct(dev, ops))
>> dma_direct_unmap_page(dev, addr, size, dir, attrs);
>> +#ifdef CONFIG_DMA_OPS_BYPASS_BUS_LIMIT
>> + else if (dev->bus_dma_limit && dma_handle_direct(dev, addr + size))
>> + dma_direct_unmap_page(dev, addr, size, dir, attrs);
>> +#endif
>
> Same here.
>
>> if (dma_map_direct(dev, ops))
>> ents = dma_direct_map_sg(dev, sg, nents, dir, attrs);
>> +#ifdef CONFIG_DMA_OPS_BYPASS_BUS_LIMIT
>> + else if (dev->bus_dma_limit) {
>> + struct scatterlist *s;
>> + bool direct = true;
>> + int i;
>> +
>> + for_each_sg(sg, s, nents, i) {
>> + direct = can_map_direct(dev, sg_phys(s) + s->offset + s->length);
>> + if (!direct)
>> + break;
>> + }
>> + if (direct)
>> + ents = dma_direct_map_sg(dev, sg, nents, dir, attrs);
>> + else
>> + ents = ops->map_sg(dev, sg, nents, dir, attrs);
>> + }
>> +#endif
>
> This needs to go into a helper as well. I think the same style as
> above would work pretty nicely as well:
Yup. I'll repost v3 soon with this change. Thanks for the review.
>
> if (dma_map_direct(dev, ops) ||
> arch_dma_map_sg_direct(dev, sg, nents))
> ents = dma_direct_map_sg(dev, sg, nents, dir, attrs);
> else
> ents = ops->map_sg(dev, sg, nents, dir, attrs);
>
>> +#ifdef CONFIG_DMA_OPS_BYPASS_BUS_LIMIT
>> + if (dev->bus_dma_limit) {
>> + struct scatterlist *s;
>> + bool direct = true;
>> + int i;
>> +
>> + for_each_sg(sg, s, nents, i) {
>> + direct = dma_handle_direct(dev, s->dma_address + s->length);
>> + if (!direct)
>> + break;
>> + }
>> + if (direct) {
>> + dma_direct_unmap_sg(dev, sg, nents, dir, attrs);
>> + return;
>> + }
>> + }
>> +#endif
>
> One more time here..
>
--
Alexey
^ permalink raw reply
* Re: [PATCH] ibmvscsi: fix race potential race after loss of transport
From: Michael Ellerman @ 2020-10-28 5:21 UTC (permalink / raw)
To: Tyrel Datwyler, james.bottomley
Cc: Tyrel Datwyler, martin.petersen, linux-scsi, linux-kernel, brking,
linuxppc-dev
In-Reply-To: <20201025001355.4527-1-tyreld@linux.ibm.com>
Tyrel Datwyler <tyreld@linux.ibm.com> writes:
> After a loss of tranport due to an adatper migration or crash/disconnect from
> the host partner there is a tiny window where we can race adjusting the
> request_limit of the adapter. The request limit is atomically inc/dec to track
> the number of inflight requests against the allowed limit of our VIOS partner.
> After a transport loss we set the request_limit to zero to reflect this state.
> However, there is a window where the adapter may attempt to queue a command
> because the transport loss event hasn't been fully processed yet and
> request_limit is still greater than zero. The hypercall to send the event will
> fail and the error path will increment the request_limit as a result. If the
> adapter processes the transport event prior to this increment the request_limit
> becomes out of sync with the adapter state and can result in scsi commands being
> submitted on the now reset connection prior to an SRP Login resulting in a
> protocol violation.
>
> Fix this race by protecting request_limit with the host lock when changing the
> value via atomic_set() to indicate no transport.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
> ---
> drivers/scsi/ibmvscsi/ibmvscsi.c | 36 +++++++++++++++++++++++---------
> 1 file changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
> index b1f3017b6547..188ed75417a5 100644
> --- a/drivers/scsi/ibmvscsi/ibmvscsi.c
> +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
> @@ -806,6 +806,22 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
> spin_unlock_irqrestore(hostdata->host->host_lock, flags);
> }
>
> +/**
> + * ibmvscsi_set_request_limit - Set the adapter request_limit in response to
> + * an adapter failure, reset, or SRP Login. Done under host lock to prevent
> + * race with scsi command submission.
> + * @hostdata: adapter to adjust
> + * @limit: new request limit
> + */
> +static void ibmvscsi_set_request_limit(struct ibmvscsi_host_data *hostdata, int limit)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(hostdata->host->host_lock, flags);
> + atomic_set(&hostdata->request_limit, limit);
> + spin_unlock_irqrestore(hostdata->host->host_lock, flags);
> +}
> +
> /**
> * ibmvscsi_reset_host - Reset the connection to the server
> * @hostdata: struct ibmvscsi_host_data to reset
...
> @@ -2137,12 +2153,12 @@ static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata)
> }
>
> hostdata->action = IBMVSCSI_HOST_ACTION_NONE;
> + spin_unlock_irqrestore(hostdata->host->host_lock, flags);
You drop the lock ...
> if (rc) {
> - atomic_set(&hostdata->request_limit, -1);
> + ibmvscsi_set_request_limit(hostdata, -1);
.. then retake it, then drop it again in ibmvscsi_set_request_limit().
Which introduces the possibility that something else gets the lock
before you can set the limit to -1.
I'm not sure that's a bug, but it's not obviously correct either?
cheers
> dev_err(hostdata->dev, "error after %s\n", action);
> }
> - spin_unlock_irqrestore(hostdata->host->host_lock, flags);
>
> scsi_unblock_requests(hostdata->host);
> }
^ permalink raw reply
* Re: [PATCH 1/2] ASoC: dt-bindings: fsl_aud2htx: Add binding doc for aud2htx module
From: Shengjiu Wang @ 2020-10-28 5:20 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
alsa-devel, Timur Tabi, Xiubo Li, Fabio Estevam, Shengjiu Wang,
Liam Girdwood, Takashi Iwai, Nicolin Chen, Rob Herring,
Mark Brown, linuxppc-dev, linux-kernel
In-Reply-To: <20201027110840.GA23076@kozik-lap>
On Tue, Oct 27, 2020 at 7:09 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Mon, Oct 26, 2020 at 06:40:54PM +0800, Shengjiu Wang wrote:
> > AUD2HTX (Audio Subsystem TO HDMI TX Subsystem) is a new
> > IP module found on i.MX8MP.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> > ---
> > .../bindings/sound/fsl,aud2htx.yaml | 67 +++++++++++++++++++
> > 1 file changed, 67 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml b/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
> > new file mode 100644
> > index 000000000000..18548d0889a8
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/fsl,aud2htx.yaml
> > @@ -0,0 +1,67 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/sound/fsl,aud2htx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NXP Audio Subsystem to HDMI RTX Subsystem Controller
> > +
> > +maintainers:
> > + - Shengjiu Wang <shengjiu.wang@nxp.com>
> > +
> > +properties:
> > + $nodename:
> > + pattern: "^aud2htx@.*"
>
> aud2htx is not a generic class of a device so it should not be enforced.
>
> > +
> > + compatible:
> > + const: fsl,imx8mp-aud2htx
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + clocks:
> > + items:
> > + - description: Peripheral clock
> > +
> > + clock-names:
> > + items:
> > + - const: bus
> > +
> > + dmas:
> > + items:
> > + - description: DMA controller phandle and request line for TX
> > +
> > + dma-names:
> > + items:
> > + - const: tx
> > +
> > + power-domains:
> > + maxItems: 1
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - interrupts
> > + - clocks
> > + - clock-names
> > + - dmas
> > + - dma-names
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/interrupt-controller/arm-gic.h>
> > + #include <dt-bindings/clock/imx8mp-clock.h>
> > +
> > + aud2htx: aud2htx@30cb0000 {
> > + compatible = "fsl,imx8mp-aud2htx";
>
> Wrong indentation. Most of examples are indented with 4 spaces.
>
ok, I will update it.
best regards
wang shengjiu
^ permalink raw reply
* Re: [PATCH 1/3] powerpc/uaccess: Switch __put_user_size_allowed() to __put_user_asm_goto()
From: Michael Ellerman @ 2020-10-28 5:19 UTC (permalink / raw)
To: Andreas Schwab, Christophe Leroy
Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <87imav9r64.fsf@igel.home>
Andreas Schwab <schwab@linux-m68k.org> writes:
> On Okt 28 2020, Andreas Schwab wrote:
>
>> On Sep 04 2020, Christophe Leroy wrote:
>>
>>> __put_user_asm_goto() provides more flexibility to GCC and avoids using
>>> a local variable to tell if the write succeeded or not.
>>> GCC can then avoid implementing a cmp in the fast path.
>>
>> That breaks CLONE_CHILD_SETTID. I'm getting an assertion failure in
>> __libc_fork (THREAD_GETMEM (self, tid) != ppid).
>
> This is what schedule_tail now looks like. As you can see, put_user has
> become a nop:
>
> 000000000000455c <.schedule_tail>:
> 455c: 7c 08 02 a6 mflr r0
> 4560: f8 01 00 10 std r0,16(r1)
> 4564: f8 21 ff 91 stdu r1,-112(r1)
> 4568: 4b ff cd 4d bl 12b4 <.finish_task_switch>
> 456c: 4b ff c0 99 bl 604 <.balance_callback>
> 4570: e8 6d 01 88 ld r3,392(r13)
> 4574: e9 23 06 b0 ld r9,1712(r3)
> 4578: 2f a9 00 00 cmpdi cr7,r9,0
> 457c: 41 9e 00 14 beq cr7,4590 <.schedule_tail+0x34>
> 4580: 38 80 00 00 li r4,0
> 4584: 38 a0 00 00 li r5,0
> 4588: 48 00 00 01 bl 4588 <.schedule_tail+0x2c>
> 4588: R_PPC64_REL24 .__task_pid_nr_ns
> 458c: 60 00 00 00 nop
> 4590: 48 00 00 01 bl 4590 <.schedule_tail+0x34>
> 4590: R_PPC64_REL24 .calculate_sigpending
> 4594: 60 00 00 00 nop
> 4598: 38 21 00 70 addi r1,r1,112
> 459c: e8 01 00 10 ld r0,16(r1)
> 45a0: 7c 08 03 a6 mtlr r0
> 45a4: 4e 80 00 20 blr
Not for me, see below.
What config and compiler are you using?
cheers
c000000000181aa0 <schedule_tail>:
c000000000181aa0: 82 01 4c 3c addis r2,r12,386
c000000000181aa4: 60 1b 42 38 addi r2,r2,7008
c000000000181aa8: a6 02 08 7c mflr r0
c000000000181aac: cd b5 ee 4b bl c00000000006d078 <_mcount>
c000000000181ab0: a6 02 08 7c mflr r0
c000000000181ab4: f8 ff e1 fb std r31,-8(r1)
c000000000181ab8: 10 00 01 f8 std r0,16(r1)
c000000000181abc: d1 ff 21 f8 stdu r1,-48(r1)
c000000000181ac0: c9 7d ff 4b bl c000000000179888 <finish_task_switch+0x8>
c000000000181ac4: 40 0a 23 e9 ld r9,2624(r3)
c000000000181ac8: 00 00 a9 2f cmpdi cr7,r9,0
c000000000181acc: b4 00 9e 40 bne cr7,c000000000181b80 <schedule_tail+0xe0>
c000000000181ad0: 68 09 6d e8 ld r3,2408(r13)
c000000000181ad4: 48 07 e3 eb ld r31,1864(r3)
c000000000181ad8: 00 00 bf 2f cmpdi cr7,r31,0
c000000000181adc: 88 00 9e 41 beq cr7,c000000000181b64 <schedule_tail+0xc4>
c000000000181ae0: 00 00 a0 38 li r5,0
c000000000181ae4: 00 00 80 38 li r4,0
c000000000181ae8: 21 4b fe 4b bl c000000000166608 <__task_pid_nr_ns+0x8>
c000000000181aec: 00 00 00 60 nop
c000000000181af0: ff ff 20 39 li r9,-1
c000000000181af4: 00 03 29 79 clrldi r9,r9,12
c000000000181af8: 40 48 bf 7f cmpld cr7,r31,r9
c000000000181afc: 68 00 9d 41 bgt cr7,c000000000181b64 <schedule_tail+0xc4>
c000000000181b00: 01 00 29 39 addi r9,r9,1
c000000000181b04: 50 48 3f 7d subf r9,r31,r9
c000000000181b08: 03 00 a9 2b cmpldi cr7,r9,3
c000000000181b0c: 58 00 9d 40 ble cr7,c000000000181b64 <schedule_tail+0xc4>
c000000000181b10: 02 00 42 3d addis r10,r2,2
c000000000181b14: 18 25 4a 39 addi r10,r10,9496
c000000000181b18: 00 00 2a e9 ld r9,0(r10)
c000000000181b1c: 22 00 29 e9 lwa r9,32(r9)
c000000000181b20: 00 00 89 2f cmpwi cr7,r9,0
c000000000181b24: 24 00 9c 40 bge cr7,c000000000181b48 <schedule_tail+0xa8>
c000000000181b28: 2c 01 00 4c isync
c000000000181b2c: 00 40 20 3d lis r9,16384
c000000000181b30: c6 07 29 79 rldicr r9,r9,32,31
c000000000181b34: a6 03 3d 7d mtspr 29,r9 # put_user() begins here
c000000000181b38: 2c 01 00 4c isync
c000000000181b3c: 00 00 2a e9 ld r9,0(r10)
c000000000181b40: 22 00 29 e9 lwa r9,32(r9)
c000000000181b44: 00 00 89 2f cmpwi cr7,r9,0
c000000000181b48: 00 00 7f 90 stw r3,0(r31)
c000000000181b4c: 18 00 9c 40 bge cr7,c000000000181b64 <schedule_tail+0xc4>
c000000000181b50: 2c 01 00 4c isync
c000000000181b54: ff ff 20 39 li r9,-1
c000000000181b58: 44 00 29 79 rldicr r9,r9,0,1
c000000000181b5c: a6 03 3d 7d mtspr 29,r9
c000000000181b60: 2c 01 00 4c isync
c000000000181b64: b5 c9 fc 4b bl c00000000014e518 <calculate_sigpending+0x8>
c000000000181b68: 00 00 00 60 nop
c000000000181b6c: 30 00 21 38 addi r1,r1,48
c000000000181b70: 10 00 01 e8 ld r0,16(r1)
c000000000181b74: f8 ff e1 eb ld r31,-8(r1)
c000000000181b78: a6 03 08 7c mtlr r0
c000000000181b7c: 20 00 80 4e blr
c000000000181b80: 39 40 ff 4b bl c000000000175bb8 <__balance_callback+0x8>
c000000000181b84: 4c ff ff 4b b c000000000181ad0 <schedule_tail+0x30>
^ permalink raw reply
* Re: [PATCH] ibmveth: Fix use of ibmveth in a bridge.
From: Jakub Kicinski @ 2020-10-28 0:54 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Cristobal Forno, netdev, linux-kernel, Paul Mackerras,
Michal Suchanek, linuxppc-dev, David S. Miller, Cris Forno
In-Reply-To: <20201026200407.fcf43678ba4cef7fe0cb7c98@suse.de>
On Mon, 26 Oct 2020 20:04:07 +0100 Thomas Bogendoerfer wrote:
> > On Mon, 26 Oct 2020 11:42:21 +0100 Michal Suchanek wrote:
> > > From: Thomas Bogendoerfer <tbogendoerfer@suse.de>
> > >
> > > The check for src mac address in ibmveth_is_packet_unsupported is wrong.
> > > Commit 6f2275433a2f wanted to shut down messages for loopback packets,
> > > but now suppresses bridged frames, which are accepted by the hypervisor
> > > otherwise bridging won't work at all.
> > >
> > > Fixes: 6f2275433a2f ("ibmveth: Detect unsupported packets before sending to the hypervisor")
> > > Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> >
> > Since the From: line says Thomas we need a signoff from him.
>
> you can add
>
> Signed-off-by: tbogendoerfer@suse.de
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 1/3] powerpc/uaccess: Switch __put_user_size_allowed() to __put_user_asm_goto()
From: Andreas Schwab @ 2020-10-27 23:37 UTC (permalink / raw)
To: Christophe Leroy; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <87mu079ron.fsf@igel.home>
On Okt 28 2020, Andreas Schwab wrote:
> On Sep 04 2020, Christophe Leroy wrote:
>
>> __put_user_asm_goto() provides more flexibility to GCC and avoids using
>> a local variable to tell if the write succeeded or not.
>> GCC can then avoid implementing a cmp in the fast path.
>
> That breaks CLONE_CHILD_SETTID. I'm getting an assertion failure in
> __libc_fork (THREAD_GETMEM (self, tid) != ppid).
This is what schedule_tail now looks like. As you can see, put_user has
become a nop:
000000000000455c <.schedule_tail>:
455c: 7c 08 02 a6 mflr r0
4560: f8 01 00 10 std r0,16(r1)
4564: f8 21 ff 91 stdu r1,-112(r1)
4568: 4b ff cd 4d bl 12b4 <.finish_task_switch>
456c: 4b ff c0 99 bl 604 <.balance_callback>
4570: e8 6d 01 88 ld r3,392(r13)
4574: e9 23 06 b0 ld r9,1712(r3)
4578: 2f a9 00 00 cmpdi cr7,r9,0
457c: 41 9e 00 14 beq cr7,4590 <.schedule_tail+0x34>
4580: 38 80 00 00 li r4,0
4584: 38 a0 00 00 li r5,0
4588: 48 00 00 01 bl 4588 <.schedule_tail+0x2c>
4588: R_PPC64_REL24 .__task_pid_nr_ns
458c: 60 00 00 00 nop
4590: 48 00 00 01 bl 4590 <.schedule_tail+0x34>
4590: R_PPC64_REL24 .calculate_sigpending
4594: 60 00 00 00 nop
4598: 38 21 00 70 addi r1,r1,112
459c: e8 01 00 10 ld r0,16(r1)
45a0: 7c 08 03 a6 mtlr r0
45a4: 4e 80 00 20 blr
This is schedule_tail in 5.9:
000000000000455c <.schedule_tail>:
455c: 7c 08 02 a6 mflr r0
4560: fb c1 ff f0 std r30,-16(r1)
4564: fb e1 ff f8 std r31,-8(r1)
4568: f8 01 00 10 std r0,16(r1)
456c: f8 21 ff 81 stdu r1,-128(r1)
4570: 4b ff cd 45 bl 12b4 <.finish_task_switch>
4574: 4b ff c0 91 bl 604 <.balance_callback>
4578: eb cd 01 88 ld r30,392(r13)
457c: eb fe 06 b0 ld r31,1712(r30)
4580: 2f bf 00 00 cmpdi cr7,r31,0
4584: 41 9e 00 2c beq cr7,45b0 <.schedule_tail+0x54>
4588: 7f c3 f3 78 mr r3,r30
458c: 38 80 00 00 li r4,0
4590: 38 a0 00 00 li r5,0
4594: 48 00 00 01 bl 4594 <.schedule_tail+0x38>
4594: R_PPC64_REL24 .__task_pid_nr_ns
4598: 60 00 00 00 nop
459c: e9 3e 0a b8 ld r9,2744(r30)
45a0: 7f bf 48 40 cmpld cr7,r31,r9
45a4: 41 9d 00 0c bgt cr7,45b0 <.schedule_tail+0x54>
45a8: 2b a9 00 03 cmpldi cr7,r9,3
45ac: 41 9d 00 14 bgt cr7,45c0 <.schedule_tail+0x64>
45b0: 48 00 00 01 bl 45b0 <.schedule_tail+0x54>
45b0: R_PPC64_REL24 .calculate_sigpending
45b4: 60 00 00 00 nop
45b8: 38 21 00 80 addi r1,r1,128
45bc: 48 00 00 00 b 45bc <.schedule_tail+0x60>
45bc: R_PPC64_REL24 _restgpr0_30
45c0: 39 20 00 00 li r9,0
45c4: 90 7f 00 00 stw r3,0(r31)
45c8: 4b ff ff e8 b 45b0 <.schedule_tail+0x54>
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH 1/3] powerpc/uaccess: Switch __put_user_size_allowed() to __put_user_asm_goto()
From: Andreas Schwab @ 2020-10-27 23:26 UTC (permalink / raw)
To: Christophe Leroy; +Cc: Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <94ba5a5138f99522e1562dbcdb38d31aa790dc89.1599216721.git.christophe.leroy__44535.5968013004$1599217383$gmane$org@csgroup.eu>
On Sep 04 2020, Christophe Leroy wrote:
> __put_user_asm_goto() provides more flexibility to GCC and avoids using
> a local variable to tell if the write succeeded or not.
> GCC can then avoid implementing a cmp in the fast path.
That breaks CLONE_CHILD_SETTID. I'm getting an assertion failure in
__libc_fork (THREAD_GETMEM (self, tid) != ppid).
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply
* [PATCH net-next 13/15] soc/fsl/qbman: Add an argument to signal if NAPI processing is required.
From: Sebastian Andrzej Siewior @ 2020-10-27 22:54 UTC (permalink / raw)
To: netdev
Cc: Aymen Sghaier, Madalin Bucur, Sebastian Andrzej Siewior,
Zhu Yanjun, Samuel Chessman, Ping-Ke Shih, Herbert Xu,
Horia Geantă, linux-rdma, Rain River, Kalle Valo,
Ulrich Kunitz, Jouni Malinen, Daniel Drake, Jakub Kicinski,
Thomas Gleixner, linux-arm-kernel, Leon Romanovsky, linuxppc-dev,
linux-wireless, Li Yang, linux-crypto, Jon Mason, Saeed Mahameed,
David S. Miller
In-Reply-To: <20201027225454.3492351-1-bigeasy@linutronix.de>
dpaa_eth_napi_schedule() and caam_qi_napi_schedule() schedule NAPI if
invoked from:
- Hard interrupt context
- Any context which is not serving soft interrupts
Any context which is not serving soft interrupts includes hard interrupts
so the in_irq() check is redundant. caam_qi_napi_schedule() has a comment
about this:
/*
* In case of threaded ISR, for RT kernels in_irq() does not return
* appropriate value, so use in_serving_softirq to distinguish between
* softirq and irq contexts.
*/
if (in_irq() || !in_serving_softirq())
This has nothing to do with RT. Even on a non RT kernel force threaded
interrupts run obviously in thread context and therefore in_irq() returns
false when invoked from the handler.
The extension of the in_irq() check with !in_serving_softirq() was there
when the drivers were added, but in the out of tree FSL BSP the original
condition was in_irq() which got extended due to failures on RT.
The usage of in_xxx() in drivers is phased out and Linus clearly requested
that code which changes behaviour depending on context should either be
seperated or the context be conveyed in an argument passed by the caller,
which usually knows the context. Right he is, the above construct is
clearly showing why.
The following callchains have been analyzed to end up in
dpaa_eth_napi_schedule():
qman_p_poll_dqrr()
__poll_portal_fast()
fq->cb.dqrr()
dpaa_eth_napi_schedule()
portal_isr()
__poll_portal_fast()
fq->cb.dqrr()
dpaa_eth_napi_schedule()
Both need to schedule NAPI.
The crypto part has another code path leading up to this:
kill_fq()
empty_retired_fq()
qman_p_poll_dqrr()
__poll_portal_fast()
fq->cb.dqrr()
dpaa_eth_napi_schedule()
kill_fq() is called from task context and ends up scheduling NAPI, but
that's pointless and an unintended side effect of the !in_serving_softirq()
check.
The code path:
caam_qi_poll() -> qman_p_poll_dqrr()
is invoked from NAPI and I *assume* from crypto's NAPI device and not
from qbman's NAPI device. I *guess* it is okay to skip scheduling NAPI
(because this is what happens now) but could be changed if it is wrong
due to `budget' handling.
Add an argument to __poll_portal_fast() which is true if NAPI needs to be
scheduled. This requires propagating the value to the caller including
`qman_cb_dqrr' typedef which is used by the dpaa and the crypto driver.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: "Horia Geantă" <horia.geanta@nxp.com>
Cc: Aymen Sghaier <aymen.sghaier@nxp.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Madalin Bucur <madalin.bucur@nxp.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Li Yang <leoyang.li@nxp.com>
Cc: linux-crypto@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/crypto/caam/qi.c | 3 ++-
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 ++++++++----
drivers/soc/fsl/qbman/qman.c | 12 ++++++------
drivers/soc/fsl/qbman/qman_test_api.c | 6 ++++--
drivers/soc/fsl/qbman/qman_test_stash.c | 6 ++++--
include/soc/fsl/qman.h | 3 ++-
6 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c
index ec53528d82058..09ea398304c8b 100644
--- a/drivers/crypto/caam/qi.c
+++ b/drivers/crypto/caam/qi.c
@@ -564,7 +564,8 @@ static int caam_qi_napi_schedule(struct qman_portal *p, struct caam_napi *np)
static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
struct qman_fq *rsp_fq,
- const struct qm_dqrr_entry *dqrr)
+ const struct qm_dqrr_entry *dqrr,
+ bool napi)
{
struct caam_napi *caam_napi = raw_cpu_ptr(&pcpu_qipriv.caam_napi);
struct caam_drv_req *drv_req;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 06cc863f4dd63..27835310b718e 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2316,7 +2316,8 @@ static inline int dpaa_eth_napi_schedule(struct dpaa_percpu_priv *percpu_priv,
static enum qman_cb_dqrr_result rx_error_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dq)
+ const struct qm_dqrr_entry *dq,
+ bool napi)
{
struct dpaa_fq *dpaa_fq = container_of(fq, struct dpaa_fq, fq_base);
struct dpaa_percpu_priv *percpu_priv;
@@ -2343,7 +2344,8 @@ static enum qman_cb_dqrr_result rx_error_dqrr(struct qman_portal *portal,
static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dq)
+ const struct qm_dqrr_entry *dq,
+ bool napi)
{
struct skb_shared_hwtstamps *shhwtstamps;
struct rtnl_link_stats64 *percpu_stats;
@@ -2460,7 +2462,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
static enum qman_cb_dqrr_result conf_error_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dq)
+ const struct qm_dqrr_entry *dq,
+ bool napi)
{
struct dpaa_percpu_priv *percpu_priv;
struct net_device *net_dev;
@@ -2481,7 +2484,8 @@ static enum qman_cb_dqrr_result conf_error_dqrr(struct qman_portal *portal,
static enum qman_cb_dqrr_result conf_dflt_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dq)
+ const struct qm_dqrr_entry *dq,
+ bool napi)
{
struct dpaa_percpu_priv *percpu_priv;
struct net_device *net_dev;
diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 9888a70618730..a92bd032fc36a 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1159,7 +1159,7 @@ static u32 fq_to_tag(struct qman_fq *fq)
static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
static inline unsigned int __poll_portal_fast(struct qman_portal *p,
- unsigned int poll_limit);
+ unsigned int poll_limit, bool napi);
static void qm_congestion_task(struct work_struct *work);
static void qm_mr_process_task(struct work_struct *work);
@@ -1174,7 +1174,7 @@ static irqreturn_t portal_isr(int irq, void *ptr)
/* DQRR-handling if it's interrupt-driven */
if (is & QM_PIRQ_DQRI) {
- __poll_portal_fast(p, QMAN_POLL_LIMIT);
+ __poll_portal_fast(p, QMAN_POLL_LIMIT, true);
clear = QM_DQAVAIL_MASK | QM_PIRQ_DQRI;
}
/* Handling of anything else that's interrupt-driven */
@@ -1602,7 +1602,7 @@ static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
* user callbacks to call into any QMan API.
*/
static inline unsigned int __poll_portal_fast(struct qman_portal *p,
- unsigned int poll_limit)
+ unsigned int poll_limit, bool napi)
{
const struct qm_dqrr_entry *dq;
struct qman_fq *fq;
@@ -1636,7 +1636,7 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p,
* and we don't want multiple if()s in the critical
* path (SDQCR).
*/
- res = fq->cb.dqrr(p, fq, dq);
+ res = fq->cb.dqrr(p, fq, dq, napi);
if (res == qman_cb_dqrr_stop)
break;
/* Check for VDQCR completion */
@@ -1646,7 +1646,7 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p,
/* SDQCR: context_b points to the FQ */
fq = tag_to_fq(be32_to_cpu(dq->context_b));
/* Now let the callback do its stuff */
- res = fq->cb.dqrr(p, fq, dq);
+ res = fq->cb.dqrr(p, fq, dq, napi);
/*
* The callback can request that we exit without
* consuming this entry nor advancing;
@@ -1753,7 +1753,7 @@ EXPORT_SYMBOL(qman_start_using_portal);
int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
{
- return __poll_portal_fast(p, limit);
+ return __poll_portal_fast(p, limit, false);
}
EXPORT_SYMBOL(qman_p_poll_dqrr);
diff --git a/drivers/soc/fsl/qbman/qman_test_api.c b/drivers/soc/fsl/qbman/qman_test_api.c
index 7066b2f1467cc..93eb86923e44f 100644
--- a/drivers/soc/fsl/qbman/qman_test_api.c
+++ b/drivers/soc/fsl/qbman/qman_test_api.c
@@ -45,7 +45,8 @@
static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
struct qman_fq *,
- const struct qm_dqrr_entry *);
+ const struct qm_dqrr_entry *,
+ bool napi);
static void cb_ern(struct qman_portal *, struct qman_fq *,
const union qm_mr_entry *);
static void cb_fqs(struct qman_portal *, struct qman_fq *,
@@ -208,7 +209,8 @@ int qman_test_api(void)
static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dq)
+ const struct qm_dqrr_entry *dq,
+ bool napi)
{
if (WARN_ON(fd_neq(&fd_dq, &dq->fd))) {
pr_err("BADNESS: dequeued frame doesn't match;\n");
diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c
index e87b65403b672..9b8caceedf7f3 100644
--- a/drivers/soc/fsl/qbman/qman_test_stash.c
+++ b/drivers/soc/fsl/qbman/qman_test_stash.c
@@ -275,7 +275,8 @@ static inline int process_frame_data(struct hp_handler *handler,
static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dqrr)
+ const struct qm_dqrr_entry *dqrr,
+ bool napi)
{
struct hp_handler *handler = (struct hp_handler *)fq;
@@ -293,7 +294,8 @@ static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dqrr)
+ const struct qm_dqrr_entry *dqrr,
+ bool napi)
{
struct hp_handler *handler = (struct hp_handler *)fq;
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index 9f484113cfda7..fe3faa2d64f16 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -689,7 +689,8 @@ enum qman_cb_dqrr_result {
};
typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
struct qman_fq *fq,
- const struct qm_dqrr_entry *dqrr);
+ const struct qm_dqrr_entry *dqrr,
+ bool napi);
/*
* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
--
2.28.0
^ permalink raw reply related
* [PATCH net-next 14/15] net: dpaa: Replace in_irq() usage.
From: Sebastian Andrzej Siewior @ 2020-10-27 22:54 UTC (permalink / raw)
To: netdev
Cc: Aymen Sghaier, Madalin Bucur, Sebastian Andrzej Siewior,
Zhu Yanjun, Samuel Chessman, Ping-Ke Shih, Herbert Xu,
Horia Geantă, linux-rdma, Rain River, Kalle Valo,
Ulrich Kunitz, Jouni Malinen, Daniel Drake, Jakub Kicinski,
Thomas Gleixner, linux-arm-kernel, Leon Romanovsky, linuxppc-dev,
linux-wireless, Li Yang, linux-crypto, Jon Mason, Saeed Mahameed,
David S. Miller
In-Reply-To: <20201027225454.3492351-1-bigeasy@linutronix.de>
The driver uses in_irq() + in_serving_softirq() magic to decide if NAPI
scheduling is required or packet processing.
The usage of in_*() in drivers is phased out and Linus clearly requested
that code which changes behaviour depending on context should either be
seperated or the context be conveyed in an argument passed by the caller,
which usually knows the context.
Use the `napi' argument passed by the callback. It is set true if
called from the interrupt handler and NAPI should be scheduled.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: "Horia Geantă" <horia.geanta@nxp.com>
Cc: Aymen Sghaier <aymen.sghaier@nxp.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Madalin Bucur <madalin.bucur@nxp.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Li Yang <leoyang.li@nxp.com>
Cc: linux-crypto@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 27835310b718e..2c949acd74c67 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2300,9 +2300,9 @@ static void dpaa_tx_conf(struct net_device *net_dev,
}
static inline int dpaa_eth_napi_schedule(struct dpaa_percpu_priv *percpu_priv,
- struct qman_portal *portal)
+ struct qman_portal *portal, bool napi)
{
- if (unlikely(in_irq() || !in_serving_softirq())) {
+ if (napi) {
/* Disable QMan IRQ and invoke NAPI */
qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
@@ -2333,7 +2333,7 @@ static enum qman_cb_dqrr_result rx_error_dqrr(struct qman_portal *portal,
percpu_priv = this_cpu_ptr(priv->percpu_priv);
- if (dpaa_eth_napi_schedule(percpu_priv, portal))
+ if (dpaa_eth_napi_schedule(percpu_priv, portal, napi))
return qman_cb_dqrr_stop;
dpaa_eth_refill_bpools(priv);
@@ -2377,7 +2377,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
percpu_priv = this_cpu_ptr(priv->percpu_priv);
percpu_stats = &percpu_priv->stats;
- if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
+ if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal, napi)))
return qman_cb_dqrr_stop;
/* Make sure we didn't run out of buffers */
@@ -2474,7 +2474,7 @@ static enum qman_cb_dqrr_result conf_error_dqrr(struct qman_portal *portal,
percpu_priv = this_cpu_ptr(priv->percpu_priv);
- if (dpaa_eth_napi_schedule(percpu_priv, portal))
+ if (dpaa_eth_napi_schedule(percpu_priv, portal, napi))
return qman_cb_dqrr_stop;
dpaa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
@@ -2499,7 +2499,7 @@ static enum qman_cb_dqrr_result conf_dflt_dqrr(struct qman_portal *portal,
percpu_priv = this_cpu_ptr(priv->percpu_priv);
- if (dpaa_eth_napi_schedule(percpu_priv, portal))
+ if (dpaa_eth_napi_schedule(percpu_priv, portal, napi))
return qman_cb_dqrr_stop;
dpaa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
--
2.28.0
^ permalink raw reply related
* [PATCH net-next 12/15] net: rtlwifi: Remove in_interrupt() usage in halbtc_send_bt_mp_operation()
From: Sebastian Andrzej Siewior @ 2020-10-27 22:54 UTC (permalink / raw)
To: netdev
Cc: Aymen Sghaier, Madalin Bucur, Sebastian Andrzej Siewior,
Zhu Yanjun, Samuel Chessman, Ping-Ke Shih, Herbert Xu,
Horia Geantă, linux-rdma, Rain River, Kalle Valo,
Ulrich Kunitz, Jouni Malinen, Daniel Drake, Jakub Kicinski,
Thomas Gleixner, linux-arm-kernel, Leon Romanovsky, linuxppc-dev,
linux-wireless, Li Yang, linux-crypto, Jon Mason, Saeed Mahameed,
David S. Miller
In-Reply-To: <20201027225454.3492351-1-bigeasy@linutronix.de>
halbtc_send_bt_mp_operation() uses in_interrupt() to determine if it is
safe to invoke wait_for_completion().
The usage of in_interrupt() in drivers is phased out and Linus clearly
requested that code which changes behaviour depending on context should
either be separated or the context be conveyed in an argument passed by the
caller, which usually knows the context.
Aside of that in_interrupt() is not correct as it does not catch preempt
disabled regions which neither can sleep.
halbtc_send_bt_mp_operation() is called from:
rtl_watchdog_wq_callback()
rtl_btc_periodical()
halbtc_get()
case BTC_GET_U4_BT_PATCH_VER:
halbtc_get_bt_patch_version()
which is preemtible context.
rtl_c2h_content_parsing()
btc_ops->btc_btinfo_notify()
rtl_btc_btinfo_notify()
exhalbtc_bt_info_notify()
ex_btc8723b1ant_bt_info_notify()
ex_btc8821a1ant_bt_info_notify()
ex_btc8821a2ant_bt_info_notify()
btcoexist->btc_set_bt_reg()
halbtc_set_bt_reg()
rtl_c2h_content_parsing() is in turn called from:
rtl_c2hcmd_wq_callback()
rtl_c2hcmd_launcher()
which is preemptible context and from:
_rtl_pci_rx_interrupt
rtl_c2hcmd_enqueue()
which is obviously not preemptible but limited to C2H_BT_MP commands
which does invoke rtl_c2h_content_parsing().
Aside of that it can be reached from:
halbtc_get()
case BTC_GET_U4_SUPPORTED_FEATURE:
halbtc_get_bt_coex_supported_feature()
case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL:
halbtc_get_bt_forbidden_slot_val()
case BTC_GET_U4_BT_DEVICE_INFO:
halbtc_get_bt_device_info()
case BTC_GET_U4_SUPPORTED_VERSION:
halbtc_get_bt_coex_supported_version()
case BTC_GET_U4_SUPPORTED_FEATURE:
halbtc_get_bt_coex_supported_feature()
btcoexist->btc_get_bt_afh_map_from_bt()
halbtc_get_bt_afh_map_from_bt()
btcoexist->btc_get_ble_scan_para_from_bt()
halbtc_get_ble_scan_para_from_bt()
btcoexist->btc_get_ble_scan_type_from_bt()
halbtc_get_ble_scan_type_from_bt()
btcoexist->btc_get_ant_det_val_from_bt()
halbtc_get_ant_det_val_from_bt()
btcoexist->btc_get_bt_coex_supported_version()
halbtc_get_bt_coex_supported_version()
btcoexist->btc_get_bt_coex_supported_feature()
halbtc_get_bt_coex_supported_feature()
None of these have a caller. Welcome to the wonderful world of HALs and
onion layers.
Remove in_interrupt() check.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Ping-Ke Shih <pkshih@realtek.com>
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 2155a6699ef8d..be4c0e60d44d1 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -240,9 +240,6 @@ bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms);
- if (in_interrupt())
- return false;
-
if (wait_for_completion_timeout(&btcoexist->bt_mp_comp,
msecs_to_jiffies(wait_ms)) == 0) {
rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
--
2.28.0
^ permalink raw reply related
* [PATCH net-next 15/15] crypto: caam: Replace in_irq() usage.
From: Sebastian Andrzej Siewior @ 2020-10-27 22:54 UTC (permalink / raw)
To: netdev
Cc: Aymen Sghaier, Madalin Bucur, Sebastian Andrzej Siewior,
Zhu Yanjun, Samuel Chessman, Ping-Ke Shih, Herbert Xu,
Horia Geantă, linux-rdma, Rain River, Kalle Valo,
Ulrich Kunitz, Jouni Malinen, Daniel Drake, Jakub Kicinski,
Thomas Gleixner, linux-arm-kernel, Leon Romanovsky, linuxppc-dev,
linux-wireless, Li Yang, linux-crypto, Jon Mason, Saeed Mahameed,
David S. Miller
In-Reply-To: <20201027225454.3492351-1-bigeasy@linutronix.de>
The driver uses in_irq() + in_serving_softirq() magic to decide if NAPI
scheduling is required or packet processing.
The usage of in_*() in drivers is phased out and Linus clearly requested
that code which changes behaviour depending on context should either be
seperated or the context be conveyed in an argument passed by the caller,
which usually knows the context.
Use the `napi' argument passed by the callback. It is set true if
called from the interrupt handler and NAPI should be scheduled.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: "Horia Geantă" <horia.geanta@nxp.com>
Cc: Aymen Sghaier <aymen.sghaier@nxp.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Madalin Bucur <madalin.bucur@nxp.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Li Yang <leoyang.li@nxp.com>
Cc: linux-crypto@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/crypto/caam/qi.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c
index 09ea398304c8b..79dbd90887f8a 100644
--- a/drivers/crypto/caam/qi.c
+++ b/drivers/crypto/caam/qi.c
@@ -545,14 +545,10 @@ static void cgr_cb(struct qman_portal *qm, struct qman_cgr *cgr, int congested)
}
}
-static int caam_qi_napi_schedule(struct qman_portal *p, struct caam_napi *np)
+static int caam_qi_napi_schedule(struct qman_portal *p, struct caam_napi *np,
+ bool napi)
{
- /*
- * In case of threaded ISR, for RT kernels in_irq() does not return
- * appropriate value, so use in_serving_softirq to distinguish between
- * softirq and irq contexts.
- */
- if (unlikely(in_irq() || !in_serving_softirq())) {
+ if (napi) {
/* Disable QMan IRQ source and invoke NAPI */
qman_p_irqsource_remove(p, QM_PIRQ_DQRI);
np->p = p;
@@ -574,7 +570,7 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
struct caam_drv_private *priv = dev_get_drvdata(qidev);
u32 status;
- if (caam_qi_napi_schedule(p, caam_napi))
+ if (caam_qi_napi_schedule(p, caam_napi, napi))
return qman_cb_dqrr_stop;
fd = &dqrr->fd;
--
2.28.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox