* Re: [PATCH 1/2] powerpc/perf: init platform pmu driver from core-book3s
From: kbuild test robot @ 2019-04-01 9:55 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: Madhavan Srinivasan, linuxppc-dev, kbuild-all
In-Reply-To: <1554059913-20335-1-git-send-email-maddy@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1650 bytes --]
Hi Madhavan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.1-rc3 next-20190401]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/powerpc-perf-init-platform-pmu-driver-from-core-book3s/20190401-104458
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-pmac32_defconfig (attached as .config)
compiler: powerpc-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=powerpc
All errors (new ones prefixed by >>):
arch/powerpc/perf/core-book3s.o: In function `init_ppc64_pmu':
>> core-book3s.c:(.init.text+0xc): undefined reference to `init_power5_pmu'
>> core-book3s.c:(.init.text+0x20): undefined reference to `init_power5p_pmu'
>> core-book3s.c:(.init.text+0x2c): undefined reference to `init_power6_pmu'
>> core-book3s.c:(.init.text+0x38): undefined reference to `init_power7_pmu'
>> core-book3s.c:(.init.text+0x44): undefined reference to `init_power8_pmu'
>> core-book3s.c:(.init.text+0x50): undefined reference to `init_power9_pmu'
>> core-book3s.c:(.init.text+0x5c): undefined reference to `init_ppc970_pmu'
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23288 bytes --]
^ permalink raw reply
* Re: [PATCH v2 5/5] Lib: sort.h: replace int size with size_t size in the swap function
From: George Spelvin @ 2019-04-01 9:56 UTC (permalink / raw)
To: andriy.shevchenko, st5pub
Cc: peterz, dchinner, linux-kernel, linux-mtd, hpa, jslaby, sfr,
darrick.wong, mark, x86, mingo, naveen.n.rao, linux-snps-arc,
jannh, bp, jlbec, jpoimboe, tglx, lkml, ard.biesheuvel, gregkh,
dedekind1, adrian.hunter, vgupta, richard, paulus, linuxppc-dev,
ocfs2-devel
In-Reply-To: <20190401093555.GD9224@smile.fi.intel.com>
On Mon, 1 Apr 2019 at 12:35:55 +0300, Andy Shevchenko wrote:
> Hmm... If (*swap)() is called recursively it means the change might increase
> stack usage on 64-bit platforms.
>
> Am I missing something?
Under what conceivable circumstance would someone write a recursive
(*swap)() function?
You're technically right, but the precondition is more fantastical
than "if the U.K.'s parliament get their shit together before the
12th", so I have a hard time worrying about it.
But you did make me think of something: the whole reason swap()
takes a size argument is for the benefit of the (no longer existing)
generic swap functions. All of the custom swap functions ignore
it.
So how about *deleting* the parameter instead? That simplifies
everything.
^ permalink raw reply
* Re: [PATCH 1/8] PCI: dwc: pci-dra7xx: fix a leaked reference by adding missing of_node_put
From: Lorenzo Pieralisi @ 2019-04-01 10:03 UTC (permalink / raw)
To: Wen Yang
Cc: heiko, hayashi.kunihiko, shawn.lin, minghuan.Lian, paulus,
thomas.petazzoni, ryder.lee, kishon, linux-rockchip,
bcm-kernel-feedback-list, linux-arm-kernel, linux-pci, wang.yi59,
rjui, linux-mediatek, tyreld, matthias.bgg, linux-omap,
mingkai.hu, roy.zang, sbranden, yamada.masahiro, linuxppc-dev,
linux-kernel, bhelgaas
In-Reply-To: <1551242443-27300-1-git-send-email-wen.yang99@zte.com.cn>
On Wed, Feb 27, 2019 at 12:40:36PM +0800, Wen Yang wrote:
> The call to of_get_next_child returns a node pointer with refcount
> incremented thus it must be explicitly decremented after the last
> usage.
> irq_domain_add_linear also calls of_node_get to increase refcount,
> so irq_domain will not be affected when it is released.
>
> Detected by coccinelle with the following warnings:
> ./drivers/pci/controller/dwc/pci-dra7xx.c:252:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 241, but without a corresponding object release within this function.
> ./drivers/pci/controller/dwc/pci-dra7xx.c:255:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 241, but without a corresponding object release within this function.
>
> Signed-off-by: Wen Yang <wen.yang99@zte.com.cn>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: linux-omap@vger.kernel.org
> Cc: linux-pci@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> drivers/pci/controller/dwc/pci-dra7xx.c | 1 +
> 1 file changed, 1 insertion(+)
Applied the series to pci/misc for v5.2, thanks.
Lorenzo
> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
> index ae84a69..627c91d 100644
> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> @@ -247,6 +247,7 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
>
> dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
> &intx_domain_ops, pp);
> + of_node_put(pcie_intc_node);
> if (!dra7xx->irq_domain) {
> dev_err(dev, "Failed to get a INTx IRQ domain\n");
> return -ENODEV;
> --
> 2.9.5
>
^ permalink raw reply
* Re: [PATCH 2/5] powerpc: module_[32|64].c: replace swap function with built-in one
From: Michael Ellerman @ 2019-04-01 10:11 UTC (permalink / raw)
To: Andrey Abramov; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <21287961553964090@iva7-8a22bc446c12.qloud-c.yandex.net>
Andrey Abramov <st5pub@yandex.ru> writes:
> Replace relaswap with built-in one, because of relaswap
> does a simple byte to byte swap.
>
> Signed-off-by: Andrey Abramov <st5pub@yandex.ru>
> ---
> arch/powerpc/kernel/module_32.c | 17 +----------------
> arch/powerpc/kernel/module_64.c | 17 +----------------
> 2 files changed, 2 insertions(+), 32 deletions(-)
This looks OK. It's a bit of a pity to replace the 8-byte-at-a-time copy
with a byte-at-a-time copy, but I suspect it's insignificant compared to
the overhead of calling the comparison and swap functions.
And we could always add a generic 8-byte-at-a-time swap function if it's
a bottleneck.
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
cheers
> diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
> index 88d83771f462..c311e8575d10 100644
> --- a/arch/powerpc/kernel/module_32.c
> +++ b/arch/powerpc/kernel/module_32.c
> @@ -79,21 +79,6 @@ static int relacmp(const void *_x, const void *_y)
> return 0;
> }
>
> -static void relaswap(void *_x, void *_y, int size)
> -{
> - uint32_t *x, *y, tmp;
> - int i;
> -
> - y = (uint32_t *)_x;
> - x = (uint32_t *)_y;
> -
> - for (i = 0; i < sizeof(Elf32_Rela) / sizeof(uint32_t); i++) {
> - tmp = x[i];
> - x[i] = y[i];
> - y[i] = tmp;
> - }
> -}
> -
> /* Get the potential trampolines size required of the init and
> non-init sections */
> static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
> @@ -130,7 +115,7 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
> */
> sort((void *)hdr + sechdrs[i].sh_offset,
> sechdrs[i].sh_size / sizeof(Elf32_Rela),
> - sizeof(Elf32_Rela), relacmp, relaswap);
> + sizeof(Elf32_Rela), relacmp, NULL);
>
> ret += count_relocs((void *)hdr
> + sechdrs[i].sh_offset,
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index 8661eea78503..0c833d7f36f1 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -231,21 +231,6 @@ static int relacmp(const void *_x, const void *_y)
> return 0;
> }
>
> -static void relaswap(void *_x, void *_y, int size)
> -{
> - uint64_t *x, *y, tmp;
> - int i;
> -
> - y = (uint64_t *)_x;
> - x = (uint64_t *)_y;
> -
> - for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) {
> - tmp = x[i];
> - x[i] = y[i];
> - y[i] = tmp;
> - }
> -}
> -
> /* Get size of potential trampolines required. */
> static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
> const Elf64_Shdr *sechdrs)
> @@ -269,7 +254,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
> */
> sort((void *)sechdrs[i].sh_addr,
> sechdrs[i].sh_size / sizeof(Elf64_Rela),
> - sizeof(Elf64_Rela), relacmp, relaswap);
> + sizeof(Elf64_Rela), relacmp, NULL);
>
> relocs += count_relocs((void *)sechdrs[i].sh_addr,
> sechdrs[i].sh_size
> --
> 2.21.0
^ permalink raw reply
* RE: [PATCH 05/13] soc/fsl/bqman: page align iommu mapping sizes
From: Laurentiu Tudor @ 2019-04-01 10:18 UTC (permalink / raw)
To: Leo Li
Cc: Madalin-cristian Bucur, Netdev, Roy Pledge, lkml, Linux IOMMU,
Camelia Alexandra Groza, linuxppc-dev, David Miller,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNTh65rwPVVzJBWt-cNrbQWAoo0FeTGnCHDiqSxvARa_5g@mail.gmail.com>
Hi Leo,
> -----Original Message-----
> From: Li Yang [mailto:leoyang.li@nxp.com]
> Sent: Saturday, March 30, 2019 12:07 AM
> To: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Cc: Netdev <netdev@vger.kernel.org>; Madalin-cristian Bucur
> <madalin.bucur@nxp.com>; Roy Pledge <roy.pledge@nxp.com>; Camelia
> Alexandra Groza <camelia.groza@nxp.com>; David Miller
> <davem@davemloft.net>; Linux IOMMU <iommu@lists.linux-foundation.org>;
> moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE <linux-arm-
> kernel@lists.infradead.org>; linuxppc-dev <linuxppc-dev@lists.ozlabs.org>;
> lkml <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH 05/13] soc/fsl/bqman: page align iommu mapping sizes
> Importance: High
>
> On Fri, Mar 29, 2019 at 9:01 AM <laurentiu.tudor@nxp.com> wrote:
> >
> > From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >
> > Prior to calling iommu_map()/iommu_unmap() page align the size or
> > failures such as below could happen:
> >
> > iommu: unaligned: iova 0x... pa 0x... size 0x4000 min_pagesz 0x10000
> > qman_portal 500000000.qman-portal: failed to iommu_map() -22
> >
> > Seen when booted a kernel compiled with 64K page size support.
>
> This will silently incease the actual space mapped to 64K when the
> driver is actually trying to map 4K. Will this potentially cause
> security breaches? If it is really safe to map 64K, probably the
> better way is to increase the region size to 64k in the device tree
> explicitly.
Not sure if such small reserved areas are practical, so I wouldn't worry
much. As an example, currently on ls1046a we reserve the following memory:
bman 16MB, qman fqd 8MB, qman pdfr 32MB.
But just to be on the safe side, maybe we could add an error check for
device trees that specify < 64KB reserved memory.
---
Best Regards, Laurentiu
> >
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> > drivers/soc/fsl/qbman/bman_ccsr.c | 2 +-
> > drivers/soc/fsl/qbman/qman_ccsr.c | 4 ++--
> > drivers/soc/fsl/qbman/qman_portal.c | 2 +-
> > 3 files changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c
> b/drivers/soc/fsl/qbman/bman_ccsr.c
> > index b209c79511bb..3a6e01bde32d 100644
> > --- a/drivers/soc/fsl/qbman/bman_ccsr.c
> > +++ b/drivers/soc/fsl/qbman/bman_ccsr.c
> > @@ -230,7 +230,7 @@ static int fsl_bman_probe(struct platform_device
> *pdev)
> > /* Create an 1-to-1 iommu mapping for FBPR area */
> > domain = iommu_get_domain_for_dev(dev);
> > if (domain) {
> > - ret = iommu_map(domain, fbpr_a, fbpr_a, fbpr_sz,
> > + ret = iommu_map(domain, fbpr_a, fbpr_a,
> PAGE_ALIGN(fbpr_sz),
> > IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > if (ret)
> > dev_warn(dev, "failed to iommu_map() %d\n",
> ret);
> > diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c
> b/drivers/soc/fsl/qbman/qman_ccsr.c
> > index eec7700507e1..8d3c950ce52d 100644
> > --- a/drivers/soc/fsl/qbman/qman_ccsr.c
> > +++ b/drivers/soc/fsl/qbman/qman_ccsr.c
> > @@ -783,11 +783,11 @@ static int fsl_qman_probe(struct platform_device
> *pdev)
> > /* Create an 1-to-1 iommu mapping for fqd and pfdr areas */
> > domain = iommu_get_domain_for_dev(dev);
> > if (domain) {
> > - ret = iommu_map(domain, fqd_a, fqd_a, fqd_sz,
> > + ret = iommu_map(domain, fqd_a, fqd_a,
> PAGE_ALIGN(fqd_sz),
> > IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > if (ret)
> > dev_warn(dev, "iommu_map(fqd) failed %d\n",
> ret);
> > - ret = iommu_map(domain, pfdr_a, pfdr_a, pfdr_sz,
> > + ret = iommu_map(domain, pfdr_a, pfdr_a,
> PAGE_ALIGN(pfdr_sz),
> > IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > if (ret)
> > dev_warn(dev, "iommu_map(pfdr) failed %d\n",
> ret);
> > diff --git a/drivers/soc/fsl/qbman/qman_portal.c
> b/drivers/soc/fsl/qbman/qman_portal.c
> > index dfb62f9815e9..bce56da2b01f 100644
> > --- a/drivers/soc/fsl/qbman/qman_portal.c
> > +++ b/drivers/soc/fsl/qbman/qman_portal.c
> > @@ -297,7 +297,7 @@ static int qman_portal_probe(struct platform_device
> *pdev)
> > */
> > err = iommu_map(domain,
> > addr_phys[0]->start, addr_phys[0]-
> >start,
> > - resource_size(addr_phys[0]),
> > + PAGE_ALIGN(resource_size(addr_phys[0])),
> > IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > if (err)
> > dev_warn(dev, "failed to iommu_map() %d\n",
> err);
> > --
> > 2.17.1
> >
^ permalink raw reply
* RE: [PATCH 01/13] soc/fsl/qman: fixup liodns only on ppc targets
From: Laurentiu Tudor @ 2019-04-01 10:21 UTC (permalink / raw)
To: Leo Li
Cc: Madalin-cristian Bucur, Netdev, Roy Pledge, lkml, Linux IOMMU,
Camelia Alexandra Groza, linuxppc-dev, David Miller,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNQ9AGRvq8XDjeTerUBry+_hO-U=shCXFaqHhtc9QvMvng@mail.gmail.com>
Hi Leo,
> -----Original Message-----
> From: Li Yang [mailto:leoyang.li@nxp.com]
> Sent: Friday, March 29, 2019 11:50 PM
> To: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Cc: Netdev <netdev@vger.kernel.org>; Madalin-cristian Bucur
> <madalin.bucur@nxp.com>; Roy Pledge <roy.pledge@nxp.com>; Camelia
> Alexandra Groza <camelia.groza@nxp.com>; David Miller
> <davem@davemloft.net>; Linux IOMMU <iommu@lists.linux-foundation.org>;
> moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE <linux-arm-
> kernel@lists.infradead.org>; linuxppc-dev <linuxppc-dev@lists.ozlabs.org>;
> lkml <linux-kernel@vger.kernel.org>
> Subject: Re: [PATCH 01/13] soc/fsl/qman: fixup liodns only on ppc targets
> Importance: High
>
> On Fri, Mar 29, 2019 at 9:01 AM <laurentiu.tudor@nxp.com> wrote:
> >
> > From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >
> > ARM SoCs use SMMU so the liodn fixup done in the qman driver is no
> > longer making sense and it also breaks the ICID settings inherited
> > from u-boot. Do the fixups only for PPC targets.
> >
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> > drivers/soc/fsl/qbman/qman_ccsr.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c
> b/drivers/soc/fsl/qbman/qman_ccsr.c
> > index 109b38de3176..12e414ca3b03 100644
> > --- a/drivers/soc/fsl/qbman/qman_ccsr.c
> > +++ b/drivers/soc/fsl/qbman/qman_ccsr.c
> > @@ -598,6 +598,7 @@ static int qman_init_ccsr(struct device *dev)
> > #define LIO_CFG_LIODN_MASK 0x0fff0000
> > void qman_liodn_fixup(u16 channel)
> > {
> > +#ifdef CONFIG_PPC
> > static int done;
> > static u32 liodn_offset;
> > u32 before, after;
> > @@ -617,6 +618,7 @@ void qman_liodn_fixup(u16 channel)
> > qm_ccsr_out(REG_REV3_QCSP_LIO_CFG(idx), after);
> > else
> > qm_ccsr_out(REG_QCSP_LIO_CFG(idx), after);
> > +#endif
>
> According to the Linux coding style recommendation, it would be better
> to put the #ifdef into the header files
> "drivers/soc/fsl/qbman/qman_priv.h". And I'm not sure if this is
> needed on PPC when IOMMU(PAMU) driver is not compiled, if not,
> probably using CONFIG_PAMU as condition would be even better.
Good point, will so in the next spin.
---
Best Regards, Laurentiu
> > }
> >
> > #define IO_CFG_SDEST_MASK 0x00ff0000
> > --
> > 2.17.1
> >
^ permalink raw reply
* Re: [PATCH v2 5/5] Lib: sort.h: replace int size with size_t size in the swap function
From: Andy Shevchenko @ 2019-04-01 10:28 UTC (permalink / raw)
To: George Spelvin
Cc: peterz, dchinner, linux-kernel, st5pub, linux-mtd, hpa, jslaby,
sfr, darrick.wong, mark, x86, mingo, naveen.n.rao, linux-snps-arc,
jannh, bp, jlbec, jpoimboe, tglx, ard.biesheuvel, gregkh,
dedekind1, adrian.hunter, vgupta, richard, paulus, linuxppc-dev,
ocfs2-devel
In-Reply-To: <201904010956.x319u70q021113@sdf.org>
On Mon, Apr 01, 2019 at 09:56:07AM +0000, George Spelvin wrote:
> On Mon, 1 Apr 2019 at 12:35:55 +0300, Andy Shevchenko wrote:
> > Hmm... If (*swap)() is called recursively it means the change might increase
> > stack usage on 64-bit platforms.
> >
> > Am I missing something?
>
> Under what conceivable circumstance would someone write a recursive
> (*swap)() function?
>
> You're technically right, but the precondition is more fantastical
> than "if the U.K.'s parliament get their shit together before the
> 12th", so I have a hard time worrying about it.
>
> But you did make me think of something: the whole reason swap()
> takes a size argument is for the benefit of the (no longer existing)
> generic swap functions. All of the custom swap functions ignore
> it.
>
> So how about *deleting* the parameter instead? That simplifies
> everything.
I like this idea!
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/2] powerpc/perf: Add generic compat mode pmu driver
From: kbuild test robot @ 2019-04-01 10:30 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: Madhavan Srinivasan, linuxppc-dev, kbuild-all
In-Reply-To: <1554059913-20335-2-git-send-email-maddy@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]
Hi Madhavan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.1-rc3 next-20190401]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/powerpc-perf-init-platform-pmu-driver-from-core-book3s/20190401-104458
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-pmac32_defconfig (attached as .config)
compiler: powerpc-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=powerpc
All errors (new ones prefixed by >>):
arch/powerpc/perf/core-book3s.o: In function `init_ppc64_pmu':
core-book3s.c:(.init.text+0xc): undefined reference to `init_power5_pmu'
core-book3s.c:(.init.text+0x18): undefined reference to `init_power5p_pmu'
core-book3s.c:(.init.text+0x24): undefined reference to `init_power6_pmu'
core-book3s.c:(.init.text+0x30): undefined reference to `init_power7_pmu'
core-book3s.c:(.init.text+0x3c): undefined reference to `init_power8_pmu'
core-book3s.c:(.init.text+0x48): undefined reference to `init_power9_pmu'
core-book3s.c:(.init.text+0x54): undefined reference to `init_ppc970_pmu'
>> core-book3s.c:(.init.text+0x6c): undefined reference to `init_generic_compat_pmu'
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23288 bytes --]
^ permalink raw reply
* RE: [PATCH 13/13] dpaa_eth: fix SG frame cleanup
From: Laurentiu Tudor @ 2019-04-01 10:41 UTC (permalink / raw)
To: jocke@infinera.com, netdev@vger.kernel.org,
Madalin-cristian Bucur, Leo Li, Roy Pledge,
Camelia Alexandra Groza
Cc: iommu@lists.linux-foundation.org, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, davem@davemloft.net
In-Reply-To: <702d2baba6c2c131c1ae59607943eb8f8813d250.camel@infinera.com>
Hi Joakim,
> -----Original Message-----
> From: Joakim Tjernlund [mailto:Joakim.Tjernlund@infinera.com]
> Sent: Friday, March 29, 2019 5:25 PM>
>
> Should this one go stable 4.14/4.19 too?
Good point. I also think it makes sense to cc: stable.
---
Best Regards, Laurentiu
> On Fri, 2019-03-29 at 16:00 +0200, laurentiu.tudor@nxp.com wrote:
> >
> > From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >
> > Fix issue with the entry indexing in the sg frame cleanup code being
> > off-by-1. This problem showed up when doing some basic iperf tests and
> > manifested in traffic coming to a halt.
> >
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > Acked-by: Madalin Bucur <madalin.bucur@nxp.com>
> > ---
> > drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > index daede7272768..40420edc9ce6 100644
> > --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> > @@ -1663,7 +1663,7 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const
> struct dpaa_priv *priv,
> > qm_sg_entry_get_len(&sgt[0]), dma_dir);
> >
> > /* remaining pages were mapped with skb_frag_dma_map()
> */
> > - for (i = 1; i < nr_frags; i++) {
> > + for (i = 1; i <= nr_frags; i++) {
> > WARN_ON(qm_sg_entry_is_ext(&sgt[i]));
> >
> > dma_unmap_page(dev, qm_sg_addr(&sgt[i]),
> > --
> > 2.17.1
> >
^ permalink raw reply
* RE: [PATCH 02/13] soc/fsl/bman: map FBPR area in the iommu
From: Laurentiu Tudor @ 2019-04-01 11:04 UTC (permalink / raw)
To: Robin Murphy, netdev@vger.kernel.org, Madalin-cristian Bucur,
Roy Pledge, Camelia Alexandra Groza, Leo Li
Cc: iommu@lists.linux-foundation.org, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, davem@davemloft.net
In-Reply-To: <b747c418-a495-56e0-c106-a8ec8e82ccb9@arm.com>
Hi Robin,
> -----Original Message-----
> From: Robin Murphy [mailto:robin.murphy@arm.com]
> Sent: Friday, March 29, 2019 4:51 PM
>
> On 29/03/2019 14:00, laurentiu.tudor@nxp.com wrote:
> > From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >
> > Add a one-to-one iommu mapping for bman private data memory (FBPR).
> > This is required for BMAN to work without faults behind an iommu.
> >
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> > drivers/soc/fsl/qbman/bman_ccsr.c | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c
> b/drivers/soc/fsl/qbman/bman_ccsr.c
> > index 7c3cc968053c..b209c79511bb 100644
> > --- a/drivers/soc/fsl/qbman/bman_ccsr.c
> > +++ b/drivers/soc/fsl/qbman/bman_ccsr.c
> > @@ -29,6 +29,7 @@
> > */
> >
> > #include "bman_priv.h"
> > +#include <linux/iommu.h>
> >
> > u16 bman_ip_rev;
> > EXPORT_SYMBOL(bman_ip_rev);
> > @@ -178,6 +179,7 @@ static int fsl_bman_probe(struct platform_device
> *pdev)
> > int ret, err_irq;
> > struct device *dev = &pdev->dev;
> > struct device_node *node = dev->of_node;
> > + struct iommu_domain *domain;
> > struct resource *res;
> > u16 id, bm_pool_cnt;
> > u8 major, minor;
> > @@ -225,6 +227,15 @@ static int fsl_bman_probe(struct platform_device
> *pdev)
> >
> > dev_dbg(dev, "Allocated FBPR 0x%llx 0x%zx\n", fbpr_a, fbpr_sz);
> >
> > + /* Create an 1-to-1 iommu mapping for FBPR area */
> > + domain = iommu_get_domain_for_dev(dev);
>
> If that's expected to be the default domain that you're grabbing, then
> this is *incredibly* fragile. There's nothing to stop the IOVA that you
> forcibly map from being automatically allocated later and causing some
> other DMA mapping to fail noisily and unexpectedly.
Agree here, we pretty much rely on luck with this implementation. As a side note, I've also experimented using dma_map_resource() instead of directly calling into iommu api and things worked fine, but see below ...
> Furthermore, have you tried this with "iommu.passthrough=1"?
Yes. The iommu_map() calls fail and the drivers issue warning messages, but apart from that I don't see any issues.
> That said, I really don't understand what's going on here anyway :/
>
> As far as I can tell from qbman_init_private_mem(), fbpr_a comes from
> dma_alloc_coherent() and thus would already be a mapped IOVA - isn't
> this the stuff that Roy converted to nicely use shared-dma-pool regions
> a while ago?
I must say that I'm also unclear on this. The thing is that I don't get to see a smmu mapping being created for the reserved memory as result of calling dma_alloc_coherent(). IIRC, at the time when I looked at this I concluded that the call to dma_alloc_coherent() simply returns the phys address of the device's reserved memory without creating a smmu mapping to back it up. Maybe my understanding was not correct or perhaps there's an issue with this shared-dma-pool mechanism where instead of creating a mapping in the smmu and return an IOVA it just returns the physical address of the reserved memory area.
---
Thanks & Best Regards, Laurentiu
>
> > + if (domain) {
> > + ret = iommu_map(domain, fbpr_a, fbpr_a, fbpr_sz,
> > + IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > + if (ret)
> > + dev_warn(dev, "failed to iommu_map() %d\n", ret);
> > + }
> > +
> > bm_set_memory(fbpr_a, fbpr_sz);
> >
> > err_irq = platform_get_irq(pdev, 0);
> >
^ permalink raw reply
* Re: [PATCH v2 2/5] powerpc: module_[32|64].c: replace swap function with built-in one
From: Michael Ellerman @ 2019-04-01 11:08 UTC (permalink / raw)
To: Andrey Abramov, vgupta, benh, paulus, tglx, mingo, bp, hpa, x86,
mark, jlbec, richard, dedekind1, adrian.hunter, gregkh,
naveen.n.rao, jpoimboe, Dave Chinner, darrick.wong,
ard.biesheuvel, George Spelvin, linux-snps-arc,
Linux Kernel Mailing List, linuxppc-dev, ocfs2-devel, linux-mtd,
sfr
Cc: malat, yamada.masahiro, npiggin
In-Reply-To: <14019281554057359@sas1-87f9feb8d943.qloud-c.yandex.net>
Andrey Abramov <st5pub@yandex.ru> writes:
> Replace relaswap with built-in one, because relaswap
> does a simple byte to byte swap.
I replied to v1 with an ack, which stands, this is just a clarification.
> Since Spectre mitigations have made indirect function calls more
> expensive, and the default simple byte copies swap is implemented
> without them, an "optimized" custom swap function is now
> a waste of time as well as code.
Spectre mitigations don't necessarily slow down indirect function calls
on all arches or in all configurations on all arches, so that
justification is a bit dubious.
That's not really a problem for this patch, because the existing
overhead of the function call is probably already enough to rival the
cost of the 24 byte copy.
cheers
^ permalink raw reply
* Re: linux-next: build failure after merge of the sound-asoc tree
From: Michael Ellerman @ 2019-04-01 11:11 UTC (permalink / raw)
To: Mark Brown
Cc: Stephen Rothwell, Liam Girdwood, Annaliese McDermond,
Linux Kernel Mailing List, linuxppc-dev, Linux Next Mailing List,
Paul Mackerras
In-Reply-To: <20190327115745.GA11404@sirena.org.uk>
Mark Brown <broonie@kernel.org> writes:
> On Wed, Mar 27, 2019 at 03:29:55PM +1100, Michael Ellerman wrote:
>> Mark Brown <broonie@kernel.org> writes:
>
>> > Hrm, seems PowerPC is still not using the common clock API - is there
>> > any plan for that? There are some ASoC PowerPC uses so it's going to be
>> > a bit of an issue as we expand our use of the clock API.
>
>> I don't know anything about the common clock API. What would it involve
>> for powerpc to use it?
>
> It's what's in drivers/clk - you'd have to provide clock drivers for all
> the clocks that are current supported by arch-specific code, make sure
> that those drivers can be instantiated and then remove the custom
> implementation of the clock API in arch/powerpc in favour of those.
OK. I realise we do have some support for the common clock API, but only
on certain sub-platforms (PPC_MPC512x, PPC_MPC52xx, PPC_E500MC).
On other platforms we have nothing at all AFAICS.
Seems Ben posted an RFC to support it in 2009, but nothing since:
http://patchwork.ozlabs.org/patch/31551/
Anyway I think what you've done in next, make the code depend on
COMMON_CLOCK, is the best option. If anyone cares about that driver on
powerpc platforms that don't support COMMON_CLOCK they should speak up.
cheers
^ permalink raw reply
* Re: [PATCH] powerpc/rtas: fix early boot failure.
From: Christophe Leroy @ 2019-04-01 11:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Larry Finger
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <aab41779cac995ebdc03e700a9dc7cfc30a28770.1553503163.git.christophe.leroy@c-s.fr>
Michael,
Looks like you missed this fix for rc3.
Christophe
Le 25/03/2019 à 09:43, Christophe Leroy a écrit :
> Commit 0df977eafc79 ("powerpc/6xx: Don't use SPRN_SPRG2 for storing
> stack pointer while in RTAS") changes the code to use a field in
> thread struct to store the stack pointer while in RTAS instead of
> using SPRN_SPRG2. It therefore converts all places which were
> manipulating SPRN_SPRG2 to use that field. During early startup,
> the zeroing of SPRN_SPRG2 has been replaced by a zeroing of that
> field in thread struct. But at least in start_here, that's done
> wrongly because it used the physical address of the fields while
> MMU is on at that time.
>
> So the virtual address of the field should be used instead, but in
> the meantime, thread struct has already been zeroised and initialised
> so we can just drop this initialisation.
>
> Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
> Fixes: 0df977eafc79 ("powerpc/6xx: Don't use SPRN_SPRG2 for storing stack pointer while in RTAS")
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> arch/powerpc/kernel/head_32.S | 8 --------
> 1 file changed, 8 deletions(-)
>
> diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
> index 48051c8977c5..e25b615e9f9e 100644
> --- a/arch/powerpc/kernel/head_32.S
> +++ b/arch/powerpc/kernel/head_32.S
> @@ -851,10 +851,6 @@ __secondary_start:
> tophys(r4,r2)
> addi r4,r4,THREAD /* phys address of our thread_struct */
> mtspr SPRN_SPRG_THREAD,r4
> -#ifdef CONFIG_PPC_RTAS
> - li r3,0
> - stw r3, RTAS_SP(r4) /* 0 => not in RTAS */
> -#endif
> lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
> ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
> mtspr SPRN_SPRG_PGDIR, r4
> @@ -941,10 +937,6 @@ start_here:
> tophys(r4,r2)
> addi r4,r4,THREAD /* init task's THREAD */
> mtspr SPRN_SPRG_THREAD,r4
> -#ifdef CONFIG_PPC_RTAS
> - li r3,0
> - stw r3, RTAS_SP(r4) /* 0 => not in RTAS */
> -#endif
> lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
> ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
> mtspr SPRN_SPRG_PGDIR, r4
>
^ permalink raw reply
* RE: [PATCH 02/13] soc/fsl/bman: map FBPR area in the iommu
From: Laurentiu Tudor @ 2019-04-01 11:15 UTC (permalink / raw)
To: Leo Li
Cc: Madalin-cristian Bucur, Netdev, Roy Pledge, lkml, Linux IOMMU,
Camelia Alexandra Groza, linuxppc-dev, David Miller,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNTPZ1xhYr_YKZvrXVJhVqhV9RNAu6ekVHDeOudXTZx3=g@mail.gmail.com>
Hi Leo,
> -----Original Message-----
> From: Li Yang [mailto:leoyang.li@nxp.com]
> Sent: Friday, March 29, 2019 11:16 PM
>
> On Fri, Mar 29, 2019 at 9:03 AM <laurentiu.tudor@nxp.com> wrote:
> >
> > From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> >
> > Add a one-to-one iommu mapping for bman private data memory (FBPR).
> > This is required for BMAN to work without faults behind an iommu.
> >
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
> > drivers/soc/fsl/qbman/bman_ccsr.c | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c
> b/drivers/soc/fsl/qbman/bman_ccsr.c
> > index 7c3cc968053c..b209c79511bb 100644
> > --- a/drivers/soc/fsl/qbman/bman_ccsr.c
> > +++ b/drivers/soc/fsl/qbman/bman_ccsr.c
> > @@ -29,6 +29,7 @@
> > */
> >
> > #include "bman_priv.h"
> > +#include <linux/iommu.h>
> >
> > u16 bman_ip_rev;
> > EXPORT_SYMBOL(bman_ip_rev);
> > @@ -178,6 +179,7 @@ static int fsl_bman_probe(struct platform_device
> *pdev)
> > int ret, err_irq;
> > struct device *dev = &pdev->dev;
> > struct device_node *node = dev->of_node;
> > + struct iommu_domain *domain;
> > struct resource *res;
> > u16 id, bm_pool_cnt;
> > u8 major, minor;
> > @@ -225,6 +227,15 @@ static int fsl_bman_probe(struct platform_device
> *pdev)
> >
> > dev_dbg(dev, "Allocated FBPR 0x%llx 0x%zx\n", fbpr_a, fbpr_sz);
> >
> > + /* Create an 1-to-1 iommu mapping for FBPR area */
> > + domain = iommu_get_domain_for_dev(dev);
> > + if (domain) {
> > + ret = iommu_map(domain, fbpr_a, fbpr_a, fbpr_sz,
> > + IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE);
> > + if (ret)
> > + dev_warn(dev, "failed to iommu_map() %d\n",
> ret);
> > + }
>
> Like Robin has pointed out, could you explain why the mapping in this
> patch and other similar patches cannot be dealt with the dma APIs
> automatically? If the current bqman driver doesn't use the dma APIs
> correctly, we need to fix that instead of doing the mapping
> explicitly.
Please see my reply to Robin.
As a side comment, if we want to convert to dma api it will be interesting to see how we'll deal with the qman portal devices as they require a smmu mapping for an area of their register block (where stashing goes). Problem is they treated as distinct devices, the address where they should dma cannot be configured independently for each one of them. I think I can came up with a proposal but probably will not look very pretty.
---
Best Regards, Laurentiu
> > +
> > bm_set_memory(fbpr_a, fbpr_sz);
> >
> > err_irq = platform_get_irq(pdev, 0);
> > --
> > 2.17.1
> >
^ permalink raw reply
* [PATCH] ASoC: fsl_esai: Support synchronous mode
From: S.j. Wang @ 2019-04-01 11:39 UTC (permalink / raw)
To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com,
festevam@gmail.com, broonie@kernel.org,
alsa-devel@alsa-project.org
Cc: linuxppc-dev@lists.ozlabs.org
In ESAI synchronous mode, the clock is generated by Tx, So
we should always set registers of Tx which relate with the
bit clock and frame clock generation (TCCR, TCR, ECR), even
there is only Rx is working.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_esai.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 3623aa9a6f2e..d9fcddd55c02 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -230,6 +230,21 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
return -EINVAL;
}
+ if (esai_priv->synchronous && !tx) {
+ switch (clk_id) {
+ case ESAI_HCKR_FSYS:
+ fsl_esai_set_dai_sysclk(dai, ESAI_HCKT_FSYS,
+ freq, dir);
+ break;
+ case ESAI_HCKR_EXTAL:
+ fsl_esai_set_dai_sysclk(dai, ESAI_HCKT_EXTAL,
+ freq, dir);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
/* Bypass divider settings if the requirement doesn't change */
if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
return 0;
@@ -537,10 +552,21 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
bclk = params_rate(params) * slot_width * esai_priv->slots;
- ret = fsl_esai_set_bclk(dai, tx, bclk);
+ ret = fsl_esai_set_bclk(dai, esai_priv->synchronous ? true : tx, bclk);
if (ret)
return ret;
+ if (esai_priv->synchronous && !tx) {
+ /* Use Normal mode to support monaural audio */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
+ ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
+ ESAI_xCR_xMOD_NETWORK : 0);
+
+ mask = ESAI_xCR_xSWS_MASK | ESAI_xCR_PADC;
+ val = ESAI_xCR_xSWS(slot_width, width) | ESAI_xCR_PADC;
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
+ }
+
/* Use Normal mode to support monaural audio */
regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 03/12] PowerPC-83xx: add missing of_node_put after of_device_is_available
From: Mukesh Ojha @ 2019-04-01 12:49 UTC (permalink / raw)
To: Julia Lawall, Scott Wood
Cc: kernel-janitors, linux-kernel, Paul Mackerras, linuxppc-dev
In-Reply-To: <1550928043-14889-4-git-send-email-Julia.Lawall@lip6.fr>
On 2/23/2019 6:50 PM, Julia Lawall wrote:
> Add an of_node_put when a tested device node is not available.
>
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> identifier f;
> local idexpression e;
> expression x;
> @@
>
> e = f(...);
> ... when != of_node_put(e)
> when != x = e
> when != e = x
> when any
> if (<+...of_device_is_available(e)...+>) {
> ... when != of_node_put(e)
> (
> return e;
> |
> + of_node_put(e);
> return ...;
> )
> }
> // </smpl>
>
> Fixes: c026c98739c7e ("powerpc/83xx: Do not configure or probe disabled FSL DR USB controllers")
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Reviewed-by: Mukesh Ojha <mojha@codeaurora.org>
Cheers,
-Mukesh
>
> ---
> arch/powerpc/platforms/83xx/usb.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff -u -p a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
> --- a/arch/powerpc/platforms/83xx/usb.c
> +++ b/arch/powerpc/platforms/83xx/usb.c
> @@ -221,8 +221,10 @@ int mpc837x_usb_cfg(void)
> int ret = 0;
>
> np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
> - if (!np || !of_device_is_available(np))
> + if (!np || !of_device_is_available(np)) {
> + of_node_put(np);
> return -ENODEV;
> + }
> prop = of_get_property(np, "phy_type", NULL);
>
> if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) {
>
^ permalink raw reply
* [PATCH 6/6 v3] syscalls: Remove start and number from syscall_set_arguments() args
From: Steven Rostedt @ 2019-04-01 13:41 UTC (permalink / raw)
To: linux-kernel
Cc: linux-ia64, Gustavo A. R. Silva, Peter Zijlstra, Palmer Dabbelt,
Dominik Brodowski, Dmitry V. Levin, H. Peter Anvin, sparclinux,
linux-riscv, Ingo Molnar, linux-arch, linux-s390, linux-c6x-dev,
linux-sh, linux-hexagon, x86, Ingo Molnar, linux-snps-arc,
Dave Martin, uclinux-h8-devel, linux-xtensa, Kees Cook,
Roland McGrath, linux-um, linux-mips, openrisc, Borislav Petkov,
Andy Lutomirski, Thomas Gleixner, linux-arm-kernel, linux-parisc,
linuxppc-dev, Oleg Nesterov, Andy Lutomirski, Eric W. Biederman,
nios2-dev, Andrew Morton, Linus Torvalds
In-Reply-To: <20190401134104.676620247@goodmis.org>
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
After removing the start and count arguments of syscall_get_arguments() it
seems reasonable to remove them from syscall_set_arguments(). Note, as of
today, there are no users of syscall_set_arguments(). But we are told that
there will be soon. But for now, at least make it consistent with
syscall_get_arguments().
Link: http://lkml.kernel.org/r/20190327222014.GA32540@altlinux.org
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Dave Martin <dave.martin@arm.com>
Cc: "Dmitry V. Levin" <ldv@altlinux.org>
Cc: x86@kernel.org
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: uclinux-h8-devel@lists.sourceforge.jp
Cc: linux-hexagon@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Cc: nios2-dev@lists.rocketboards.org
Cc: openrisc@lists.librecores.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linux-um@lists.infradead.org
Cc: linux-xtensa@linux-xtensa.org
Cc: linux-arch@vger.kernel.org
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
arch/arm/include/asm/syscall.h | 22 ++-------
arch/arm64/include/asm/syscall.h | 22 ++-------
arch/c6x/include/asm/syscall.h | 38 +++------------
arch/csky/include/asm/syscall.h | 14 ++----
arch/ia64/include/asm/syscall.h | 10 ++--
arch/ia64/kernel/ptrace.c | 7 ++-
arch/microblaze/include/asm/syscall.h | 4 +-
arch/nds32/include/asm/syscall.h | 29 ++---------
arch/nios2/include/asm/syscall.h | 42 +++-------------
arch/openrisc/include/asm/syscall.h | 6 +--
arch/powerpc/include/asm/syscall.h | 7 +--
arch/riscv/include/asm/syscall.h | 13 ++---
arch/s390/include/asm/syscall.h | 11 ++---
arch/sh/include/asm/syscall_32.h | 21 +++-----
arch/sh/include/asm/syscall_64.h | 4 +-
arch/sparc/include/asm/syscall.h | 7 ++-
arch/um/include/asm/syscall-generic.h | 39 +++------------
arch/x86/include/asm/syscall.h | 69 +++++++--------------------
arch/xtensa/include/asm/syscall.h | 17 ++-----
include/asm-generic/syscall.h | 10 +---
20 files changed, 88 insertions(+), 304 deletions(-)
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
index db969a2972ae..080ce70cab12 100644
--- a/arch/arm/include/asm/syscall.h
+++ b/arch/arm/include/asm/syscall.h
@@ -65,26 +65,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- if (n == 0)
- return;
-
- if (i + n > SYSCALL_MAX_ARGS) {
- pr_warn("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- n = SYSCALL_MAX_ARGS - i;
- }
-
- if (i == 0) {
- regs->ARM_ORIG_r0 = args[0];
- args++;
- i++;
- n--;
- }
-
- memcpy(®s->ARM_r0 + i, args, n * sizeof(args[0]));
+ regs->ARM_ORIG_r0 = args[0];
+ args++;
+
+ memcpy(®s->ARM_r0 + 1, args, 5 * sizeof(args[0]));
}
static inline int syscall_get_arch(void)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 55b2dab21023..a179df3674a1 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -75,26 +75,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- if (n == 0)
- return;
-
- if (i + n > SYSCALL_MAX_ARGS) {
- pr_warning("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- n = SYSCALL_MAX_ARGS - i;
- }
-
- if (i == 0) {
- regs->orig_x0 = args[0];
- args++;
- i++;
- n--;
- }
-
- memcpy(®s->regs[i], args, n * sizeof(args[0]));
+ regs->orig_x0 = args[0];
+ args++;
+
+ memcpy(®s->regs[1], args, 5 * sizeof(args[0]));
}
/*
diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h
index 06db3251926b..15ba8599858e 100644
--- a/arch/c6x/include/asm/syscall.h
+++ b/arch/c6x/include/asm/syscall.h
@@ -59,40 +59,14 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- switch (i) {
- case 0:
- if (!n--)
- break;
- regs->a4 = *args++;
- case 1:
- if (!n--)
- break;
- regs->b4 = *args++;
- case 2:
- if (!n--)
- break;
- regs->a6 = *args++;
- case 3:
- if (!n--)
- break;
- regs->b6 = *args++;
- case 4:
- if (!n--)
- break;
- regs->a8 = *args++;
- case 5:
- if (!n--)
- break;
- regs->a9 = *args++;
- case 6:
- if (!n)
- break;
- default:
- BUG();
- }
+ regs->a4 = *args++;
+ regs->b4 = *args++;
+ regs->a6 = *args++;
+ regs->b6 = *args++;
+ regs->a8 = *args++;
+ regs->a9 = *args;
}
#endif /* __ASM_C6X_SYSCALLS_H */
diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h
index c691fe92edc6..bda0a446c63e 100644
--- a/arch/csky/include/asm/syscall.h
+++ b/arch/csky/include/asm/syscall.h
@@ -52,17 +52,11 @@ syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
static inline void
syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, const unsigned long *args)
+ const unsigned long *args)
{
- BUG_ON(i + n > 6);
- if (i == 0) {
- regs->orig_a0 = args[0];
- args++;
- n--;
- } else {
- i--;
- }
- memcpy(®s->a1 + i, args, n * sizeof(regs->a1));
+ regs->orig_a0 = args[0];
+ args++;
+ memcpy(®s->a1, args, 5 * sizeof(regs->a1));
}
static inline int
diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index 8204c1ff70ce..0d9e7fab4a79 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -59,23 +59,19 @@ static inline void syscall_set_return_value(struct task_struct *task,
}
extern void ia64_syscall_get_set_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned int i, unsigned int n,
- unsigned long *args, int rw);
+ struct pt_regs *regs, unsigned long *args, int rw);
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned long *args)
{
- ia64_syscall_get_set_arguments(task, regs, 0, 6, args, 0);
+ ia64_syscall_get_set_arguments(task, regs, args, 0);
}
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
+ ia64_syscall_get_set_arguments(task, regs, args, 1);
}
static inline int syscall_get_arch(void)
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 6d50ede0ed69..bf9c24d9ce84 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -2179,12 +2179,11 @@ static void syscall_get_set_args_cb(struct unw_frame_info *info, void *data)
}
void ia64_syscall_get_set_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned int i, unsigned int n,
- unsigned long *args, int rw)
+ struct pt_regs *regs, unsigned long *args, int rw)
{
struct syscall_get_set_args data = {
- .i = i,
- .n = n,
+ .i = 0,
+ .n = 6,
.args = args,
.regs = regs,
.rw = rw,
diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h
index 4b23e44e5c3c..833d3a53dab3 100644
--- a/arch/microblaze/include/asm/syscall.h
+++ b/arch/microblaze/include/asm/syscall.h
@@ -93,9 +93,11 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
+ unsigned int i = 0;
+ unsigned int n = 6;
+
while (n--)
microblaze_set_syscall_arg(regs, i++, *args++);
}
diff --git a/arch/nds32/include/asm/syscall.h b/arch/nds32/include/asm/syscall.h
index 89a6ec8731d8..671ebd357496 100644
--- a/arch/nds32/include/asm/syscall.h
+++ b/arch/nds32/include/asm/syscall.h
@@ -129,39 +129,20 @@ void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
* syscall_set_arguments - change system call parameter value
* @task: task of interest, must be in system call entry tracing
* @regs: task_pt_regs() of @task
- * @i: argument index [0,5]
- * @n: number of arguments; n+i must be [1,6].
* @args: array of argument values to store
*
- * Changes @n arguments to the system call starting with the @i'th argument.
- * Argument @i gets value @args[0], and so on.
- * An arch inline version is probably optimal when @i and @n are constants.
+ * Changes 6 arguments to the system call. The first argument gets value
+ * @args[0], and so on.
*
* It's only valid to call this when @task is stopped for tracing on
* entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- * It's invalid to call this with @i + @n > 6; we only support system calls
- * taking up to 6 arguments.
*/
void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- if (n == 0)
- return;
-
- if (i + n > SYSCALL_MAX_ARGS) {
- pr_warn("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- n = SYSCALL_MAX_ARGS - i;
- }
-
- if (i == 0) {
- regs->orig_r0 = args[0];
- args++;
- i++;
- n--;
- }
+ regs->orig_r0 = args[0];
+ args++;
- memcpy(®s->uregs[0] + i, args, n * sizeof(args[0]));
+ memcpy(®s->uregs[0] + 1, args, 5 * sizeof(args[0]));
}
#endif /* _ASM_NDS32_SYSCALL_H */
diff --git a/arch/nios2/include/asm/syscall.h b/arch/nios2/include/asm/syscall.h
index 792bd449d839..d7624ed06efb 100644
--- a/arch/nios2/include/asm/syscall.h
+++ b/arch/nios2/include/asm/syscall.h
@@ -69,42 +69,14 @@ static inline void syscall_get_arguments(struct task_struct *task,
}
static inline void syscall_set_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned int i, unsigned int n,
- const unsigned long *args)
+ struct pt_regs *regs, const unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- switch (i) {
- case 0:
- if (!n--)
- break;
- regs->r4 = *args++;
- case 1:
- if (!n--)
- break;
- regs->r5 = *args++;
- case 2:
- if (!n--)
- break;
- regs->r6 = *args++;
- case 3:
- if (!n--)
- break;
- regs->r7 = *args++;
- case 4:
- if (!n--)
- break;
- regs->r8 = *args++;
- case 5:
- if (!n--)
- break;
- regs->r9 = *args++;
- case 6:
- if (!n)
- break;
- default:
- BUG();
- }
+ regs->r4 = *args++;
+ regs->r5 = *args++;
+ regs->r6 = *args++;
+ regs->r7 = *args++;
+ regs->r8 = *args++;
+ regs->r9 = *args;
}
#endif
diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h
index 72607860cd55..b4ff07c1baed 100644
--- a/arch/openrisc/include/asm/syscall.h
+++ b/arch/openrisc/include/asm/syscall.h
@@ -63,11 +63,9 @@ syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
static inline void
syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, const unsigned long *args)
+ const unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- memcpy(®s->gpr[3 + i], args, n * sizeof(args[0]));
+ memcpy(®s->gpr[3], args, 6 * sizeof(args[0]));
}
static inline int syscall_get_arch(void)
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 5c9b9dc82b7e..1243045bad2d 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -86,15 +86,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- BUG_ON(i + n > 6);
- memcpy(®s->gpr[3 + i], args, n * sizeof(args[0]));
+ memcpy(®s->gpr[3], args, 6 * sizeof(args[0]));
/* Also copy the first argument into orig_gpr3 */
- if (i == 0 && n > 0)
- regs->orig_gpr3 = args[0];
+ regs->orig_gpr3 = args[0];
}
static inline int syscall_get_arch(void)
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 6adca1804be1..a3d5273ded7c 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -81,18 +81,11 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- BUG_ON(i + n > 6);
- if (i == 0) {
- regs->orig_a0 = args[0];
- args++;
- n--;
- } else {
- i--;
- }
- memcpy(®s->a1 + i, args, n * sizeof(regs->a1));
+ regs->orig_a0 = args[0];
+ args++;
+ memcpy(®s->a1, args, 5 * sizeof(regs->a1));
}
static inline int syscall_get_arch(void)
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index ee0b1f6aa36d..59c3e91f2cdb 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -74,15 +74,14 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- BUG_ON(i + n > 6);
+ unsigned int n = 6;
+
while (n-- > 0)
- if (i + n > 0)
- regs->gprs[2 + i + n] = args[n];
- if (i == 0)
- regs->orig_gpr2 = args[0];
+ if (n > 0)
+ regs->gprs[2 + n] = args[n];
+ regs->orig_gpr2 = args[0];
}
static inline int syscall_get_arch(void)
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 2bf1199a0595..8c9d7e5e5dcc 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -62,23 +62,14 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- /* Same note as above applies */
- BUG_ON(i);
-
- switch (n) {
- case 6: regs->regs[1] = args[5];
- case 5: regs->regs[0] = args[4];
- case 4: regs->regs[7] = args[3];
- case 3: regs->regs[6] = args[2];
- case 2: regs->regs[5] = args[1];
- case 1: regs->regs[4] = args[0];
- break;
- default:
- BUG();
- }
+ regs->regs[1] = args[5];
+ regs->regs[0] = args[4];
+ regs->regs[7] = args[3];
+ regs->regs[6] = args[2];
+ regs->regs[5] = args[1];
+ regs->regs[4] = args[0];
}
static inline int syscall_get_arch(void)
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index 4e8f6460c703..22fad97da066 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -54,11 +54,9 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- BUG_ON(i + n > 6);
- memcpy(®s->regs[2 + i], args, n * sizeof(args[0]));
+ memcpy(®s->regs[2], args, 6 * sizeof(args[0]));
}
static inline int syscall_get_arch(void)
diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h
index 872dfee852d6..4d075434e816 100644
--- a/arch/sparc/include/asm/syscall.h
+++ b/arch/sparc/include/asm/syscall.h
@@ -119,13 +119,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
- unsigned int j;
+ unsigned int i;
- for (j = 0; j < n; j++)
- regs->u_regs[UREG_I0 + i + j] = args[j];
+ for (i = 0; i < 6; i++)
+ regs->u_regs[UREG_I0 + i] = args[i];
}
static inline int syscall_get_arch(void)
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
index 25d00acd1322..98e50c50c12e 100644
--- a/arch/um/include/asm/syscall-generic.h
+++ b/arch/um/include/asm/syscall-generic.h
@@ -67,43 +67,16 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
struct uml_pt_regs *r = ®s->regs;
- switch (i) {
- case 0:
- if (!n--)
- break;
- UPT_SYSCALL_ARG1(r) = *args++;
- case 1:
- if (!n--)
- break;
- UPT_SYSCALL_ARG2(r) = *args++;
- case 2:
- if (!n--)
- break;
- UPT_SYSCALL_ARG3(r) = *args++;
- case 3:
- if (!n--)
- break;
- UPT_SYSCALL_ARG4(r) = *args++;
- case 4:
- if (!n--)
- break;
- UPT_SYSCALL_ARG5(r) = *args++;
- case 5:
- if (!n--)
- break;
- UPT_SYSCALL_ARG6(r) = *args++;
- case 6:
- if (!n--)
- break;
- default:
- BUG();
- break;
- }
+ UPT_SYSCALL_ARG1(r) = *args++;
+ UPT_SYSCALL_ARG2(r) = *args++;
+ UPT_SYSCALL_ARG3(r) = *args++;
+ UPT_SYSCALL_ARG4(r) = *args++;
+ UPT_SYSCALL_ARG5(r) = *args++;
+ UPT_SYSCALL_ARG6(r) = *args;
}
/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index 8dbb5c379450..4c305471ec33 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -138,63 +138,26 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
# ifdef CONFIG_IA32_EMULATION
- if (task->thread_info.status & TS_COMPAT)
- switch (i) {
- case 0:
- if (!n--) break;
- regs->bx = *args++;
- case 1:
- if (!n--) break;
- regs->cx = *args++;
- case 2:
- if (!n--) break;
- regs->dx = *args++;
- case 3:
- if (!n--) break;
- regs->si = *args++;
- case 4:
- if (!n--) break;
- regs->di = *args++;
- case 5:
- if (!n--) break;
- regs->bp = *args++;
- case 6:
- if (!n--) break;
- default:
- BUG();
- break;
- }
- else
+ if (task->thread_info.status & TS_COMPAT) {
+ regs->bx = *args++;
+ regs->cx = *args++;
+ regs->dx = *args++;
+ regs->si = *args++;
+ regs->di = *args++;
+ regs->bp = *args;
+ } else
# endif
- switch (i) {
- case 0:
- if (!n--) break;
- regs->di = *args++;
- case 1:
- if (!n--) break;
- regs->si = *args++;
- case 2:
- if (!n--) break;
- regs->dx = *args++;
- case 3:
- if (!n--) break;
- regs->r10 = *args++;
- case 4:
- if (!n--) break;
- regs->r8 = *args++;
- case 5:
- if (!n--) break;
- regs->r9 = *args++;
- case 6:
- if (!n--) break;
- default:
- BUG();
- break;
- }
+ {
+ regs->di = *args++;
+ regs->si = *args++;
+ regs->dx = *args++;
+ regs->r10 = *args++;
+ regs->r8 = *args++;
+ regs->r9 = *args;
+ }
}
static inline int syscall_get_arch(void)
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index 1504ce9a233a..91dc06d58060 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -70,24 +70,13 @@ static inline void syscall_get_arguments(struct task_struct *task,
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args)
{
static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS;
- unsigned int j;
-
- if (n == 0)
- return;
-
- if (WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS)) {
- if (i < SYSCALL_MAX_ARGS)
- n = SYSCALL_MAX_ARGS - i;
- else
- return;
- }
+ unsigned int i;
- for (j = 0; j < n; ++j)
- regs->areg[reg[i + j]] = args[j];
+ for (i = 0; i < 6; ++i)
+ regs->areg[reg[i]] = args[i];
}
asmlinkage long xtensa_rt_sigreturn(struct pt_regs*);
diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 269e9412ef42..b88239e9efe4 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -120,21 +120,15 @@ void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
* syscall_set_arguments - change system call parameter value
* @task: task of interest, must be in system call entry tracing
* @regs: task_pt_regs() of @task
- * @i: argument index [0,5]
- * @n: number of arguments; n+i must be [1,6].
* @args: array of argument values to store
*
- * Changes @n arguments to the system call starting with the @i'th argument.
- * Argument @i gets value @args[0], and so on.
- * An arch inline version is probably optimal when @i and @n are constants.
+ * Changes 6 arguments to the system call.
+ * The first argument gets value @args[0], and so on.
*
* It's only valid to call this when @task is stopped for tracing on
* entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- * It's invalid to call this with @i + @n > 6; we only support system calls
- * taking up to 6 arguments.
*/
void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n,
const unsigned long *args);
/**
--
2.20.1
^ permalink raw reply related
* [PATCH 5/6 v3] syscalls: Remove start and number from syscall_get_arguments() args
From: Steven Rostedt @ 2019-04-01 13:41 UTC (permalink / raw)
To: linux-kernel
Cc: linux-ia64, Gustavo A. R. Silva, Peter Zijlstra, Palmer Dabbelt,
Dominik Brodowski, Dmitry V. Levin, H. Peter Anvin, sparclinux,
linux-riscv, Ingo Molnar, linux-arch, linux-s390, linux-c6x-dev,
linux-sh, linux-hexagon, x86, Ingo Molnar, linux-snps-arc,
Dave Martin, uclinux-h8-devel, linux-xtensa, Kees Cook,
Roland McGrath, linux-um, linux-mips, openrisc, Borislav Petkov,
Andy Lutomirski, Thomas Gleixner, linux-arm-kernel, linux-parisc,
linuxppc-dev, Oleg Nesterov, Andy Lutomirski, Eric W. Biederman,
nios2-dev, Andrew Morton, Linus Torvalds
In-Reply-To: <20190401134104.676620247@goodmis.org>
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
At Linux Plumbers, Andy Lutomirski approached me and pointed out that the
function call syscall_get_arguments() implemented in x86 was horribly
written and not optimized for the standard case of passing in 0 and 6 for
the starting index and the number of system calls to get. When looking at
all the users of this function, I discovered that all instances pass in only
0 and 6 for these arguments. Instead of having this function handle
different cases that are never used, simply rewrite it to return the first 6
arguments of a system call.
This should help out the performance of tracing system calls by ptrace,
ftrace and perf.
Link: http://lkml.kernel.org/r/20161107213233.754809394@goodmis.org
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Dave Martin <dave.martin@arm.com>
Cc: "Dmitry V. Levin" <ldv@altlinux.org>
Cc: x86@kernel.org
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: uclinux-h8-devel@lists.sourceforge.jp
Cc: linux-hexagon@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Cc: nios2-dev@lists.rocketboards.org
Cc: openrisc@lists.librecores.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linux-um@lists.infradead.org
Cc: linux-xtensa@linux-xtensa.org
Cc: linux-arch@vger.kernel.org
Reported-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
arch/arc/include/asm/syscall.h | 7 ++-
arch/arm/include/asm/syscall.h | 23 ++-------
arch/arm64/include/asm/syscall.h | 22 ++------
arch/c6x/include/asm/syscall.h | 41 +++------------
arch/csky/include/asm/syscall.h | 14 ++---
arch/h8300/include/asm/syscall.h | 34 +++----------
arch/hexagon/include/asm/syscall.h | 4 +-
arch/ia64/include/asm/syscall.h | 5 +-
arch/microblaze/include/asm/syscall.h | 4 +-
arch/mips/include/asm/syscall.h | 3 +-
arch/mips/kernel/ptrace.c | 2 +-
arch/nds32/include/asm/syscall.h | 33 +++---------
arch/nios2/include/asm/syscall.h | 42 +++------------
arch/openrisc/include/asm/syscall.h | 6 +--
arch/parisc/include/asm/syscall.h | 30 +++--------
arch/powerpc/include/asm/syscall.h | 8 ++-
arch/riscv/include/asm/syscall.h | 13 ++---
arch/s390/include/asm/syscall.h | 17 ++-----
arch/sh/include/asm/syscall_32.h | 26 +++-------
arch/sh/include/asm/syscall_64.h | 4 +-
arch/sparc/include/asm/syscall.h | 4 +-
arch/um/include/asm/syscall-generic.h | 39 +++-----------
arch/x86/include/asm/syscall.h | 73 +++++++--------------------
arch/xtensa/include/asm/syscall.h | 16 ++----
include/asm-generic/syscall.h | 11 ++--
include/trace/events/syscalls.h | 2 +-
kernel/seccomp.c | 2 +-
kernel/trace/trace_syscalls.c | 4 +-
lib/syscall.c | 2 +-
29 files changed, 113 insertions(+), 378 deletions(-)
diff --git a/arch/arc/include/asm/syscall.h b/arch/arc/include/asm/syscall.h
index 29de09804306..c7a4201ed62b 100644
--- a/arch/arc/include/asm/syscall.h
+++ b/arch/arc/include/asm/syscall.h
@@ -55,12 +55,11 @@ syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
*/
static inline void
syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args)
+ unsigned long *args)
{
unsigned long *inside_ptregs = &(regs->r0);
- inside_ptregs -= i;
-
- BUG_ON((i + n) > 6);
+ unsigned int n = 6;
+ unsigned int i = 0;
while (n--) {
args[i++] = (*inside_ptregs);
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
index 06dea6bce293..db969a2972ae 100644
--- a/arch/arm/include/asm/syscall.h
+++ b/arch/arm/include/asm/syscall.h
@@ -55,29 +55,12 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- if (n == 0)
- return;
-
- if (i + n > SYSCALL_MAX_ARGS) {
- unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
- unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
- pr_warn("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- memset(args_bad, 0, n_bad * sizeof(args[0]));
- n = SYSCALL_MAX_ARGS - i;
- }
-
- if (i == 0) {
- args[0] = regs->ARM_ORIG_r0;
- args++;
- i++;
- n--;
- }
+ args[0] = regs->ARM_ORIG_r0;
+ args++;
- memcpy(args, ®s->ARM_r0 + i, n * sizeof(args[0]));
+ memcpy(args, ®s->ARM_r0 + 1, 5 * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index ad8be16a39c9..55b2dab21023 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -65,28 +65,12 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- if (n == 0)
- return;
-
- if (i + n > SYSCALL_MAX_ARGS) {
- unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
- unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
- pr_warning("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- memset(args_bad, 0, n_bad * sizeof(args[0]));
- }
-
- if (i == 0) {
- args[0] = regs->orig_x0;
- args++;
- i++;
- n--;
- }
+ args[0] = regs->orig_x0;
+ args++;
- memcpy(args, ®s->regs[i], n * sizeof(args[0]));
+ memcpy(args, ®s->regs[1], 5 * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h
index ae2be315ee9c..06db3251926b 100644
--- a/arch/c6x/include/asm/syscall.h
+++ b/arch/c6x/include/asm/syscall.h
@@ -46,40 +46,15 @@ static inline void syscall_set_return_value(struct task_struct *task,
}
static inline void syscall_get_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned int i,
- unsigned int n, unsigned long *args)
+ struct pt_regs *regs,
+ unsigned long *args)
{
- switch (i) {
- case 0:
- if (!n--)
- break;
- *args++ = regs->a4;
- case 1:
- if (!n--)
- break;
- *args++ = regs->b4;
- case 2:
- if (!n--)
- break;
- *args++ = regs->a6;
- case 3:
- if (!n--)
- break;
- *args++ = regs->b6;
- case 4:
- if (!n--)
- break;
- *args++ = regs->a8;
- case 5:
- if (!n--)
- break;
- *args++ = regs->b8;
- case 6:
- if (!n--)
- break;
- default:
- BUG();
- }
+ *args++ = regs->a4;
+ *args++ = regs->b4;
+ *args++ = regs->a6;
+ *args++ = regs->b6;
+ *args++ = regs->a8;
+ *args = regs->b8;
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/csky/include/asm/syscall.h b/arch/csky/include/asm/syscall.h
index 9a9cd81e66c1..c691fe92edc6 100644
--- a/arch/csky/include/asm/syscall.h
+++ b/arch/csky/include/asm/syscall.h
@@ -43,17 +43,11 @@ syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
static inline void
syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args)
+ unsigned long *args)
{
- BUG_ON(i + n > 6);
- if (i == 0) {
- args[0] = regs->orig_a0;
- args++;
- n--;
- } else {
- i--;
- }
- memcpy(args, ®s->a1 + i, n * sizeof(args[0]));
+ args[0] = regs->orig_a0;
+ args++;
+ memcpy(args, ®s->a1, 5 * sizeof(args[0]));
}
static inline void
diff --git a/arch/h8300/include/asm/syscall.h b/arch/h8300/include/asm/syscall.h
index 924990401237..ddd483c6ca95 100644
--- a/arch/h8300/include/asm/syscall.h
+++ b/arch/h8300/include/asm/syscall.h
@@ -17,34 +17,14 @@ syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
static inline void
syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args)
+ unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- while (n > 0) {
- switch (i) {
- case 0:
- *args++ = regs->er1;
- break;
- case 1:
- *args++ = regs->er2;
- break;
- case 2:
- *args++ = regs->er3;
- break;
- case 3:
- *args++ = regs->er4;
- break;
- case 4:
- *args++ = regs->er5;
- break;
- case 5:
- *args++ = regs->er6;
- break;
- }
- i++;
- n--;
- }
+ *args++ = regs->er1;
+ *args++ = regs->er2;
+ *args++ = regs->er3;
+ *args++ = regs->er4;
+ *args++ = regs->er5;
+ *args = regs->er6;
}
diff --git a/arch/hexagon/include/asm/syscall.h b/arch/hexagon/include/asm/syscall.h
index 4af9c7b6f13a..ae3a1e24fabd 100644
--- a/arch/hexagon/include/asm/syscall.h
+++ b/arch/hexagon/include/asm/syscall.h
@@ -37,10 +37,8 @@ static inline long syscall_get_nr(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
- memcpy(args, &(®s->r00)[i], n * sizeof(args[0]));
+ memcpy(args, &(®s->r00)[0], 6 * sizeof(args[0]));
}
#endif
diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index 1d0b875fec44..8204c1ff70ce 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -63,12 +63,9 @@ extern void ia64_syscall_get_set_arguments(struct task_struct *task,
unsigned long *args, int rw);
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
+ ia64_syscall_get_set_arguments(task, regs, 0, 6, args, 0);
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h
index 220decd605a4..4b23e44e5c3c 100644
--- a/arch/microblaze/include/asm/syscall.h
+++ b/arch/microblaze/include/asm/syscall.h
@@ -82,9 +82,11 @@ static inline void microblaze_set_syscall_arg(struct pt_regs *regs,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
+ unsigned int i = 0;
+ unsigned int n = 6;
+
while (n--)
*args++ = microblaze_get_syscall_arg(regs, i++);
}
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
index 6cf8ffb5367e..a2b4748655df 100644
--- a/arch/mips/include/asm/syscall.h
+++ b/arch/mips/include/asm/syscall.h
@@ -116,9 +116,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
+ unsigned int i = 0;
+ unsigned int n = 6;
int ret;
/* O32 ABI syscall() */
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 0057c910bc2f..3a62f80958e1 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -1419,7 +1419,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
sd.nr = syscall;
sd.arch = syscall_get_arch();
- syscall_get_arguments(current, regs, 0, 6, args);
+ syscall_get_arguments(current, regs, args);
for (i = 0; i < 6; i++)
sd.args[i] = args[i];
sd.instruction_pointer = KSTK_EIP(current);
diff --git a/arch/nds32/include/asm/syscall.h b/arch/nds32/include/asm/syscall.h
index f7e5e86765fe..89a6ec8731d8 100644
--- a/arch/nds32/include/asm/syscall.h
+++ b/arch/nds32/include/asm/syscall.h
@@ -108,42 +108,21 @@ void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
* syscall_get_arguments - extract system call parameter values
* @task: task of interest, must be blocked
* @regs: task_pt_regs() of @task
- * @i: argument index [0,5]
- * @n: number of arguments; n+i must be [1,6].
* @args: array filled with argument values
*
- * Fetches @n arguments to the system call starting with the @i'th argument
- * (from 0 through 5). Argument @i is stored in @args[0], and so on.
- * An arch inline version is probably optimal when @i and @n are constants.
+ * Fetches 6 arguments to the system call (from 0 through 5). The first
+ * argument is stored in @args[0], and so on.
*
* It's only valid to call this when @task is stopped for tracing on
* entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- * It's invalid to call this with @i + @n > 6; we only support system calls
- * taking up to 6 arguments.
*/
#define SYSCALL_MAX_ARGS 6
void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args)
+ unsigned long *args)
{
- if (n == 0)
- return;
- if (i + n > SYSCALL_MAX_ARGS) {
- unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
- unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
- pr_warning("%s called with max args %d, handling only %d\n",
- __func__, i + n, SYSCALL_MAX_ARGS);
- memset(args_bad, 0, n_bad * sizeof(args[0]));
- memset(args_bad, 0, n_bad * sizeof(args[0]));
- }
-
- if (i == 0) {
- args[0] = regs->orig_r0;
- args++;
- i++;
- n--;
- }
-
- memcpy(args, ®s->uregs[0] + i, n * sizeof(args[0]));
+ args[0] = regs->orig_r0;
+ args++;
+ memcpy(args, ®s->uregs[0] + 1, 5 * sizeof(args[0]));
}
/**
diff --git a/arch/nios2/include/asm/syscall.h b/arch/nios2/include/asm/syscall.h
index 9de220854c4a..792bd449d839 100644
--- a/arch/nios2/include/asm/syscall.h
+++ b/arch/nios2/include/asm/syscall.h
@@ -58,42 +58,14 @@ static inline void syscall_set_return_value(struct task_struct *task,
}
static inline void syscall_get_arguments(struct task_struct *task,
- struct pt_regs *regs, unsigned int i, unsigned int n,
- unsigned long *args)
+ struct pt_regs *regs, unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- switch (i) {
- case 0:
- if (!n--)
- break;
- *args++ = regs->r4;
- case 1:
- if (!n--)
- break;
- *args++ = regs->r5;
- case 2:
- if (!n--)
- break;
- *args++ = regs->r6;
- case 3:
- if (!n--)
- break;
- *args++ = regs->r7;
- case 4:
- if (!n--)
- break;
- *args++ = regs->r8;
- case 5:
- if (!n--)
- break;
- *args++ = regs->r9;
- case 6:
- if (!n--)
- break;
- default:
- BUG();
- }
+ *args++ = regs->r4;
+ *args++ = regs->r5;
+ *args++ = regs->r6;
+ *args++ = regs->r7;
+ *args++ = regs->r8;
+ *args = regs->r9;
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h
index 2db9f1cf0694..72607860cd55 100644
--- a/arch/openrisc/include/asm/syscall.h
+++ b/arch/openrisc/include/asm/syscall.h
@@ -56,11 +56,9 @@ syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
static inline void
syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args)
+ unsigned long *args)
{
- BUG_ON(i + n > 6);
-
- memcpy(args, ®s->gpr[3 + i], n * sizeof(args[0]));
+ memcpy(args, ®s->gpr[3], 6 * sizeof(args[0]));
}
static inline void
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h
index 8bff1a58c97f..62a6d477fae0 100644
--- a/arch/parisc/include/asm/syscall.h
+++ b/arch/parisc/include/asm/syscall.h
@@ -18,29 +18,15 @@ static inline long syscall_get_nr(struct task_struct *tsk,
}
static inline void syscall_get_arguments(struct task_struct *tsk,
- struct pt_regs *regs, unsigned int i,
- unsigned int n, unsigned long *args)
+ struct pt_regs *regs,
+ unsigned long *args)
{
- BUG_ON(i);
-
- switch (n) {
- case 6:
- args[5] = regs->gr[21];
- case 5:
- args[4] = regs->gr[22];
- case 4:
- args[3] = regs->gr[23];
- case 3:
- args[2] = regs->gr[24];
- case 2:
- args[1] = regs->gr[25];
- case 1:
- args[0] = regs->gr[26];
- case 0:
- break;
- default:
- BUG();
- }
+ args[5] = regs->gr[21];
+ args[4] = regs->gr[22];
+ args[3] = regs->gr[23];
+ args[2] = regs->gr[24];
+ args[1] = regs->gr[25];
+ args[0] = regs->gr[26];
}
static inline long syscall_get_return_value(struct task_struct *task,
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index 1a0e7a8b1c81..5c9b9dc82b7e 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -65,22 +65,20 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
unsigned long val, mask = -1UL;
-
- BUG_ON(i + n > 6);
+ unsigned int n = 6;
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_32BIT))
mask = 0xffffffff;
#endif
while (n--) {
- if (n == 0 && i == 0)
+ if (n == 0)
val = regs->orig_gpr3;
else
- val = regs->gpr[3 + i + n];
+ val = regs->gpr[3 + n];
args[n] = val & mask;
}
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 6ea9e1804233..6adca1804be1 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -72,18 +72,11 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
- if (i == 0) {
- args[0] = regs->orig_a0;
- args++;
- n--;
- } else {
- i--;
- }
- memcpy(args, ®s->a1 + i, n * sizeof(args[0]));
+ args[0] = regs->orig_a0;
+ args++;
+ memcpy(args, ®s->a1, 5 * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index 96f9a9151fde..ee0b1f6aa36d 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -56,27 +56,20 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
unsigned long mask = -1UL;
+ unsigned int n = 6;
- /*
- * No arguments for this syscall, there's nothing to do.
- */
- if (!n)
- return;
-
- BUG_ON(i + n > 6);
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT))
mask = 0xffffffff;
#endif
while (n-- > 0)
- if (i + n > 0)
- args[n] = regs->gprs[2 + i + n] & mask;
- if (i == 0)
- args[0] = regs->orig_gpr2 & mask;
+ if (n > 0)
+ args[n] = regs->gprs[2 + n] & mask;
+
+ args[0] = regs->orig_gpr2 & mask;
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 6e118799831c..2bf1199a0595 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -48,30 +48,16 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- /*
- * Do this simply for now. If we need to start supporting
- * fetching arguments from arbitrary indices, this will need some
- * extra logic. Presently there are no in-tree users that depend
- * on this behaviour.
- */
- BUG_ON(i);
/* Argument pattern is: R4, R5, R6, R7, R0, R1 */
- switch (n) {
- case 6: args[5] = regs->regs[1];
- case 5: args[4] = regs->regs[0];
- case 4: args[3] = regs->regs[7];
- case 3: args[2] = regs->regs[6];
- case 2: args[1] = regs->regs[5];
- case 1: args[0] = regs->regs[4];
- case 0:
- break;
- default:
- BUG();
- }
+ args[5] = regs->regs[1];
+ args[4] = regs->regs[0];
+ args[3] = regs->regs[7];
+ args[2] = regs->regs[6];
+ args[1] = regs->regs[5];
+ args[0] = regs->regs[4];
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index 43882580c7f9..4e8f6460c703 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -47,11 +47,9 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
- memcpy(args, ®s->regs[2 + i], n * sizeof(args[0]));
+ memcpy(args, ®s->regs[2], 6 * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h
index 053989e3f6a6..872dfee852d6 100644
--- a/arch/sparc/include/asm/syscall.h
+++ b/arch/sparc/include/asm/syscall.h
@@ -96,11 +96,11 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
int zero_extend = 0;
unsigned int j;
+ unsigned int n = 6;
#ifdef CONFIG_SPARC64
if (test_tsk_thread_flag(task, TIF_32BIT))
@@ -108,7 +108,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
#endif
for (j = 0; j < n; j++) {
- unsigned long val = regs->u_regs[UREG_I0 + i + j];
+ unsigned long val = regs->u_regs[UREG_I0 + j];
if (zero_extend)
args[j] = (u32) val;
diff --git a/arch/um/include/asm/syscall-generic.h b/arch/um/include/asm/syscall-generic.h
index 9fb9cf8cd39a..25d00acd1322 100644
--- a/arch/um/include/asm/syscall-generic.h
+++ b/arch/um/include/asm/syscall-generic.h
@@ -53,43 +53,16 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
const struct uml_pt_regs *r = ®s->regs;
- switch (i) {
- case 0:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG1(r);
- case 1:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG2(r);
- case 2:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG3(r);
- case 3:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG4(r);
- case 4:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG5(r);
- case 5:
- if (!n--)
- break;
- *args++ = UPT_SYSCALL_ARG6(r);
- case 6:
- if (!n--)
- break;
- default:
- BUG();
- break;
- }
+ *args++ = UPT_SYSCALL_ARG1(r);
+ *args++ = UPT_SYSCALL_ARG2(r);
+ *args++ = UPT_SYSCALL_ARG3(r);
+ *args++ = UPT_SYSCALL_ARG4(r);
+ *args++ = UPT_SYSCALL_ARG5(r);
+ *args = UPT_SYSCALL_ARG6(r);
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index d653139857af..8dbb5c379450 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -91,11 +91,9 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
- BUG_ON(i + n > 6);
- memcpy(args, ®s->bx + i, n * sizeof(args[0]));
+ memcpy(args, ®s->bx, 6 * sizeof(args[0]));
}
static inline void syscall_set_arguments(struct task_struct *task,
@@ -116,63 +114,26 @@ static inline int syscall_get_arch(void)
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
# ifdef CONFIG_IA32_EMULATION
- if (task->thread_info.status & TS_COMPAT)
- switch (i) {
- case 0:
- if (!n--) break;
- *args++ = regs->bx;
- case 1:
- if (!n--) break;
- *args++ = regs->cx;
- case 2:
- if (!n--) break;
- *args++ = regs->dx;
- case 3:
- if (!n--) break;
- *args++ = regs->si;
- case 4:
- if (!n--) break;
- *args++ = regs->di;
- case 5:
- if (!n--) break;
- *args++ = regs->bp;
- case 6:
- if (!n--) break;
- default:
- BUG();
- break;
- }
- else
+ if (task->thread_info.status & TS_COMPAT) {
+ *args++ = regs->bx;
+ *args++ = regs->cx;
+ *args++ = regs->dx;
+ *args++ = regs->si;
+ *args++ = regs->di;
+ *args = regs->bp;
+ } else
# endif
- switch (i) {
- case 0:
- if (!n--) break;
- *args++ = regs->di;
- case 1:
- if (!n--) break;
- *args++ = regs->si;
- case 2:
- if (!n--) break;
- *args++ = regs->dx;
- case 3:
- if (!n--) break;
- *args++ = regs->r10;
- case 4:
- if (!n--) break;
- *args++ = regs->r8;
- case 5:
- if (!n--) break;
- *args++ = regs->r9;
- case 6:
- if (!n--) break;
- default:
- BUG();
- break;
- }
+ {
+ *args++ = regs->di;
+ *args++ = regs->si;
+ *args++ = regs->dx;
+ *args++ = regs->r10;
+ *args++ = regs->r8;
+ *args = regs->r9;
+ }
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h
index a168bf81c7f4..1504ce9a233a 100644
--- a/arch/xtensa/include/asm/syscall.h
+++ b/arch/xtensa/include/asm/syscall.h
@@ -59,23 +59,13 @@ static inline void syscall_set_return_value(struct task_struct *task,
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
- unsigned int i, unsigned int n,
unsigned long *args)
{
static const unsigned int reg[] = XTENSA_SYSCALL_ARGUMENT_REGS;
- unsigned int j;
-
- if (n == 0)
- return;
-
- WARN_ON_ONCE(i + n > SYSCALL_MAX_ARGS);
+ unsigned int i;
- for (j = 0; j < n; ++j) {
- if (i + j < SYSCALL_MAX_ARGS)
- args[j] = regs->areg[reg[i + j]];
- else
- args[j] = 0;
- }
+ for (i = 0; i < 6; ++i)
+ args[i] = regs->areg[reg[i]];
}
static inline void syscall_set_arguments(struct task_struct *task,
diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 0c938a4354f6..269e9412ef42 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -105,21 +105,16 @@ void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
* syscall_get_arguments - extract system call parameter values
* @task: task of interest, must be blocked
* @regs: task_pt_regs() of @task
- * @i: argument index [0,5]
- * @n: number of arguments; n+i must be [1,6].
* @args: array filled with argument values
*
- * Fetches @n arguments to the system call starting with the @i'th argument
- * (from 0 through 5). Argument @i is stored in @args[0], and so on.
- * An arch inline version is probably optimal when @i and @n are constants.
+ * Fetches 6 arguments to the system call. First argument is stored in
+* @args[0], and so on.
*
* It's only valid to call this when @task is stopped for tracing on
* entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
- * It's invalid to call this with @i + @n > 6; we only support system calls
- * taking up to 6 arguments.
*/
void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
- unsigned int i, unsigned int n, unsigned long *args);
+ unsigned long *args);
/**
* syscall_set_arguments - change system call parameter value
diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h
index 44a3259ed4a5..b6e0cbc2c71f 100644
--- a/include/trace/events/syscalls.h
+++ b/include/trace/events/syscalls.h
@@ -28,7 +28,7 @@ TRACE_EVENT_FN(sys_enter,
TP_fast_assign(
__entry->id = id;
- syscall_get_arguments(current, regs, 0, 6, __entry->args);
+ syscall_get_arguments(current, regs, __entry->args);
),
TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)",
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 54a0347ca812..df27e499956a 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -149,7 +149,7 @@ static void populate_seccomp_data(struct seccomp_data *sd)
sd->nr = syscall_get_nr(task, regs);
sd->arch = syscall_get_arch();
- syscall_get_arguments(task, regs, 0, 6, args);
+ syscall_get_arguments(task, regs, args);
sd->args[0] = args[0];
sd->args[1] = args[1];
sd->args[2] = args[2];
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index e9f5bbbad6d9..fa8fbff736d6 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -348,7 +348,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
entry = ring_buffer_event_data(event);
entry->nr = syscall_nr;
- syscall_get_arguments(current, regs, 0, 6, args);
+ syscall_get_arguments(current, regs, args);
memcpy(entry->args, args, sizeof(unsigned long) * sys_data->nb_args);
event_trigger_unlock_commit(trace_file, buffer, event, entry,
@@ -616,7 +616,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
return;
rec->nr = syscall_nr;
- syscall_get_arguments(current, regs, 0, 6, args);
+ syscall_get_arguments(current, regs, args);
memcpy(&rec->args, args, sizeof(unsigned long) * sys_data->nb_args);
if ((valid_prog_array &&
diff --git a/lib/syscall.c b/lib/syscall.c
index e8467e17b9a2..fb328e7ccb08 100644
--- a/lib/syscall.c
+++ b/lib/syscall.c
@@ -27,7 +27,7 @@ static int collect_syscall(struct task_struct *target, struct syscall_info *info
info->data.nr = syscall_get_nr(target, regs);
if (info->data.nr != -1L)
- syscall_get_arguments(target, regs, 0, 6,
+ syscall_get_arguments(target, regs,
(unsigned long *)&info->data.args[0]);
put_task_stack(target);
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v2 1/5] arch/arc: unwind.c: replace swap function with built-in one
From: Vineet Gupta @ 2019-04-01 17:53 UTC (permalink / raw)
To: Andrey Abramov, benh, paulus, mpe, tglx, mingo, bp, hpa, x86,
mark, jlbec, richard, dedekind1, adrian.hunter, gregkh,
naveen.n.rao, jpoimboe, Dave Chinner, darrick.wong,
ard.biesheuvel, George Spelvin, linux-snps-arc,
Linux Kernel Mailing List, linuxppc-dev, ocfs2-devel, linux-mtd,
sfr
Cc: mhocko, rppt
In-Reply-To: <23405591554057090@iva8-b333b7f98ab0.qloud-c.yandex.net>
On 3/31/19 11:31 AM, Andrey Abramov wrote:
> Replace swap_eh_frame_hdr_table_entries with built-in one, because
> swap_eh_frame_hdr_table_entries does a simple byte to byte swap.
>
> Since Spectre mitigations have made indirect function calls more
> expensive, and the default simple byte copies swap is implemented
> without them, an "optimized" custom swap function is now
> a waste of time as well as code.
>
> Signed-off-by: Andrey Abramov <st5pub@yandex.ru>
> Reviewed by: George Spelvin <lkml@sdf.org>
>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
Thx,
-Vineet
^ permalink raw reply
* [PATCH 0/5] Fix vDSO clock_getres()
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.
A possible fix is to change the vdso implementation of clock_getres,
keeping a copy of hrtimer_resolution in vdso data and using that
directly [1].
This patchset implements the proposed fix for arm64, powerpc, s390,
nds32 and adds a test to verify that the syscall and the vdso library
implementation of clock_getres return the same values.
[1] https://marc.info/?l=linux-arm-kernel&m=155110381930196&w=2
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Vincenzo Frascino (5):
arm64: Fix vDSO clock_getres()
powerpc: Fix vDSO clock_getres()
s390: Fix vDSO clock_getres()
nds32: Fix vDSO clock_getres()
kselftest: Extend vDSO selftest to clock_getres
arch/arm64/include/asm/vdso_datapage.h | 1 +
arch/arm64/kernel/asm-offsets.c | 2 +-
arch/arm64/kernel/vdso.c | 2 +
arch/arm64/kernel/vdso/gettimeofday.S | 25 ++--
arch/nds32/include/asm/vdso_datapage.h | 1 +
arch/nds32/kernel/vdso.c | 1 +
arch/nds32/kernel/vdso/gettimeofday.c | 4 +-
arch/powerpc/include/asm/vdso_datapage.h | 2 +
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/time.c | 1 +
arch/powerpc/kernel/vdso32/gettimeofday.S | 22 ++--
arch/powerpc/kernel/vdso64/gettimeofday.S | 22 ++--
arch/s390/include/asm/vdso.h | 1 +
arch/s390/kernel/asm-offsets.c | 2 +-
arch/s390/kernel/time.c | 1 +
arch/s390/kernel/vdso32/clock_getres.S | 17 ++-
arch/s390/kernel/vdso64/clock_getres.S | 15 ++-
tools/testing/selftests/vDSO/Makefile | 2 +
.../selftests/vDSO/vdso_clock_getres.c | 107 ++++++++++++++++++
19 files changed, 191 insertions(+), 39 deletions(-)
create mode 100644 tools/testing/selftests/vDSO/vdso_clock_getres.c
--
2.21.0
^ permalink raw reply
* [PATCH 1/5] arm64: Fix vDSO clock_getres()
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
In-Reply-To: <20190401115152.32751-1-vincenzo.frascino@arm.com>
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.
Fix the arm64 vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/arm64/include/asm/vdso_datapage.h | 1 +
arch/arm64/kernel/asm-offsets.c | 2 +-
arch/arm64/kernel/vdso.c | 2 ++
arch/arm64/kernel/vdso/gettimeofday.S | 25 ++++++++++++++-----------
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h
index 2b9a63771eda..f89263c8e11a 100644
--- a/arch/arm64/include/asm/vdso_datapage.h
+++ b/arch/arm64/include/asm/vdso_datapage.h
@@ -38,6 +38,7 @@ struct vdso_data {
__u32 tz_minuteswest; /* Whacky timezone stuff */
__u32 tz_dsttime;
__u32 use_syscall;
+ __u32 hrtimer_res;
};
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 7f40dcbdd51d..e10e2a5d9ddc 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -94,7 +94,7 @@ int main(void)
DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
DEFINE(CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_RAW);
- DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
+ DEFINE(CLOCK_REALTIME_RES, offsetof(struct vdso_data, hrtimer_res));
DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
DEFINE(CLOCK_MONOTONIC_COARSE,CLOCK_MONOTONIC_COARSE);
DEFINE(CLOCK_COARSE_RES, LOW_RES_NSEC);
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 2d419006ad43..47ba72345739 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -245,6 +245,8 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->cs_shift = tk->tkr_mono.shift;
}
+ vdso_data->hrtimer_res = hrtimer_resolution;
+
smp_wmb();
++vdso_data->tb_seq_count;
}
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index c39872a7b03c..7a2cd2f8e13a 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -296,32 +296,35 @@ ENDPROC(__kernel_clock_gettime)
/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
ENTRY(__kernel_clock_getres)
.cfi_startproc
+ adr vdso_data, _vdso_data
cmp w0, #CLOCK_REALTIME
ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
ccmp w0, #CLOCK_MONOTONIC_RAW, #0x4, ne
- b.ne 1f
+ b.ne 2f
- ldr x2, 5f
- b 2f
-1:
+1: /* Get hrtimer_res */
+ seqcnt_acquire
+ syscall_check fail=5f
+ ldr x2, [vdso_data, #CLOCK_REALTIME_RES]
+ seqcnt_check fail=1b
+ b 3f
+2:
cmp w0, #CLOCK_REALTIME_COARSE
ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
- b.ne 4f
+ b.ne 5f
ldr x2, 6f
-2:
- cbz x1, 3f
+3:
+ cbz x1, 4f
stp xzr, x2, [x1]
-3: /* res == NULL. */
+4: /* res == NULL. */
mov w0, wzr
ret
-4: /* Syscall fallback. */
+5: /* Syscall fallback. */
mov x8, #__NR_clock_getres
svc #0
ret
-5:
- .quad CLOCK_REALTIME_RES
6:
.quad CLOCK_COARSE_RES
.cfi_endproc
--
2.21.0
^ permalink raw reply related
* [PATCH 2/5] powerpc: Fix vDSO clock_getres()
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
In-Reply-To: <20190401115152.32751-1-vincenzo.frascino@arm.com>
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.
Fix the powerpc vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/powerpc/include/asm/vdso_datapage.h | 2 ++
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/time.c | 1 +
arch/powerpc/kernel/vdso32/gettimeofday.S | 22 +++++++++++++++-------
arch/powerpc/kernel/vdso64/gettimeofday.S | 22 +++++++++++++++-------
5 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index 1afe90ade595..4ae43fc77fe9 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -86,6 +86,7 @@ struct vdso_data {
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
__u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
+ __u32 hrtimer_res; /* hrtimer resolution */
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
};
@@ -107,6 +108,7 @@ struct vdso_data {
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
__u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
+ __u32 hrtimer_res; /* hrtimer resolution */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 dcache_block_size; /* L1 d-cache block size */
__u32 icache_block_size; /* L1 i-cache block size */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 86a61e5f8285..52e4b98a8492 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -383,6 +383,7 @@ int main(void)
OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec);
OFFSET(STAMP_XTIME, vdso_data, stamp_xtime);
OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
+ OFFSET(CLOCK_REALTIME_RES, vdso_data, hrtimer_res);
OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
@@ -413,7 +414,6 @@ int main(void)
DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
- DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
#ifdef CONFIG_BUG
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index bc0503ef9c9c..62c04a6746d8 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -955,6 +955,7 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec;
vdso_data->stamp_xtime = xt;
vdso_data->stamp_sec_fraction = frac_sec;
+ vdso_data->hrtimer_res = hrtimer_resolution;
smp_wmb();
++(vdso_data->tb_update_count);
}
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index 1e0bc5955a40..b21630079496 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -160,14 +160,21 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
cror cr0*4+eq,cr0*4+eq,cr1*4+eq
bne cr0,99f
- li r3,0
- cmpli cr0,r4,0
+ mflr r12
+ .cfi_register lr,r12
+ mr r11,r4
+ bl __get_datapage@local
+ lwz r5,CLOCK_REALTIME_RES(r3)
+ li r4,0
+ cmplwi r11,0 /* check if res is NULL */
+ beq 1f
+
+ stw r4,TSPC32_TV_SEC(r11)
+ stw r5,TSPC32_TV_NSEC(r11)
+
+1: mtlr r12
crclr cr0*4+so
- beqlr
- lis r5,CLOCK_REALTIME_RES@h
- ori r5,r5,CLOCK_REALTIME_RES@l
- stw r3,TSPC32_TV_SEC(r4)
- stw r5,TSPC32_TV_NSEC(r4)
+ li r3,0
blr
/*
@@ -175,6 +182,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
*/
99:
li r0,__NR_clock_getres
+ .cfi_restore lr
sc
blr
.cfi_endproc
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index a4ed9edfd5f0..a7e49bddd475 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -190,14 +190,21 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
cror cr0*4+eq,cr0*4+eq,cr1*4+eq
bne cr0,99f
- li r3,0
- cmpldi cr0,r4,0
+ mflr r12
+ .cfi_register lr,r12
+ mr r11, r4
+ bl V_LOCAL_FUNC(__get_datapage)
+ lwz r5,CLOCK_REALTIME_RES(r3)
+ li r4,0
+ cmpldi r11,0 /* check if res is NULL */
+ beq 1f
+
+ std r4,TSPC64_TV_SEC(r11)
+ std r5,TSPC64_TV_NSEC(r11)
+
+1: mtlr r12
crclr cr0*4+so
- beqlr
- lis r5,CLOCK_REALTIME_RES@h
- ori r5,r5,CLOCK_REALTIME_RES@l
- std r3,TSPC64_TV_SEC(r4)
- std r5,TSPC64_TV_NSEC(r4)
+ li r3,0
blr
/*
@@ -205,6 +212,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
*/
99:
li r0,__NR_clock_getres
+ .cfi_restore lr
sc
blr
.cfi_endproc
--
2.21.0
^ permalink raw reply related
* [PATCH 3/5] s390: Fix vDSO clock_getres()
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
In-Reply-To: <20190401115152.32751-1-vincenzo.frascino@arm.com>
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.
Fix the s390 vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/s390/include/asm/vdso.h | 1 +
arch/s390/kernel/asm-offsets.c | 2 +-
arch/s390/kernel/time.c | 1 +
arch/s390/kernel/vdso32/clock_getres.S | 17 ++++++++++++-----
arch/s390/kernel/vdso64/clock_getres.S | 15 ++++++++++-----
5 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index 169d7604eb80..f3ba84fa9bd1 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -36,6 +36,7 @@ struct vdso_data {
__u32 tk_shift; /* Shift used for xtime_nsec 0x60 */
__u32 ts_dir; /* TOD steering direction 0x64 */
__u64 ts_end; /* TOD steering end 0x68 */
+ __u32 hrtimer_res; /* hrtimer resolution 0x70 */
};
struct vdso_per_cpu_data {
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 164bec175628..36db4a9ee703 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -75,6 +75,7 @@ int main(void)
OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir);
OFFSET(__VDSO_TS_END, vdso_data, ts_end);
+ OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res);
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
@@ -86,7 +87,6 @@ int main(void)
DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
- DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
BLANK();
/* idle data offsets */
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index e8766beee5ad..8ea9db599d38 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -310,6 +310,7 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->tk_mult = tk->tkr_mono.mult;
vdso_data->tk_shift = tk->tkr_mono.shift;
+ vdso_data->hrtimer_res = hrtimer_resolution;
smp_wmb();
++vdso_data->tb_update_count;
}
diff --git a/arch/s390/kernel/vdso32/clock_getres.S b/arch/s390/kernel/vdso32/clock_getres.S
index eaf9cf1417f6..00fc50ad228c 100644
--- a/arch/s390/kernel/vdso32/clock_getres.S
+++ b/arch/s390/kernel/vdso32/clock_getres.S
@@ -18,20 +18,27 @@
__kernel_clock_getres:
CFI_STARTPROC
basr %r1,0
- la %r1,4f-.(%r1)
+10: al %r1,4f-10b(%r1)
+11: l %r4,__VDSO_UPD_COUNT+4(%r1) /* load update counter */
+ tml %r4,0x0001 /* pending update ? loop */
+ jnz 11b
+ l %r0,__VDSO_CLOCK_REALTIME_RES(%r1)
+ cl %r4,__VDSO_UPD_COUNT+4(%r1) /* check update counter */
+ jne 11b
chi %r2,__CLOCK_REALTIME
je 0f
chi %r2,__CLOCK_MONOTONIC
je 0f
- la %r1,5f-4f(%r1)
+ basr %r1,0
+ la %r1,5f-.(%r1)
+ l %r0,0(%r1)
chi %r2,__CLOCK_REALTIME_COARSE
je 0f
chi %r2,__CLOCK_MONOTONIC_COARSE
jne 3f
0: ltr %r3,%r3
jz 2f /* res == NULL */
-1: l %r0,0(%r1)
- xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */
+1: xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */
st %r0,4(%r3) /* store tp->tv_usec */
2: lhi %r2,0
br %r14
@@ -39,6 +46,6 @@ __kernel_clock_getres:
svc 0
br %r14
CFI_ENDPROC
-4: .long __CLOCK_REALTIME_RES
+4: .long _vdso_data - 10b
5: .long __CLOCK_COARSE_RES
.size __kernel_clock_getres,.-__kernel_clock_getres
diff --git a/arch/s390/kernel/vdso64/clock_getres.S b/arch/s390/kernel/vdso64/clock_getres.S
index 081435398e0a..1400a8df9802 100644
--- a/arch/s390/kernel/vdso64/clock_getres.S
+++ b/arch/s390/kernel/vdso64/clock_getres.S
@@ -17,12 +17,19 @@
.type __kernel_clock_getres,@function
__kernel_clock_getres:
CFI_STARTPROC
- larl %r1,4f
+ larl %r1,3f
+ lg %r0,0(%r1)
cghi %r2,__CLOCK_REALTIME_COARSE
je 0f
cghi %r2,__CLOCK_MONOTONIC_COARSE
je 0f
- larl %r1,3f
+ larl %r1,_vdso_data
+11: lg %r4,__VDSO_UPD_COUNT(%r1) /* load update counter */
+ tmll %r4,0x0001 /* pending update ? loop */
+ jnz 11b
+ l %r0,__VDSO_CLOCK_REALTIME_RES(%r1)
+ clg %r4,__VDSO_UPD_COUNT(%r1) /* check update counter */
+ jne 11b
cghi %r2,__CLOCK_REALTIME
je 0f
cghi %r2,__CLOCK_MONOTONIC
@@ -36,7 +43,6 @@ __kernel_clock_getres:
jz 2f
0: ltgr %r3,%r3
jz 1f /* res == NULL */
- lg %r0,0(%r1)
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
stg %r0,8(%r3) /* store tp->tv_usec */
1: lghi %r2,0
@@ -45,6 +51,5 @@ __kernel_clock_getres:
svc 0
br %r14
CFI_ENDPROC
-3: .quad __CLOCK_REALTIME_RES
-4: .quad __CLOCK_COARSE_RES
+3: .quad __CLOCK_COARSE_RES
.size __kernel_clock_getres,.-__kernel_clock_getres
--
2.21.0
^ permalink raw reply related
* [PATCH 4/5] nds32: Fix vDSO clock_getres()
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
In-Reply-To: <20190401115152.32751-1-vincenzo.frascino@arm.com>
clock_getres in the vDSO library has to preserve the same behaviour
of posix_get_hrtimer_res().
In particular, posix_get_hrtimer_res() does:
sec = 0;
ns = hrtimer_resolution;
and hrtimer_resolution depends on the enablement of the high
resolution timers that can happen either at compile or at run time.
Fix the nds32 vdso implementation of clock_getres keeping a copy of
hrtimer_resolution in vdso data and using that directly.
Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
arch/nds32/include/asm/vdso_datapage.h | 1 +
arch/nds32/kernel/vdso.c | 1 +
arch/nds32/kernel/vdso/gettimeofday.c | 4 +++-
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/nds32/include/asm/vdso_datapage.h b/arch/nds32/include/asm/vdso_datapage.h
index 79db5a12ca5e..34d80548297f 100644
--- a/arch/nds32/include/asm/vdso_datapage.h
+++ b/arch/nds32/include/asm/vdso_datapage.h
@@ -20,6 +20,7 @@ struct vdso_data {
u32 xtime_clock_sec; /* CLOCK_REALTIME - seconds */
u32 cs_mult; /* clocksource multiplier */
u32 cs_shift; /* Cycle to nanosecond divisor (power of two) */
+ u32 hrtimer_res; /* hrtimer resolution */
u64 cs_cycle_last; /* last cycle value */
u64 cs_mask; /* clocksource mask */
diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c
index 016f15891f6d..90bcae6f8554 100644
--- a/arch/nds32/kernel/vdso.c
+++ b/arch/nds32/kernel/vdso.c
@@ -220,6 +220,7 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->xtime_coarse_sec = tk->xtime_sec;
vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >>
tk->tkr_mono.shift;
+ vdso_data->hrtimer_res = hrtimer_resolution;
vdso_write_end(vdso_data);
}
diff --git a/arch/nds32/kernel/vdso/gettimeofday.c b/arch/nds32/kernel/vdso/gettimeofday.c
index 038721af40e3..b02581891c33 100644
--- a/arch/nds32/kernel/vdso/gettimeofday.c
+++ b/arch/nds32/kernel/vdso/gettimeofday.c
@@ -208,6 +208,8 @@ static notrace int clock_getres_fallback(clockid_t _clk_id,
notrace int __vdso_clock_getres(clockid_t clk_id, struct timespec *res)
{
+ struct vdso_data *vdata = __get_datapage();
+
if (res == NULL)
return 0;
switch (clk_id) {
@@ -215,7 +217,7 @@ notrace int __vdso_clock_getres(clockid_t clk_id, struct timespec *res)
case CLOCK_MONOTONIC:
case CLOCK_MONOTONIC_RAW:
res->tv_sec = 0;
- res->tv_nsec = CLOCK_REALTIME_RES;
+ res->tv_nsec = vdata->hrtimer_res;
break;
case CLOCK_REALTIME_COARSE:
case CLOCK_MONOTONIC_COARSE:
--
2.21.0
^ permalink raw reply related
* [PATCH 5/5] kselftest: Extend vDSO selftest to clock_getres
From: Vincenzo Frascino @ 2019-04-01 11:51 UTC (permalink / raw)
To: linux-arch, linux-arm-kernel, linuxppc-dev, linux-s390
Cc: Arnd Bergmann, Heiko Carstens, Catalin Marinas, Will Deacon,
Paul Mackerras, Greentime Hu, Martin Schwidefsky, Thomas Gleixner,
Vincent Chen, Shuah Khan
In-Reply-To: <20190401115152.32751-1-vincenzo.frascino@arm.com>
The current version of the multiarch vDSO selftest verifies only
gettimeofday.
Extend the vDSO selftest to clock_getres, to verify that the
syscall and the vDSO library function return the same information.
The extension has been used to verify the hrtimer_resoltion fix.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
tools/testing/selftests/vDSO/Makefile | 2 +
.../selftests/vDSO/vdso_clock_getres.c | 107 ++++++++++++++++++
2 files changed, 109 insertions(+)
create mode 100644 tools/testing/selftests/vDSO/vdso_clock_getres.c
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
index 9e03d61f52fd..d5c5bfdf1ac1 100644
--- a/tools/testing/selftests/vDSO/Makefile
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -5,6 +5,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
TEST_GEN_PROGS := $(OUTPUT)/vdso_test
+TEST_GEN_PROGS += $(OUTPUT)/vdso_clock_getres
ifeq ($(ARCH),x86)
TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
endif
@@ -18,6 +19,7 @@ endif
all: $(TEST_GEN_PROGS)
$(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c
+$(OUTPUT)/vdso_clock_getres: vdso_clock_getres.c
$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
$(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
vdso_standalone_test_x86.c parse_vdso.c \
diff --git a/tools/testing/selftests/vDSO/vdso_clock_getres.c b/tools/testing/selftests/vDSO/vdso_clock_getres.c
new file mode 100644
index 000000000000..589949f6ca90
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_clock_getres.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * vdso_clock_getres.c: Sample code to test clock_getres.
+ * Copyright (c) 2019 Arm Ltd.
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_clock_getres.c
+ *
+ * Tested on ARM, ARM64, MIPS32, x86 (32-bit and 64-bit),
+ * Power (32-bit and 64-bit), S390x (32-bit and 64-bit).
+ * Might work on other architectures.
+ */
+#include <elf.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "../kselftest.h"
+
+static long syscall_clock_getres(clockid_t _clkid, struct timespec *_ts)
+{
+ long ret;
+
+ ret = syscall(SYS_clock_getres, _clkid, _ts);
+
+ return ret;
+}
+
+const char *vdso_clock_name[12] = {
+ "CLOCK_REALTIME",
+ "CLOCK_MONOTONIC",
+ "CLOCK_PROCESS_CPUTIME_ID",
+ "CLOCK_THREAD_CPUTIME_ID",
+ "CLOCK_MONOTONIC_RAW",
+ "CLOCK_REALTIME_COARSE",
+ "CLOCK_MONOTONIC_COARSE",
+ "CLOCK_BOOTTIME",
+ "CLOCK_REALTIME_ALARM",
+ "CLOCK_BOOTTIME_ALARM",
+ "CLOCK_SGI_CYCLE",
+ "CLOCK_TAI",
+};
+
+/*
+ * Macro to call clock_getres in vdso and by system call
+ * with different values for clock_id.
+ */
+#define vdso_test_clock(clock_id) \
+do { \
+ struct timespec x, y; \
+ printf("clock_id: %s", vdso_clock_name[clock_id]); \
+ clock_getres(clock_id, &x); \
+ syscall_clock_getres(clock_id, &y); \
+ if ((x.tv_sec != y.tv_sec) || (x.tv_sec != y.tv_sec)) { \
+ printf(" [FAIL]\n"); \
+ return KSFT_SKIP; \
+ } else { \
+ printf(" [PASS]\n"); \
+ } \
+} while (0)
+
+int main(int argc, char **argv)
+{
+
+#if _POSIX_TIMERS > 0
+
+#ifdef CLOCK_REALTIME
+ vdso_test_clock(CLOCK_REALTIME);
+#endif
+
+#ifdef CLOCK_BOOTTIME
+ vdso_test_clock(CLOCK_BOOTTIME);
+#endif
+
+#ifdef CLOCK_TAI
+ vdso_test_clock(CLOCK_TAI);
+#endif
+
+#ifdef CLOCK_REALTIME_COARSE
+ vdso_test_clock(CLOCK_REALTIME_COARSE);
+#endif
+
+#ifdef CLOCK_MONOTONIC
+ vdso_test_clock(CLOCK_MONOTONIC);
+#endif
+
+#ifdef CLOCK_MONOTONIC_RAW
+ vdso_test_clock(CLOCK_MONOTONIC_RAW);
+#endif
+
+#ifdef CLOCK_MONOTONIC_COARSE
+ vdso_test_clock(CLOCK_MONOTONIC_COARSE);
+#endif
+
+#endif
+
+ return 0;
+}
--
2.21.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