* [PATCH -next] ppc: boot: Fix a typo in the file decompress.c
From: Zhang Jianhua @ 2021-05-10 7:51 UTC (permalink / raw)
To: mpe, benh, paulus, gustavoars, ojeda, ndesaulniers, chris.zjh
Cc: linuxppc-dev, linux-kernel
s/input buffer/output buffer/
s/length of the input buffer/length of the input buffer/
--------
Signed-off-by: Zhang Jianhua <chris.zjh@huawei.com>
---
arch/powerpc/boot/decompress.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/decompress.c b/arch/powerpc/boot/decompress.c
index 6098b879ac97..977eb15a6d17 100644
--- a/arch/powerpc/boot/decompress.c
+++ b/arch/powerpc/boot/decompress.c
@@ -99,8 +99,8 @@ static void print_err(char *s)
* partial_decompress - decompresses part or all of a compressed buffer
* @inbuf: input buffer
* @input_size: length of the input buffer
- * @outbuf: input buffer
- * @output_size: length of the input buffer
+ * @outbuf: output buffer
+ * @output_size: length of the output buffer
* @skip number of output bytes to ignore
*
* This function takes compressed data from inbuf, decompresses and write it to
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] powerpc/legacy_serial: Fix UBSAN: array-index-out-of-bounds
From: Segher Boessenkool @ 2021-05-10 21:14 UTC (permalink / raw)
To: Christophe Leroy; +Cc: pmenzel, linux-kernel, Paul Mackerras, linuxppc-dev
In-Reply-To: <d5e3c8e66bad3725d7d48d0e45c4b7eb7c02631d.1620455671.git.christophe.leroy@csgroup.eu>
On Sat, May 08, 2021 at 06:36:21AM +0000, Christophe Leroy wrote:
> UBSAN complains when a pointer is calculated with invalid
> 'legacy_serial_console' index, allthough the index is verified
> before dereferencing the pointer.
Addressing like this is UB already.
You could just move this:
> - if (legacy_serial_console < 0)
> - return 0;
to before
> - struct legacy_serial_info *info = &legacy_serial_infos[legacy_serial_console];
> - struct plat_serial8250_port *port = &legacy_serial_ports[legacy_serial_console];
and no other change is necessary.
Segher
^ permalink raw reply
* Re: [V3 PATCH 12/16] powerpc/pseries/vas: sysfs interface to export capabilities
From: Haren Myneni @ 2021-05-10 20:52 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620628126.jezp40t2h6.astroid@bobo.none>
On Mon, 2021-05-10 at 16:34 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:10 am:
> > pHyp provides GZIP default and GZIP QoS capabilities which gives
> > the total number of credits are available in LPAR. This patch
> > creates sysfs entries and exports LPAR credits, the currently used
> > and the available credits for each feature.
> >
> > /sys/kernel/vas/VasCaps/VDefGzip: (default GZIP capabilities)
> > avail_lpar_creds /* Available credits to use */
> > target_lpar_creds /* Total credits available which can be
> > /* changed with DLPAR operation */
> > used_lpar_creds /* Used credits */
>
> /sys/kernel/ is not an appropriate directory to put it in. Also
> camel
> case is not thought very highly of these days.
These capabilities are VAS specific ones (powerpc kernel), not for the
indicidual coprocessor. Not sure where to add in sysfs.
>
> And s/capabs/caps/g applies here (and all other patches).
Thanks, will change.
>
> Thanks,
> Nick
^ permalink raw reply
* Re: [V3 PATCH 15/16] crypto/nx: Get NX capabilities for GZIP coprocessor type
From: Haren Myneni @ 2021-05-10 20:44 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620628516.4xglqwl3t1.astroid@bobo.none>
On Mon, 2021-05-10 at 16:38 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:12 am:
> > phyp provides NX capabilities which gives recommended minimum
> > compression / decompression length and maximum request buffer size
> > in bytes.
> >
> > Changes to get NX overall capabilities which points to the specific
> > features phyp supports. Then retrieve NXGZIP specific capabilities.
> >
> > Signed-off-by: Haren Myneni <haren@linux.ibm.com>
> > ---
> > drivers/crypto/nx/nx-common-pseries.c | 83
> > +++++++++++++++++++++++++++
> > 1 file changed, 83 insertions(+)
> >
> > diff --git a/drivers/crypto/nx/nx-common-pseries.c
> > b/drivers/crypto/nx/nx-common-pseries.c
> > index 9a40fca8a9e6..49224870d05e 100644
> > --- a/drivers/crypto/nx/nx-common-pseries.c
> > +++ b/drivers/crypto/nx/nx-common-pseries.c
> > @@ -9,6 +9,7 @@
> > */
> >
> > #include <asm/vio.h>
> > +#include <asm/hvcall.h>
> > #include <asm/vas.h>
> >
> > #include "nx-842.h"
> > @@ -20,6 +21,24 @@ MODULE_DESCRIPTION("842 H/W Compression driver
> > for IBM Power processors");
> > MODULE_ALIAS_CRYPTO("842");
> > MODULE_ALIAS_CRYPTO("842-nx");
> >
> > +struct nx_ct_capabs_be {
>
> What does "ct" mean? I've seen it in a few other places too.
ct means coprocessor type such as 842 and GZIP. phyp provides only GZIP
capabilities right now. But this struct may be extended to other types
in future.
>
> > + __be64 descriptor;
> > + __be64 req_max_processed_len; /* Max bytes in one GZIP
> > request */
> > + __be64 min_compress_len; /* Min compression size in
> > bytes */
> > + __be64 min_decompress_len; /* Min decompression size
> > in bytes */
> > +} __packed __aligned(0x1000);
> > +
> > +struct nx_ct_capabs {
> > + char name[VAS_DESCR_LEN + 1];
> > + u64 descriptor;
> > + u64 req_max_processed_len; /* Max bytes in one GZIP request */
> > + u64 min_compress_len; /* Min compression in bytes */
> > + u64 min_decompress_len; /* Min decompression in bytes */
> > +};
> > +
> > +u64 capab_feat = 0;
>
> Why is this here and not a local variable?
capab_feat is used to add / delete sysfs entries.
>
> > +struct nx_ct_capabs nx_ct_capab;
>
> It's okay and generally better to use the same name as the struct
> name
> in this situation, i.e.,
>
> "struct nx_ct_capabs nx_ct_capabs"
>
> (modulo static / caps / etc)
Sure, will change.
>
> Thanks,
> Nick
^ permalink raw reply
* Re: [V3 PATCH 03/16] powerpc/vas: Create take/drop task reference functions
From: Haren Myneni @ 2021-05-10 20:32 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620624047.yy8sqcrk40.astroid@bobo.none>
On Mon, 2021-05-10 at 15:28 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:03 am:
> > Take task reference when each window opens and drops during close.
> > This functionality is needed for powerNV and pseries. So this patch
> > defines the existing code as functions in common book3s platform
> > vas-api.c
> >
> > Signed-off-by: Haren Myneni <haren@linux.ibm.com>
> > ---
> > arch/powerpc/include/asm/vas.h | 20 ++++++++
> > arch/powerpc/platforms/book3s/vas-api.c | 51
> > ++++++++++++++++++
> > arch/powerpc/platforms/powernv/vas-fault.c | 10 ++--
> > arch/powerpc/platforms/powernv/vas-window.c | 57 ++---------------
> > ----
> > arch/powerpc/platforms/powernv/vas.h | 6 +--
> > 5 files changed, 83 insertions(+), 61 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/vas.h
> > b/arch/powerpc/include/asm/vas.h
> > index 6bbade60d8f4..2daaa1a2a9a9 100644
> > --- a/arch/powerpc/include/asm/vas.h
> > +++ b/arch/powerpc/include/asm/vas.h
> > @@ -5,6 +5,9 @@
> >
> > #ifndef _ASM_POWERPC_VAS_H
> > #define _ASM_POWERPC_VAS_H
> > +#include <linux/sched/mm.h>
> > +#include <linux/mmu_context.h>
> > +#include <asm/icswx.h>
> > #include <uapi/asm/vas-api.h>
> >
> >
> > @@ -60,6 +63,22 @@ struct vas_user_win_ops {
> > int (*close_win)(void *);
> > };
> >
> > +struct vas_win_task {
> > + struct pid *pid; /* Thread group ID of owner */
> > + struct pid *tgid; /* Linux process mm_struct */
> > + struct mm_struct *mm; /* Linux process mm_struct */
> > +};
>
> Looks okay, happy with struct vas_win_task? (and vas_user_win_ops)?
>
> I'd be happier to have everything related to vas windows prefixed
> with
> vas_window_ consistently, and have _user be present always for
> userspace
> windows, but you have to read and type it.
I will change to vas_window_task and vas_user_window_ops. struct
vas_window is common for both kernel and user space window, but struct
vas_window_task is needed only for user space.
>
> > +
> > +static inline void vas_drop_reference_task(struct vas_win_task
> > *task)
>
> This is not dropping a reference task, but a task reference. And
> it's
> not really a task reference as far as Linux understands, but a
> reference on pid (not task) and mm related to an open vas window. And
> specifically a user window (with corresponding vas_user_win_ops).
Yes get and put references to pid and mm. Hence mentioned
reference_task to reflect for both pid and mm. Would you prefer
vas_put_reference_pid_mm()?
>
> Could it be called a 'struct vas_window_user_ref' instead?
To support LPM and DLPAR, plannig to add VMA (mapping address) in
struct vas_window_task. But I can change it to 'struct
vas_window_user_ref' instread of vas_window_task.
Thanks
Haren
>
> Thanks,
> Nick
>
> > +{
> > + /* Drop references to pid and mm */
> > + put_pid(task->pid);
> > + if (task->mm) {
> > + mm_context_remove_vas_window(task->mm);
> > + mmdrop(task->mm);
> > + }
^ permalink raw reply
* Re: [PATCH V3 02/16] powerpc/vas: Move VAS API to common book3s platform
From: Haren Myneni @ 2021-05-10 17:12 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620623481.kmr54zmxzv.astroid@bobo.none>
On Mon, 2021-05-10 at 15:19 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:02 am:
> > Using the same /dev/crypto/nx-gzip interface for both powerNV and
> > pseries.
>
> The pseries NX driver will use the powernv VAS API ?
Yes, both powerNV and pseries drivers use same VAS API.
>
> > So this patch creates platforms/book3s/ and moves VAS API
> > to that directory. The actual functionality is not changed.
> >
> > Common interface functions such as open, window open ioctl, mmap
> > and close are moved to arch/powerpc/platforms/book3s/vas-api.c
> > Added hooks to call platform specific code, but the underline
> > powerNV code in these functions is not changed.
>
> Even so, could you do one patch that just moves, and another that
> adds the ops struct?
Sure, I will create separate patches.
>
> > Signed-off-by: Haren Myneni <haren@linux.ibm.com>
> > ---
> > arch/powerpc/include/asm/vas.h | 22 ++++++-
> > arch/powerpc/platforms/Kconfig | 1 +
> > arch/powerpc/platforms/Makefile | 1 +
> > arch/powerpc/platforms/book3s/Kconfig | 15 +++++
> > arch/powerpc/platforms/book3s/Makefile | 2 +
>
> The usual place for these would be arch/powerpc/sysdev/vas. E.g., see
> arch/powerpc/sysdev/xive.
It was recommended to create book3s and move common vas-api code.
>
> > .../platforms/{powernv => book3s}/vas-api.c | 64 ++++++++++-----
> > ---
> > arch/powerpc/platforms/powernv/Kconfig | 14 ----
> > arch/powerpc/platforms/powernv/Makefile | 2 +-
> > arch/powerpc/platforms/powernv/vas-window.c | 66
> > +++++++++++++++++++
> > 9 files changed, 143 insertions(+), 44 deletions(-)
> > create mode 100644 arch/powerpc/platforms/book3s/Kconfig
> > create mode 100644 arch/powerpc/platforms/book3s/Makefile
> > rename arch/powerpc/platforms/{powernv => book3s}/vas-api.c (83%)
> >
> > diff --git a/arch/powerpc/include/asm/vas.h
> > b/arch/powerpc/include/asm/vas.h
> > index 41f73fae7ab8..6bbade60d8f4 100644
> > --- a/arch/powerpc/include/asm/vas.h
> > +++ b/arch/powerpc/include/asm/vas.h
> > @@ -5,6 +5,8 @@
> >
> > #ifndef _ASM_POWERPC_VAS_H
> > #define _ASM_POWERPC_VAS_H
> > +#include <uapi/asm/vas-api.h>
> > +
> >
> > struct vas_window;
> >
> > @@ -48,6 +50,16 @@ enum vas_cop_type {
> > VAS_COP_TYPE_MAX,
> > };
> >
> > +/*
> > + * User space window operations used for powernv and powerVM
> > + */
> > +struct vas_user_win_ops {
> > + struct vas_window * (*open_win)(struct vas_tx_win_open_attr *,
> > + enum vas_cop_type);
> > + u64 (*paste_addr)(void *);
> > + int (*close_win)(void *);
> > +};
> > +
> > /*
> > * Receive window attributes specified by the (in-kernel) owner of
> > window.
> > */
> > @@ -161,6 +173,9 @@ int vas_copy_crb(void *crb, int offset);
> > * assumed to be true for NX windows.
> > */
> > int vas_paste_crb(struct vas_window *win, int offset, bool re);
> > +int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name);
> > +void vas_unregister_api_powernv(void);
> >
> > /*
> > * Register / unregister coprocessor type to VAS API which will be
> > exported
> > @@ -170,8 +185,9 @@ int vas_paste_crb(struct vas_window *win, int
> > offset, bool re);
> > * Only NX GZIP coprocessor type is supported now, but this API
> > can be
> > * used for others in future.
> > */
> > -int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > - const char *name);
> > -void vas_unregister_api_powernv(void);
> > +int vas_register_coproc_api(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name,
> > + struct vas_user_win_ops *vops);
> > +void vas_unregister_coproc_api(void);
> >
> > #endif /* __ASM_POWERPC_VAS_H */
> > diff --git a/arch/powerpc/platforms/Kconfig
> > b/arch/powerpc/platforms/Kconfig
> > index 7a5e8f4541e3..594544a65b02 100644
> > --- a/arch/powerpc/platforms/Kconfig
> > +++ b/arch/powerpc/platforms/Kconfig
> > @@ -20,6 +20,7 @@ source
> > "arch/powerpc/platforms/embedded6xx/Kconfig"
> > source "arch/powerpc/platforms/44x/Kconfig"
> > source "arch/powerpc/platforms/40x/Kconfig"
> > source "arch/powerpc/platforms/amigaone/Kconfig"
> > +source "arch/powerpc/platforms/book3s/Kconfig"
> >
> > config KVM_GUEST
> > bool "KVM Guest support"
> > diff --git a/arch/powerpc/platforms/Makefile
> > b/arch/powerpc/platforms/Makefile
> > index 143d4417f6cc..0e75d7df387b 100644
> > --- a/arch/powerpc/platforms/Makefile
> > +++ b/arch/powerpc/platforms/Makefile
> > @@ -22,3 +22,4 @@ obj-$(CONFIG_PPC_CELL) += cell/
> > obj-$(CONFIG_PPC_PS3) += ps3/
> > obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
> > obj-$(CONFIG_AMIGAONE) += amigaone/
> > +obj-$(CONFIG_PPC_BOOK3S) += book3s/
> > diff --git a/arch/powerpc/platforms/book3s/Kconfig
> > b/arch/powerpc/platforms/book3s/Kconfig
> > new file mode 100644
> > index 000000000000..51e14db83a79
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/book3s/Kconfig
> > @@ -0,0 +1,15 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +config PPC_VAS
> > + bool "IBM Virtual Accelerator Switchboard (VAS)"
> > + depends on PPC_POWERNV && PPC_64K_PAGES
> > + default y
> > + help
> > + This enables support for IBM Virtual Accelerator Switchboard
> > (VAS).
> > +
> > + VAS allows accelerators in co-processors like NX-GZIP and NX-
> > 842
> > + to be accessible to kernel subsystems and user processes.
> > + VAS adapters are found in POWER9 and later based systems.
> > + The user mode NX-GZIP support is added on P9 for powerNV and
> > on
> > + P10 for powerVM.
> > +
> > + If unsure, say "N".
> > diff --git a/arch/powerpc/platforms/book3s/Makefile
> > b/arch/powerpc/platforms/book3s/Makefile
> > new file mode 100644
> > index 000000000000..e790f1910f61
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/book3s/Makefile
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +obj-$(CONFIG_PPC_VAS) += vas-api.o
> > diff --git a/arch/powerpc/platforms/powernv/vas-api.c
> > b/arch/powerpc/platforms/book3s/vas-api.c
> > similarity index 83%
> > rename from arch/powerpc/platforms/powernv/vas-api.c
> > rename to arch/powerpc/platforms/book3s/vas-api.c
> > index 72d8ce39e56c..05d7b99acf41 100644
> > --- a/arch/powerpc/platforms/powernv/vas-api.c
> > +++ b/arch/powerpc/platforms/book3s/vas-api.c
> > @@ -4,15 +4,20 @@
> > * Copyright (C) 2019 Haren Myneni, IBM Corp
> > */
> >
> > +#include <linux/module.h>
> > #include <linux/kernel.h>
> > #include <linux/device.h>
> > #include <linux/cdev.h>
> > #include <linux/fs.h>
> > #include <linux/slab.h>
> > #include <linux/uaccess.h>
> > +#include <linux/kthread.h>
> > +#include <linux/sched/signal.h>
> > +#include <linux/sched/mm.h>
> > +#include <linux/mmu_context.h>
> > #include <asm/vas.h>
> > +#include <asm/icswx.h>
> > #include <uapi/asm/vas-api.h>
> > -#include "vas.h"
> >
> > /*
> > * The driver creates the device node that can be used as follows:
> > @@ -42,6 +47,7 @@ static struct coproc_dev {
> > dev_t devt;
> > struct class *class;
> > enum vas_cop_type cop_type;
> > + struct vas_user_win_ops *vops;
> > } coproc_device;
> >
> > struct coproc_instance {
> > @@ -72,11 +78,10 @@ static int coproc_open(struct inode *inode,
> > struct file *fp)
> > static int coproc_ioc_tx_win_open(struct file *fp, unsigned long
> > arg)
> > {
> > void __user *uptr = (void __user *)arg;
> > - struct vas_tx_win_attr txattr = {};
> > struct vas_tx_win_open_attr uattr;
> > struct coproc_instance *cp_inst;
> > struct vas_window *txwin;
> > - int rc, vasid;
> > + int rc;
> >
> > cp_inst = fp->private_data;
> >
> > @@ -93,27 +98,20 @@ static int coproc_ioc_tx_win_open(struct file
> > *fp, unsigned long arg)
> > }
> >
> > if (uattr.version != 1) {
> > - pr_err("Invalid version\n");
> > + pr_err("Invalid window open API version\n");
> > return -EINVAL;
> > }
> >
> > - vasid = uattr.vas_id;
> > -
> > - vas_init_tx_win_attr(&txattr, cp_inst->coproc->cop_type);
> > -
> > - txattr.lpid = mfspr(SPRN_LPID);
> > - txattr.pidr = mfspr(SPRN_PID);
> > - txattr.user_win = true;
> > - txattr.rsvd_txbuf_count = false;
> > - txattr.pswid = false;
> > -
> > - pr_devel("Pid %d: Opening txwin, PIDR %ld\n", txattr.pidr,
> > - mfspr(SPRN_PID));
> > + if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->open_win)
> > {
> > + pr_err("VAS API is not registered\n");
> > + return -EACCES;
> > + }
> >
> > - txwin = vas_tx_win_open(vasid, cp_inst->coproc->cop_type,
> > &txattr);
> > + txwin = cp_inst->coproc->vops->open_win(&uattr,
> > + cp_inst->coproc->cop_type);
> > if (IS_ERR(txwin)) {
> > - pr_err("%s() vas_tx_win_open() failed, %ld\n",
> > __func__,
> > - PTR_ERR(txwin));
> > + pr_err("%s() VAS window open failed, %ld\n", __func__,
> > + PTR_ERR(txwin));
> > return PTR_ERR(txwin);
> > }
> >
> > @@ -125,9 +123,14 @@ static int coproc_ioc_tx_win_open(struct file
> > *fp, unsigned long arg)
> > static int coproc_release(struct inode *inode, struct file *fp)
> > {
> > struct coproc_instance *cp_inst = fp->private_data;
> > + int rc = 0;
> >
> > if (cp_inst->txwin) {
> > - vas_win_close(cp_inst->txwin);
> > + if (cp_inst->coproc->vops && cp_inst->coproc->vops-
> > >close_win) {
> > + rc = cp_inst->coproc->vops->close_win(cp_inst-
> > >txwin);
> > + if (rc)
> > + return rc;
> > + }
> > cp_inst->txwin = NULL;
> > }
> >
> > @@ -168,7 +171,17 @@ static int coproc_mmap(struct file *fp, struct
> > vm_area_struct *vma)
> > return -EINVAL;
> > }
> >
> > - vas_win_paste_addr(txwin, &paste_addr, NULL);
> > + if (!cp_inst->coproc->vops && !cp_inst->coproc->vops-
> > >paste_addr) {
> > + pr_err("%s(): VAS API is not registered\n", __func__);
> > + return -EACCES;
> > + }
> > +
> > + paste_addr = cp_inst->coproc->vops->paste_addr(txwin);
> > + if (!paste_addr) {
> > + pr_err("%s(): Window paste address failed\n",
> > __func__);
> > + return -EINVAL;
> > + }
> > +
> > pfn = paste_addr >> PAGE_SHIFT;
> >
> > /* flags, page_prot from cxl_mmap(), except we want cachable */
> > @@ -207,8 +220,8 @@ static struct file_operations coproc_fops = {
> > * Supporting only nx-gzip coprocessor type now, but this API code
> > * extended to other coprocessor types later.
> > */
> > -int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > - const char *name)
> > +int vas_register_coproc_api(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name, struct vas_user_win_ops
> > *vops)
> > {
> > int rc = -EINVAL;
> > dev_t devno;
> > @@ -230,6 +243,7 @@ int vas_register_api_powernv(struct module
> > *mod, enum vas_cop_type cop_type,
> > }
> > coproc_device.class->devnode = coproc_devnode;
> > coproc_device.cop_type = cop_type;
> > + coproc_device.vops = vops;
> >
> > coproc_fops.owner = mod;
> > cdev_init(&coproc_device.cdev, &coproc_fops);
> > @@ -262,9 +276,8 @@ int vas_register_api_powernv(struct module
> > *mod, enum vas_cop_type cop_type,
> > unregister_chrdev_region(coproc_device.devt, 1);
> > return rc;
> > }
> > -EXPORT_SYMBOL_GPL(vas_register_api_powernv);
> >
> > -void vas_unregister_api_powernv(void)
> > +void vas_unregister_coproc_api(void)
> > {
> > dev_t devno;
> >
> > @@ -275,4 +288,3 @@ void vas_unregister_api_powernv(void)
> > class_destroy(coproc_device.class);
> > unregister_chrdev_region(coproc_device.devt, 1);
> > }
> > -EXPORT_SYMBOL_GPL(vas_unregister_api_powernv);
> > diff --git a/arch/powerpc/platforms/powernv/Kconfig
> > b/arch/powerpc/platforms/powernv/Kconfig
> > index 619b093a0657..043eefbbdd28 100644
> > --- a/arch/powerpc/platforms/powernv/Kconfig
> > +++ b/arch/powerpc/platforms/powernv/Kconfig
> > @@ -33,20 +33,6 @@ config PPC_MEMTRACE
> > Enabling this option allows for runtime allocation of memory
> > (RAM)
> > for hardware tracing.
> >
> > -config PPC_VAS
> > - bool "IBM Virtual Accelerator Switchboard (VAS)"
> > - depends on PPC_POWERNV && PPC_64K_PAGES
> > - default y
> > - help
> > - This enables support for IBM Virtual Accelerator Switchboard
> > (VAS).
> > -
> > - VAS allows accelerators in co-processors like NX-GZIP and NX-
> > 842
> > - to be accessible to kernel subsystems and user processes.
> > -
> > - VAS adapters are found in POWER9 based systems.
> > -
> > - If unsure, say N.
> > -
> > config SCOM_DEBUGFS
> > bool "Expose SCOM controllers via debugfs"
> > depends on DEBUG_FS
> > diff --git a/arch/powerpc/platforms/powernv/Makefile
> > b/arch/powerpc/platforms/powernv/Makefile
> > index 2eb6ae150d1f..c747a1f1d25b 100644
> > --- a/arch/powerpc/platforms/powernv/Makefile
> > +++ b/arch/powerpc/platforms/powernv/Makefile
> > @@ -18,7 +18,7 @@ obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-
> > errors.o
> > obj-$(CONFIG_OPAL_PRD) += opal-prd.o
> > obj-$(CONFIG_PERF_EVENTS) += opal-imc.o
> > obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o
> > -obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o vas-
> > fault.o vas-api.o
> > +obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o vas-
> > fault.o
> > obj-$(CONFIG_OCXL_BASE) += ocxl.o
> > obj-$(CONFIG_SCOM_DEBUGFS) += opal-xscom.o
> > obj-$(CONFIG_PPC_SECURE_BOOT) += opal-secvar.o
> > diff --git a/arch/powerpc/platforms/powernv/vas-window.c
> > b/arch/powerpc/platforms/powernv/vas-window.c
> > index 5f5fe63a3d1c..b973dd574b47 100644
> > --- a/arch/powerpc/platforms/powernv/vas-window.c
> > +++ b/arch/powerpc/platforms/powernv/vas-window.c
> > @@ -16,6 +16,8 @@
> > #include <linux/mmu_context.h>
> > #include <asm/switch_to.h>
> > #include <asm/ppc-opcode.h>
> > +#include <asm/vas.h>
> > +#include <uapi/asm/vas-api.h>
> > #include "vas.h"
> > #include "copy-paste.h"
> >
> > @@ -1441,3 +1443,67 @@ struct vas_window
> > *vas_pswid_to_window(struct vas_instance *vinst,
> >
> > return window;
> > }
> > +
> > +static struct vas_window *vas_user_win_open(struct
> > vas_tx_win_open_attr *uattr,
> > + enum vas_cop_type cop_type)
> > +{
> > + struct vas_tx_win_attr txattr = {};
> > +
> > + vas_init_tx_win_attr(&txattr, cop_type);
> > +
> > + txattr.lpid = mfspr(SPRN_LPID);
> > + txattr.pidr = mfspr(SPRN_PID);
> > + txattr.user_win = true;
> > + txattr.rsvd_txbuf_count = false;
> > + txattr.pswid = false;
> > +
> > + pr_devel("Pid %d: Opening txwin, PIDR %ld\n", txattr.pidr,
> > + mfspr(SPRN_PID));
> > +
> > + return vas_tx_win_open(uattr->vas_id, cop_type, &txattr);
> > +}
> > +
> > +static u64 vas_user_win_paste_addr(void *addr)
> > +{
> > + u64 paste_addr;
> > +
> > + vas_win_paste_addr((struct vas_window *)addr, &paste_addr,
> > NULL);
> > +
> > + return paste_addr;
> > +}
> > +
> > +static int vas_user_win_close(void *addr)
> > +{
> > + struct vas_window *txwin = addr;
> > +
> > + vas_win_close(txwin);
> > +
> > + return 0;
> > +}
> > +
> > +static struct vas_user_win_ops vops = {
> > + .open_win = vas_user_win_open,
> > + .paste_addr = vas_user_win_paste_addr,
> > + .close_win = vas_user_win_close,
> > +};
> > +
> > +/*
> > + * Supporting only nx-gzip coprocessor type now, but this API code
> > + * extended to other coprocessor types later.
> > + */
> > +int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name)
> > +{
> > + int rc;
> > +
> > + rc = vas_register_coproc_api(mod, cop_type, name, &vops);
> > +
> > + return rc;
> > +}
> > +EXPORT_SYMBOL_GPL(vas_register_api_powernv);
> > +
> > +void vas_unregister_api_powernv(void)
> > +{
> > + vas_unregister_coproc_api();
> > +}
> > +EXPORT_SYMBOL_GPL(vas_unregister_api_powernv);
> > --
> > 2.18.2
> >
> >
> >
^ permalink raw reply
* Re: [V3 PATCH 05/16] powerpc/vas: Define and use common vas_window struct
From: Haren Myneni @ 2021-05-10 17:02 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620625034.ib9vm2fvp0.astroid@bobo.none>
On Mon, 2021-05-10 at 15:37 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:04 am:
> >
>
> Empty email?
>
> Thanks,
> Nick
Sorry, My mistake. Here is the patch and will add in V4 series.
[V3 PATCH 05/16] powerpc/vas: Define and use common vas_window struct
Same vas_window struct is used on powerNV and pseries. So this patch
changes in struct vas_window to support both platforms and also the
corresponding modifications in powerNV vas code.
On powerNV, vas_window is used for both TX and RX windows, whereas
only for TX windows on powerVM. So some elements are specific to
these platforms.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/include/asm/vas.h | 48 ++++++++
arch/powerpc/platforms/powernv/vas-debug.c | 12 +-
arch/powerpc/platforms/powernv/vas-fault.c | 4 +-
arch/powerpc/platforms/powernv/vas-trace.h | 6 +-
arch/powerpc/platforms/powernv/vas-window.c | 129 +++++++++++---------
arch/powerpc/platforms/powernv/vas.h | 38 +-----
6 files changed, 135 insertions(+), 102 deletions(-)
diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h
index 66bf8fb1a1be..f928bf4c7e98 100644
--- a/arch/powerpc/include/asm/vas.h
+++ b/arch/powerpc/include/asm/vas.h
@@ -69,6 +69,54 @@ struct vas_win_task {
struct mm_struct *mm; /* Linux process mm_struct */
};
+/*
+ * In-kernel state a VAS window. One per window.
+ * powerVM: Used only for Tx windows.
+ * powerNV: Used for both Tx and Rx windows.
+ */
+struct vas_window {
+ u32 winid;
+ u32 wcreds_max; /* Window credits */
+ enum vas_cop_type cop;
+ struct vas_win_task task;
+ char *dbgname;
+ struct dentry *dbgdir;
+ union {
+ /* powerNV specific data */
+ struct {
+ void *vinst; /* points to VAS instance */
+ bool tx_win; /* True if send window */
+ bool nx_win; /* True if NX window */
+ bool user_win; /* True if user space window */
+ void *hvwc_map; /* HV window context */
+ void *uwc_map; /* OS/User window context */
+
+ /* Fields applicable only to send windows */
+ void *paste_kaddr;
+ char *paste_addr_name;
+ struct vas_window *rxwin;
+
+ atomic_t num_txwins; /* Only for receive windows */
+ } pnv;
+ struct {
+ u64 win_addr; /* Physical paste address */
+ u8 win_type; /* QoS or Default window */
+ u8 status;
+ u32 complete_irq; /* Completion interrupt */
+ u32 fault_irq; /* Fault interrupt */
+ u64 domain[6]; /* Associativity domain Ids */
+ /* this window is allocated */
+ u64 util;
+
+ /* List of windows opened which is used for LPM */
+ struct list_head win_list;
+ u64 flags;
+ char *name;
+ int fault_virq;
+ } lpar;
+ };
+};
+
static inline void vas_drop_reference_task(struct vas_win_task *task)
{
/* Drop references to pid and mm */
diff --git a/arch/powerpc/platforms/powernv/vas-debug.c b/arch/powerpc/platforms/powernv/vas-debug.c
index 41fa90d2f4ab..80f735449ab8 100644
--- a/arch/powerpc/platforms/powernv/vas-debug.c
+++ b/arch/powerpc/platforms/powernv/vas-debug.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <asm/vas.h>
#include "vas.h"
static struct dentry *vas_debugfs;
@@ -33,11 +34,11 @@ static int info_show(struct seq_file *s, void *private)
mutex_lock(&vas_mutex);
/* ensure window is not unmapped */
- if (!window->hvwc_map)
+ if (!window->pnv.hvwc_map)
goto unlock;
seq_printf(s, "Type: %s, %s\n", cop_to_str(window->cop),
- window->tx_win ? "Send" : "Receive");
+ window->pnv.tx_win ? "Send" : "Receive");
seq_printf(s, "Pid : %d\n", vas_window_pid(window));
unlock:
@@ -60,7 +61,7 @@ static int hvwc_show(struct seq_file *s, void *private)
mutex_lock(&vas_mutex);
/* ensure window is not unmapped */
- if (!window->hvwc_map)
+ if (!window->pnv.hvwc_map)
goto unlock;
print_reg(s, window, VREG(LPID));
@@ -115,9 +116,10 @@ void vas_window_free_dbgdir(struct vas_window *window)
void vas_window_init_dbgdir(struct vas_window *window)
{
+ struct vas_instance *vinst = window->pnv.vinst;
struct dentry *d;
- if (!window->vinst->dbgdir)
+ if (!vinst->dbgdir)
return;
window->dbgname = kzalloc(16, GFP_KERNEL);
@@ -126,7 +128,7 @@ void vas_window_init_dbgdir(struct vas_window *window)
snprintf(window->dbgname, 16, "w%d", window->winid);
- d = debugfs_create_dir(window->dbgname, window->vinst->dbgdir);
+ d = debugfs_create_dir(window->dbgname, vinst->dbgdir);
window->dbgdir = d;
debugfs_create_file("info", 0444, d, window, &info_fops);
diff --git a/arch/powerpc/platforms/powernv/vas-fault.c b/arch/powerpc/platforms/powernv/vas-fault.c
index 2e898eac1bb2..82acede2d892 100644
--- a/arch/powerpc/platforms/powernv/vas-fault.c
+++ b/arch/powerpc/platforms/powernv/vas-fault.c
@@ -152,10 +152,10 @@ irqreturn_t vas_fault_thread_fn(int irq, void *data)
/*
* NX sees faults only with user space windows.
*/
- if (window->user_win)
+ if (window->pnv.user_win)
vas_update_csb(crb, &window->task);
else
- WARN_ON_ONCE(!window->user_win);
+ WARN_ON_ONCE(!window->pnv.user_win);
/*
* Return credit for send window after processing
diff --git a/arch/powerpc/platforms/powernv/vas-trace.h b/arch/powerpc/platforms/powernv/vas-trace.h
index a449b9f0c12e..843aae37c07a 100644
--- a/arch/powerpc/platforms/powernv/vas-trace.h
+++ b/arch/powerpc/platforms/powernv/vas-trace.h
@@ -95,9 +95,11 @@ TRACE_EVENT( vas_paste_crb,
TP_fast_assign(
__entry->pid = tsk->pid;
- __entry->vasid = win->vinst->vas_id;
+ __entry->vasid =
+ ((struct vas_instance *)win->pnv.vinst)->vas_id;
__entry->winid = win->winid;
- __entry->paste_kaddr = (unsigned long)win->paste_kaddr
+ __entry->paste_kaddr =
+ (unsigned long)win->pnv.paste_kaddr;
),
TP_printk("pid=%d, vasid=%d, winid=%d, paste_kaddr=0x%016lx\n",
diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c
index 58e3d16c316f..254be61c73ab 100644
--- a/arch/powerpc/platforms/powernv/vas-window.c
+++ b/arch/powerpc/platforms/powernv/vas-window.c
@@ -32,9 +32,10 @@ void vas_win_paste_addr(struct vas_window *window, u64 *addr, int *len)
{
int winid;
u64 base, shift;
+ struct vas_instance *vinst = window->pnv.vinst;
- base = window->vinst->paste_base_addr;
- shift = window->vinst->paste_win_id_shift;
+ base = vinst->paste_base_addr;
+ shift = vinst->paste_win_id_shift;
winid = window->winid;
*addr = base + (winid << shift);
@@ -47,9 +48,10 @@ void vas_win_paste_addr(struct vas_window *window, u64 *addr, int *len)
static inline void get_hvwc_mmio_bar(struct vas_window *window,
u64 *start, int *len)
{
+ struct vas_instance *vinst = window->pnv.vinst;
u64 pbaddr;
- pbaddr = window->vinst->hvwc_bar_start;
+ pbaddr = vinst->hvwc_bar_start;
*start = pbaddr + window->winid * VAS_HVWC_SIZE;
*len = VAS_HVWC_SIZE;
}
@@ -57,9 +59,10 @@ static inline void get_hvwc_mmio_bar(struct vas_window *window,
static inline void get_uwc_mmio_bar(struct vas_window *window,
u64 *start, int *len)
{
+ struct vas_instance *vinst = window->pnv.vinst;
u64 pbaddr;
- pbaddr = window->vinst->uwc_bar_start;
+ pbaddr = vinst->uwc_bar_start;
*start = pbaddr + window->winid * VAS_UWC_SIZE;
*len = VAS_UWC_SIZE;
}
@@ -75,13 +78,14 @@ static void *map_paste_region(struct vas_window *txwin)
void *map;
char *name;
u64 start;
+ struct vas_instance *vinst = txwin->pnv.vinst;
- name = kasprintf(GFP_KERNEL, "window-v%d-w%d", txwin->vinst->vas_id,
+ name = kasprintf(GFP_KERNEL, "window-v%d-w%d", vinst->vas_id,
txwin->winid);
if (!name)
goto free_name;
- txwin->paste_addr_name = name;
+ txwin->pnv.paste_addr_name = name;
vas_win_paste_addr(txwin, &start, &len);
if (!request_mem_region(start, len, name)) {
@@ -139,12 +143,12 @@ static void unmap_paste_region(struct vas_window *window)
int len;
u64 busaddr_start;
- if (window->paste_kaddr) {
+ if (window->pnv.paste_kaddr) {
vas_win_paste_addr(window, &busaddr_start, &len);
- unmap_region(window->paste_kaddr, busaddr_start, len);
- window->paste_kaddr = NULL;
- kfree(window->paste_addr_name);
- window->paste_addr_name = NULL;
+ unmap_region(window->pnv.paste_kaddr, busaddr_start, len);
+ window->pnv.paste_kaddr = NULL;
+ kfree(window->pnv.paste_addr_name);
+ window->pnv.paste_addr_name = NULL;
}
}
@@ -164,11 +168,11 @@ static void unmap_winctx_mmio_bars(struct vas_window *window)
mutex_lock(&vas_mutex);
- hvwc_map = window->hvwc_map;
- window->hvwc_map = NULL;
+ hvwc_map = window->pnv.hvwc_map;
+ window->pnv.hvwc_map = NULL;
- uwc_map = window->uwc_map;
- window->uwc_map = NULL;
+ uwc_map = window->pnv.uwc_map;
+ window->pnv.uwc_map = NULL;
mutex_unlock(&vas_mutex);
@@ -194,12 +198,12 @@ static int map_winctx_mmio_bars(struct vas_window *window)
u64 start;
get_hvwc_mmio_bar(window, &start, &len);
- window->hvwc_map = map_mmio_region("HVWCM_Window", start, len);
+ window->pnv.hvwc_map = map_mmio_region("HVWCM_Window", start, len);
get_uwc_mmio_bar(window, &start, &len);
- window->uwc_map = map_mmio_region("UWCM_Window", start, len);
+ window->pnv.uwc_map = map_mmio_region("UWCM_Window", start, len);
- if (!window->hvwc_map || !window->uwc_map) {
+ if (!window->pnv.hvwc_map || !window->pnv.uwc_map) {
unmap_winctx_mmio_bars(window);
return -1;
}
@@ -524,7 +528,7 @@ static int vas_assign_window_id(struct ida *ida)
static void vas_window_free(struct vas_window *window)
{
int winid = window->winid;
- struct vas_instance *vinst = window->vinst;
+ struct vas_instance *vinst = window->pnv.vinst;
unmap_winctx_mmio_bars(window);
@@ -548,7 +552,7 @@ static struct vas_window *vas_window_alloc(struct vas_instance *vinst)
if (!window)
goto out_free;
- window->vinst = vinst;
+ window->pnv.vinst = vinst;
window->winid = winid;
if (map_winctx_mmio_bars(window))
@@ -567,9 +571,9 @@ static struct vas_window *vas_window_alloc(struct vas_instance *vinst)
static void put_rx_win(struct vas_window *rxwin)
{
/* Better not be a send window! */
- WARN_ON_ONCE(rxwin->tx_win);
+ WARN_ON_ONCE(rxwin->pnv.tx_win);
- atomic_dec(&rxwin->num_txwins);
+ atomic_dec(&rxwin->pnv.num_txwins);
}
/*
@@ -592,7 +596,7 @@ static struct vas_window *get_user_rxwin(struct vas_instance *vinst, u32 pswid)
rxwin = vinst->windows[winid];
- if (!rxwin || rxwin->tx_win || rxwin->cop != VAS_COP_TYPE_FTW)
+ if (!rxwin || rxwin->pnv.tx_win || rxwin->cop != VAS_COP_TYPE_FTW)
return ERR_PTR(-EINVAL);
return rxwin;
@@ -617,7 +621,7 @@ static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst,
rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL);
if (!IS_ERR(rxwin))
- atomic_inc(&rxwin->num_txwins);
+ atomic_inc(&rxwin->pnv.num_txwins);
mutex_unlock(&vinst->mutex);
@@ -650,7 +654,7 @@ static void set_vinst_win(struct vas_instance *vinst,
* There should only be one receive window for a coprocessor type
* unless its a user (FTW) window.
*/
- if (!window->user_win && !window->tx_win) {
+ if (!window->pnv.user_win && !window->pnv.tx_win) {
WARN_ON_ONCE(vinst->rxwin[window->cop]);
vinst->rxwin[window->cop] = window;
}
@@ -668,11 +672,11 @@ static void set_vinst_win(struct vas_instance *vinst,
static void clear_vinst_win(struct vas_window *window)
{
int id = window->winid;
- struct vas_instance *vinst = window->vinst;
+ struct vas_instance *vinst = window->pnv.vinst;
mutex_lock(&vinst->mutex);
- if (!window->user_win && !window->tx_win) {
+ if (!window->pnv.user_win && !window->pnv.tx_win) {
WARN_ON_ONCE(!vinst->rxwin[window->cop]);
vinst->rxwin[window->cop] = NULL;
}
@@ -687,6 +691,8 @@ static void init_winctx_for_rxwin(struct vas_window *rxwin,
struct vas_rx_win_attr *rxattr,
struct vas_winctx *winctx)
{
+ struct vas_instance *vinst;
+
/*
* We first zero (memset()) all fields and only set non-zero fields.
* Following fields are 0/false but maybe deserve a comment:
@@ -751,8 +757,9 @@ static void init_winctx_for_rxwin(struct vas_window *rxwin,
winctx->min_scope = VAS_SCOPE_LOCAL;
winctx->max_scope = VAS_SCOPE_VECTORED_GROUP;
- if (rxwin->vinst->virq)
- winctx->irq_port = rxwin->vinst->irq_port;
+ vinst = rxwin->pnv.vinst;
+ if (vinst->virq)
+ winctx->irq_port = vinst->irq_port;
}
static bool rx_win_args_valid(enum vas_cop_type cop,
@@ -875,9 +882,9 @@ struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop,
return rxwin;
}
- rxwin->tx_win = false;
- rxwin->nx_win = rxattr->nx_win;
- rxwin->user_win = rxattr->user_win;
+ rxwin->pnv.tx_win = false;
+ rxwin->pnv.nx_win = rxattr->nx_win;
+ rxwin->pnv.user_win = rxattr->user_win;
rxwin->cop = cop;
rxwin->wcreds_max = rxattr->wcreds_max;
@@ -911,6 +918,8 @@ static void init_winctx_for_txwin(struct vas_window *txwin,
struct vas_tx_win_attr *txattr,
struct vas_winctx *winctx)
{
+ struct vas_instance *vinst = txwin->pnv.vinst;
+
/*
* We first zero all fields and only set non-zero ones. Following
* are some fields set to 0/false for the stated reason:
@@ -931,7 +940,7 @@ static void init_winctx_for_txwin(struct vas_window *txwin,
winctx->wcreds_max = txwin->wcreds_max;
winctx->user_win = txattr->user_win;
- winctx->nx_win = txwin->rxwin->nx_win;
+ winctx->nx_win = txwin->pnv.rxwin->pnv.nx_win;
winctx->pin_win = txattr->pin_win;
winctx->rej_no_credit = txattr->rej_no_credit;
winctx->rsvd_txbuf_enable = txattr->rsvd_txbuf_enable;
@@ -948,23 +957,23 @@ static void init_winctx_for_txwin(struct vas_window *txwin,
winctx->lpid = txattr->lpid;
winctx->pidr = txattr->pidr;
- winctx->rx_win_id = txwin->rxwin->winid;
+ winctx->rx_win_id = txwin->pnv.rxwin->winid;
/*
* IRQ and fault window setup is successful. Set fault window
* for the send window so that ready to handle faults.
*/
- if (txwin->vinst->virq)
- winctx->fault_win_id = txwin->vinst->fault_win->winid;
+ if (vinst->virq)
+ winctx->fault_win_id = vinst->fault_win->winid;
winctx->dma_type = VAS_DMA_TYPE_INJECT;
winctx->tc_mode = txattr->tc_mode;
winctx->min_scope = VAS_SCOPE_LOCAL;
winctx->max_scope = VAS_SCOPE_VECTORED_GROUP;
- if (txwin->vinst->virq)
- winctx->irq_port = txwin->vinst->irq_port;
+ if (vinst->virq)
+ winctx->irq_port = vinst->irq_port;
winctx->pswid = txattr->pswid ? txattr->pswid :
- encode_pswid(txwin->vinst->vas_id, txwin->winid);
+ encode_pswid(vinst->vas_id, txwin->winid);
}
static bool tx_win_args_valid(enum vas_cop_type cop,
@@ -1032,10 +1041,10 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
}
txwin->cop = cop;
- txwin->tx_win = 1;
- txwin->rxwin = rxwin;
- txwin->nx_win = txwin->rxwin->nx_win;
- txwin->user_win = attr->user_win;
+ txwin->pnv.tx_win = 1;
+ txwin->pnv.rxwin = rxwin;
+ txwin->pnv.nx_win = txwin->pnv.rxwin->pnv.nx_win;
+ txwin->pnv.user_win = attr->user_win;
txwin->wcreds_max = attr->wcreds_max ?: VAS_WCREDS_DEFAULT;
init_winctx_for_txwin(txwin, attr, &winctx);
@@ -1050,10 +1059,10 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
* NOTE: If kernel ever resubmits a user CRB after handling a page
* fault, we will need to map this into kernel as well.
*/
- if (!txwin->user_win) {
- txwin->paste_kaddr = map_paste_region(txwin);
- if (IS_ERR(txwin->paste_kaddr)) {
- rc = PTR_ERR(txwin->paste_kaddr);
+ if (!txwin->pnv.user_win) {
+ txwin->pnv.paste_kaddr = map_paste_region(txwin);
+ if (IS_ERR(txwin->pnv.paste_kaddr)) {
+ rc = PTR_ERR(txwin->pnv.paste_kaddr);
goto free_window;
}
} else {
@@ -1105,9 +1114,9 @@ int vas_paste_crb(struct vas_window *txwin, int offset, bool re)
* report-enable flag is set for NX windows. Ensure software
* complies too.
*/
- WARN_ON_ONCE(txwin->nx_win && !re);
+ WARN_ON_ONCE(txwin->pnv.nx_win && !re);
- addr = txwin->paste_kaddr;
+ addr = txwin->pnv.paste_kaddr;
if (re) {
/*
* Set the REPORT_ENABLE bit (equivalent to writing
@@ -1154,7 +1163,7 @@ static void poll_window_credits(struct vas_window *window)
int count = 0;
val = read_hvwc_reg(window, VREG(WINCTL));
- if (window->tx_win)
+ if (window->pnv.tx_win)
mode = GET_FIELD(VAS_WINCTL_TX_WCRED_MODE, val);
else
mode = GET_FIELD(VAS_WINCTL_RX_WCRED_MODE, val);
@@ -1162,7 +1171,7 @@ static void poll_window_credits(struct vas_window *window)
if (!mode)
return;
retry:
- if (window->tx_win) {
+ if (window->pnv.tx_win) {
val = read_hvwc_reg(window, VREG(TX_WCRED));
creds = GET_FIELD(VAS_TX_WCRED, val);
} else {
@@ -1278,7 +1287,7 @@ int vas_win_close(struct vas_window *window)
if (!window)
return 0;
- if (!window->tx_win && atomic_read(&window->num_txwins) != 0) {
+ if (!window->pnv.tx_win && atomic_read(&window->pnv.num_txwins) != 0) {
pr_devel("Attempting to close an active Rx window!\n");
WARN_ON_ONCE(1);
return -EBUSY;
@@ -1297,11 +1306,11 @@ int vas_win_close(struct vas_window *window)
poll_window_castout(window);
/* if send window, drop reference to matching receive window */
- if (window->tx_win) {
- if (window->user_win)
+ if (window->pnv.tx_win) {
+ if (window->pnv.user_win)
vas_drop_reference_task(&window->task);
- put_rx_win(window->rxwin);
+ put_rx_win(window->pnv.rxwin);
}
vas_window_free(window);
@@ -1385,12 +1394,12 @@ struct vas_window *vas_pswid_to_window(struct vas_instance *vinst,
* since their CRBs are ignored (not queued on FIFO or processed
* by NX).
*/
- if (!window->tx_win || !window->user_win || !window->nx_win ||
- window->cop == VAS_COP_TYPE_FAULT ||
- window->cop == VAS_COP_TYPE_FTW) {
+ if (!window->pnv.tx_win || !window->pnv.user_win ||
+ !window->pnv.nx_win || window->cop == VAS_COP_TYPE_FAULT ||
+ window->cop == VAS_COP_TYPE_FTW) {
pr_err("PSWID decode: id %d, tx %d, user %d, nx %d, cop %d\n",
- winid, window->tx_win, window->user_win,
- window->nx_win, window->cop);
+ winid, window->pnv.tx_win, window->pnv.user_win,
+ window->pnv.nx_win, window->cop);
WARN_ON(1);
}
diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h
index f7aa2d04cd16..72ccb2f692cc 100644
--- a/arch/powerpc/platforms/powernv/vas.h
+++ b/arch/powerpc/platforms/powernv/vas.h
@@ -345,34 +345,6 @@ struct vas_instance {
struct dentry *dbgdir;
};
-/*
- * In-kernel state a VAS window. One per window.
- */
-struct vas_window {
- /* Fields common to send and receive windows */
- struct vas_instance *vinst;
- int winid;
- bool tx_win; /* True if send window */
- bool nx_win; /* True if NX window */
- bool user_win; /* True if user space window */
- void *hvwc_map; /* HV window context */
- void *uwc_map; /* OS/User window context */
- int wcreds_max; /* Window credits */
-
- struct vas_win_task task;
- char *dbgname;
- struct dentry *dbgdir;
-
- /* Fields applicable only to send windows */
- void *paste_kaddr;
- char *paste_addr_name;
- struct vas_window *rxwin;
-
- /* Feilds applicable only to receive windows */
- enum vas_cop_type cop;
- atomic_t num_txwins;
-};
-
/*
* Container for the hardware state of a window. One per-window.
*
@@ -449,8 +421,8 @@ static inline void vas_log_write(struct vas_window *win, char *name,
{
if (val)
pr_debug("%swin #%d: %s reg %p, val 0x%016llx\n",
- win->tx_win ? "Tx" : "Rx", win->winid, name,
- regptr, val);
+ win->pnv.tx_win ? "Tx" : "Rx", win->winid,
+ name, regptr, val);
}
static inline void write_uwc_reg(struct vas_window *win, char *name,
@@ -458,7 +430,7 @@ static inline void write_uwc_reg(struct vas_window *win, char *name,
{
void *regptr;
- regptr = win->uwc_map + reg;
+ regptr = win->pnv.uwc_map + reg;
vas_log_write(win, name, regptr, val);
out_be64(regptr, val);
@@ -469,7 +441,7 @@ static inline void write_hvwc_reg(struct vas_window *win, char *name,
{
void *regptr;
- regptr = win->hvwc_map + reg;
+ regptr = win->pnv.hvwc_map + reg;
vas_log_write(win, name, regptr, val);
out_be64(regptr, val);
@@ -478,7 +450,7 @@ static inline void write_hvwc_reg(struct vas_window *win, char *name,
static inline u64 read_hvwc_reg(struct vas_window *win,
char *name __maybe_unused, s32 reg)
{
- return in_be64(win->hvwc_map+reg);
+ return in_be64(win->pnv.hvwc_map + reg);
}
/*
--
2.18.2
^ permalink raw reply related
* Re: [V3 PATCH 01/16] powerpc/powernv/vas: Rename register/unregister functions
From: Haren Myneni @ 2021-05-10 16:59 UTC (permalink / raw)
To: Nicholas Piggin, herbert, linux-crypto, linuxppc-dev, mpe
In-Reply-To: <1620622742.tr9lqg4vzz.astroid@bobo.none>
On Mon, 2021-05-10 at 15:10 +1000, Nicholas Piggin wrote:
> Excerpts from Haren Myneni's message of April 18, 2021 7:00 am:
> > powerNV and pseries drivers register / unregister to the
> > corresponding
> > VAS code separately. So rename powerNV VAS API register/unregister
> > functions.
>
> The pseries VAS driver will have different calls for registering a
> coprocessor driver, you mean?
>
> It certainly looks the same
>
> (from patch 13)
> ret = vas_register_api_pseries(THIS_MODULE, VAS_COP_TYPE_GZIP,
> "nx-gzip");
>
> So I guess it's just a matter of the driver being different enough
> that
> there is no benefit to making this call common (and branching to
> pseries
> or powernv dynamically).
Thanks for your review and comments on all patches.
Yes, we have separate drivers nx-common-powernv/nx-common-pseries for
powerNV and pseries.
API registeration patch is:
- driver calls platform specific API
vas_register_api_powernv/pseries
- Platform specific code calls common API with its vas_user_win_ops
vas_register_coproc_api()
>
> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> > Signed-off-by: Haren Myneni <haren@linux.ibm.com>
> > ---
> > arch/powerpc/include/asm/vas.h | 6 +++---
> > arch/powerpc/platforms/powernv/vas-api.c | 10 +++++-----
> > drivers/crypto/nx/nx-common-powernv.c | 6 +++---
> > 3 files changed, 11 insertions(+), 11 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/vas.h
> > b/arch/powerpc/include/asm/vas.h
> > index e33f80b0ea81..41f73fae7ab8 100644
> > --- a/arch/powerpc/include/asm/vas.h
> > +++ b/arch/powerpc/include/asm/vas.h
> > @@ -170,8 +170,8 @@ int vas_paste_crb(struct vas_window *win, int
> > offset, bool re);
> > * Only NX GZIP coprocessor type is supported now, but this API
> > can be
> > * used for others in future.
> > */
> > -int vas_register_coproc_api(struct module *mod, enum vas_cop_type
> > cop_type,
> > - const char *name);
> > -void vas_unregister_coproc_api(void);
> > +int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name);
> > +void vas_unregister_api_powernv(void);
> >
> > #endif /* __ASM_POWERPC_VAS_H */
> > diff --git a/arch/powerpc/platforms/powernv/vas-api.c
> > b/arch/powerpc/platforms/powernv/vas-api.c
> > index 98ed5d8c5441..72d8ce39e56c 100644
> > --- a/arch/powerpc/platforms/powernv/vas-api.c
> > +++ b/arch/powerpc/platforms/powernv/vas-api.c
> > @@ -207,8 +207,8 @@ static struct file_operations coproc_fops = {
> > * Supporting only nx-gzip coprocessor type now, but this API code
> > * extended to other coprocessor types later.
> > */
> > -int vas_register_coproc_api(struct module *mod, enum vas_cop_type
> > cop_type,
> > - const char *name)
> > +int vas_register_api_powernv(struct module *mod, enum vas_cop_type
> > cop_type,
> > + const char *name)
> > {
> > int rc = -EINVAL;
> > dev_t devno;
> > @@ -262,9 +262,9 @@ int vas_register_coproc_api(struct module *mod,
> > enum vas_cop_type cop_type,
> > unregister_chrdev_region(coproc_device.devt, 1);
> > return rc;
> > }
> > -EXPORT_SYMBOL_GPL(vas_register_coproc_api);
> > +EXPORT_SYMBOL_GPL(vas_register_api_powernv);
> >
> > -void vas_unregister_coproc_api(void)
> > +void vas_unregister_api_powernv(void)
> > {
> > dev_t devno;
> >
> > @@ -275,4 +275,4 @@ void vas_unregister_coproc_api(void)
> > class_destroy(coproc_device.class);
> > unregister_chrdev_region(coproc_device.devt, 1);
> > }
> > -EXPORT_SYMBOL_GPL(vas_unregister_coproc_api);
> > +EXPORT_SYMBOL_GPL(vas_unregister_api_powernv);
> > diff --git a/drivers/crypto/nx/nx-common-powernv.c
> > b/drivers/crypto/nx/nx-common-powernv.c
> > index 13c65deda8e9..88d728415bb2 100644
> > --- a/drivers/crypto/nx/nx-common-powernv.c
> > +++ b/drivers/crypto/nx/nx-common-powernv.c
> > @@ -1090,8 +1090,8 @@ static __init int
> > nx_compress_powernv_init(void)
> > * normal FIFO priority is assigned for userspace.
> > * 842 compression is supported only in kernel.
> > */
> > - ret = vas_register_coproc_api(THIS_MODULE,
> > VAS_COP_TYPE_GZIP,
> > - "nx-gzip");
> > + ret = vas_register_api_powernv(THIS_MODULE,
> > VAS_COP_TYPE_GZIP,
> > + "nx-gzip");
> >
> > /*
> > * GZIP is not supported in kernel right now.
> > @@ -1127,7 +1127,7 @@ static void __exit
> > nx_compress_powernv_exit(void)
> > * use. So delete this API use for GZIP engine.
> > */
> > if (!nx842_ct)
> > - vas_unregister_coproc_api();
> > + vas_unregister_api_powernv();
> >
> > crypto_unregister_alg(&nx842_powernv_alg);
> >
> > --
> > 2.18.2
> >
> >
> >
^ permalink raw reply
* Re: [PATCH 01/11] PCI: Use sysfs_emit() and sysfs_emit_at() in "show" functions
From: Logan Gunthorpe @ 2021-05-10 15:57 UTC (permalink / raw)
To: Krzysztof Wilczyński, Bjorn Helgaas
Cc: Tyrel Datwyler, linux-pci, Oliver O'Halloran, Paul Mackerras,
Kurt Schwemmer, linuxppc-dev
In-Reply-To: <20210510041424.233565-1-kw@linux.com>
On 2021-05-09 10:14 p.m., Krzysztof Wilczyński wrote:
> The sysfs_emit() and sysfs_emit_at() functions were introduced to make
> it less ambiguous which function is preferred when writing to the output
> buffer in a device attribute's "show" callback [1].
>
> Convert the PCI sysfs object "show" functions from sprintf(), snprintf()
> and scnprintf() to sysfs_emit() and sysfs_emit_at() accordingly, as the
> latter is aware of the PAGE_SIZE buffer and correctly returns the number
> of bytes written into the buffer.
>
> No functional change intended.
>
> [1] Documentation/filesystems/sysfs.rst
>
> Related to:
> commit ad025f8e46f3 ("PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions")
>
> Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
Thanks, this is a great cleanup. I've reviewed the entire series.
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
I agree that the new lines that are missing should be added.
Logan
^ permalink raw reply
* Re: [PATCH v6 08/15] swiotlb: Bounce data from/to restricted DMA pool if available
From: Christoph Hellwig @ 2021-05-10 15:05 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, Frank Rowand, mingo,
Marek Szyprowski, sstabellini, Saravana Kannan, Joerg Roedel,
Rafael J . Wysocki, Christoph Hellwig, Bartosz Golaszewski,
bskeggs, linux-pci, xen-devel, Thierry Reding, intel-gfx,
matthew.auld, linux-devicetree, jxgao, daniel, Will Deacon,
Konrad Rzeszutek Wilk, maarten.lankhorst, airlied, Dan Williams,
linuxppc-dev, jani.nikula, Rob Herring, rodrigo.vivi, bhelgaas,
boris.ostrovsky, Andy Shevchenko, jgross, Nicolas Boichat,
nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, xypron.glpk,
Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-9-tientzu@chromium.org>
> +static inline bool is_dev_swiotlb_force(struct device *dev)
> +{
> +#ifdef CONFIG_DMA_RESTRICTED_POOL
> + if (dev->dma_io_tlb_mem)
> + return true;
> +#endif /* CONFIG_DMA_RESTRICTED_POOL */
> + return false;
> +}
> +
> /* If SWIOTLB is active, use its maximum mapping size */
> if (is_swiotlb_active(dev) &&
> - (dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE))
> + (dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE ||
> + is_dev_swiotlb_force(dev)))
This is a mess. I think the right way is to have an always_bounce flag
in the io_tlb_mem structure instead. Then the global swiotlb_force can
go away and be replace with this and the fact that having no
io_tlb_mem structure at all means forced no buffering (after a little
refactoring).
^ permalink raw reply
* Re: [PATCH v6 05/15] swiotlb: Add a new get_io_tlb_mem getter
From: Christoph Hellwig @ 2021-05-10 15:03 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, Frank Rowand, mingo,
Marek Szyprowski, sstabellini, Saravana Kannan, Joerg Roedel,
Rafael J . Wysocki, Christoph Hellwig, Bartosz Golaszewski,
bskeggs, linux-pci, xen-devel, Thierry Reding, intel-gfx,
matthew.auld, linux-devicetree, jxgao, daniel, Will Deacon,
Konrad Rzeszutek Wilk, maarten.lankhorst, airlied, Dan Williams,
linuxppc-dev, jani.nikula, Rob Herring, rodrigo.vivi, bhelgaas,
boris.ostrovsky, Andy Shevchenko, jgross, Nicolas Boichat,
nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, xypron.glpk,
Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-6-tientzu@chromium.org>
> +static inline struct io_tlb_mem *get_io_tlb_mem(struct device *dev)
> +{
> +#ifdef CONFIG_DMA_RESTRICTED_POOL
> + if (dev && dev->dma_io_tlb_mem)
> + return dev->dma_io_tlb_mem;
> +#endif /* CONFIG_DMA_RESTRICTED_POOL */
> +
> + return io_tlb_default_mem;
Given that we're also looking into a not addressing restricted pool
I'd rather always assign the active pool to dev->dma_io_tlb_mem and
do away with this helper.
^ permalink raw reply
* Re: [PATCH v6 04/15] swiotlb: Add restricted DMA pool initialization
From: Christoph Hellwig @ 2021-05-10 15:02 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, Frank Rowand, mingo,
Marek Szyprowski, sstabellini, Saravana Kannan, Joerg Roedel,
Rafael J . Wysocki, Christoph Hellwig, Bartosz Golaszewski,
bskeggs, linux-pci, xen-devel, Thierry Reding, intel-gfx,
matthew.auld, linux-devicetree, jxgao, daniel, Will Deacon,
Konrad Rzeszutek Wilk, maarten.lankhorst, airlied, Dan Williams,
linuxppc-dev, jani.nikula, Rob Herring, rodrigo.vivi, bhelgaas,
boris.ostrovsky, Andy Shevchenko, jgross, Nicolas Boichat,
nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, xypron.glpk,
Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-5-tientzu@chromium.org>
> +#ifdef CONFIG_DMA_RESTRICTED_POOL
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_reserved_mem.h>
> +#include <linux/slab.h>
> +#endif
I don't think any of this belongs into swiotlb.c. Marking
swiotlb_init_io_tlb_mem non-static and having all this code in a separate
file is probably a better idea.
> +#ifdef CONFIG_DMA_RESTRICTED_POOL
> +static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
> + struct device *dev)
> +{
> + struct io_tlb_mem *mem = rmem->priv;
> + unsigned long nslabs = rmem->size >> IO_TLB_SHIFT;
> +
> + if (dev->dma_io_tlb_mem)
> + return 0;
> +
> + /* Since multiple devices can share the same pool, the private data,
> + * io_tlb_mem struct, will be initialized by the first device attached
> + * to it.
> + */
This is not the normal kernel comment style.
> +#ifdef CONFIG_ARM
> + if (!PageHighMem(pfn_to_page(PHYS_PFN(rmem->base)))) {
> + kfree(mem);
> + return -EINVAL;
> + }
> +#endif /* CONFIG_ARM */
And this is weird. Why would ARM have such a restriction? And if we have
such rstrictions it absolutely belongs into an arch helper.
> + swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false);
> +
> + rmem->priv = mem;
> +
> +#ifdef CONFIG_DEBUG_FS
> + if (!debugfs_dir)
> + debugfs_dir = debugfs_create_dir("swiotlb", NULL);
> +
> + swiotlb_create_debugfs(mem, rmem->name, debugfs_dir);
Doesn't the debugfs_create_dir belong into swiotlb_create_debugfs? Also
please use IS_ENABLEd or a stub to avoid ifdefs like this.
^ permalink raw reply
* Re: [PATCH v6 02/15] swiotlb: Refactor swiotlb_create_debugfs
From: Christoph Hellwig @ 2021-05-10 14:59 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, Frank Rowand, mingo,
Marek Szyprowski, sstabellini, Saravana Kannan, Joerg Roedel,
Rafael J . Wysocki, Christoph Hellwig, Bartosz Golaszewski,
bskeggs, linux-pci, xen-devel, Thierry Reding, intel-gfx,
matthew.auld, linux-devicetree, jxgao, daniel, Will Deacon,
Konrad Rzeszutek Wilk, maarten.lankhorst, airlied, Dan Williams,
linuxppc-dev, jani.nikula, Rob Herring, rodrigo.vivi, bhelgaas,
boris.ostrovsky, Andy Shevchenko, jgross, Nicolas Boichat,
nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, xypron.glpk,
Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-3-tientzu@chromium.org>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* Re: [PATCH v6 01/15] swiotlb: Refactor swiotlb init functions
From: Christoph Hellwig @ 2021-05-10 14:58 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, Frank Rowand, mingo,
Marek Szyprowski, sstabellini, Saravana Kannan, Joerg Roedel,
Rafael J . Wysocki, Christoph Hellwig, Bartosz Golaszewski,
bskeggs, linux-pci, xen-devel, Thierry Reding, intel-gfx,
matthew.auld, linux-devicetree, jxgao, daniel, Will Deacon,
Konrad Rzeszutek Wilk, maarten.lankhorst, airlied, Dan Williams,
linuxppc-dev, jani.nikula, Rob Herring, rodrigo.vivi, bhelgaas,
boris.ostrovsky, Andy Shevchenko, jgross, Nicolas Boichat,
nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, xypron.glpk,
Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-2-tientzu@chromium.org>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply
* [PATCH v1 1/1] powerpc/prom_init: Move custom isspace() to its own namespace
From: Andy Shevchenko @ 2021-05-10 14:49 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev, linux-kernel
Cc: Andy Shevchenko, Paul Mackerras, kernel test robot
If by some reason any of the headers will include ctype.h
we will have a name collision. Avoid this by moving isspace()
to the dedicate namespace.
First appearance of the code is in the commit cf68787b68a2
("powerpc/prom_init: Evaluate mem kernel parameter for early allocation").
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
arch/powerpc/kernel/prom_init.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 41ed7e33d897..6845cbbc0cd4 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -701,13 +701,13 @@ static int __init prom_setprop(phandle node, const char *nodename,
}
/* We can't use the standard versions because of relocation headaches. */
-#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
- || ('a' <= (c) && (c) <= 'f') \
- || ('A' <= (c) && (c) <= 'F'))
+#define prom_isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
-#define isdigit(c) ('0' <= (c) && (c) <= '9')
-#define islower(c) ('a' <= (c) && (c) <= 'z')
-#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
+#define prom_isdigit(c) ('0' <= (c) && (c) <= '9')
+#define prom_islower(c) ('a' <= (c) && (c) <= 'z')
+#define prom_toupper(c) (prom_islower(c) ? ((c) - 'a' + 'A') : (c))
static unsigned long prom_strtoul(const char *cp, const char **endp)
{
@@ -716,14 +716,14 @@ static unsigned long prom_strtoul(const char *cp, const char **endp)
if (*cp == '0') {
base = 8;
cp++;
- if (toupper(*cp) == 'X') {
+ if (prom_toupper(*cp) == 'X') {
cp++;
base = 16;
}
}
- while (isxdigit(*cp) &&
- (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+ while (prom_isxdigit(*cp) &&
+ (value = prom_isdigit(*cp) ? *cp - '0' : prom_toupper(*cp) - 'A' + 10) < base) {
result = result * base + value;
cp++;
}
--
2.30.2
^ permalink raw reply related
* Re: [RFC PATCH 0/7] Memory hotplug/hotremove at subsection size
From: Zi Yan @ 2021-05-10 14:36 UTC (permalink / raw)
To: David Hildenbrand, Michal Hocko
Cc: linux-ia64, Wei Yang, Anshuman Khandual, Rafael J . Wysocki, x86,
Dan Williams, linux-kernel, linux-mm, Andy Lutomirski,
Thomas Gleixner, linuxppc-dev, Andrew Morton, Mike Rapoport,
Oscar Salvador
In-Reply-To: <792d73e2-5d63-74a5-5554-20351d5532ff@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 5339 bytes --]
On 7 May 2021, at 10:00, David Hildenbrand wrote:
> On 07.05.21 13:55, Michal Hocko wrote:
>> [I haven't read through respective patches due to lack of time but let
>> me comment on the general idea and the underlying justification]
>>
>> On Thu 06-05-21 17:31:09, David Hildenbrand wrote:
>>> On 06.05.21 17:26, Zi Yan wrote:
>>>> From: Zi Yan <ziy@nvidia.com>
>>>>
>>>> Hi all,
>>>>
>>>> This patchset tries to remove the restriction on memory hotplug/hotremove
>>>> granularity, which is always greater or equal to memory section size[1].
>>>> With the patchset, kernel is able to online/offline memory at a size independent
>>>> of memory section size, as small as 2MB (the subsection size).
>>>
>>> ... which doesn't make any sense as we can only online/offline whole memory
>>> block devices.
>>
>> Agreed. The subsection thingy is just a hack to workaround pmem
>> alignement problems. For the real memory hotplug it is quite hard to
>> argue for reasonable hotplug scenarios for very small physical memory
>> ranges wrt. to the existing sparsemem memory model.
>>
>>>> The motivation is to increase MAX_ORDER of the buddy allocator and pageblock
>>>> size without increasing memory hotplug/hotremove granularity at the same time,
>>>
>>> Gah, no. Please no. No.
>>
>> Agreed. Those are completely independent concepts. MAX_ORDER is can be
>> really arbitrary irrespective of the section size with vmemmap sparse
>> model. The existing restriction is due to old sparse model not being
>> able to do page pointer arithmetic across memory sections. Is there any
>> reason to stick with that memory model for an advance feature you are
>> working on?
No. I just want to increase MAX_ORDER. If the existing restriction can
be removed, that will be great.
>
> I gave it some more thought yesterday. I guess the first thing we should look into is increasing MAX_ORDER and leaving pageblock_order and section size as is -- finding out what we have to tweak to get that up and running. Once we have that in place, we can actually look into better fragmentation avoidance etc. One step at a time.
It makes sense to me.
>
> Because that change itself might require some thought. Requiring that bigger MAX_ORDER depends on SPARSE_VMEMMAP is something reasonable to do.
OK, if with SPARSE_VMEMMAP MAX_ORDER can be set to be bigger than
SECTION_SIZE, it is perfectly OK to me. Since 1GB THP support, which I
want to add ultimately, will require SPARSE_VMEMMAP too (otherwise,
all page++ will need to be changed to nth_page(page,1)).
>
> As stated somewhere here already, we'll have to look into making alloc_contig_range() (and main users CMA and virtio-mem) independent of MAX_ORDER and mainly rely on pageblock_order. The current handling in alloc_contig_range() is far from optimal as we have to isolate a whole MAX_ORDER - 1 page -- and on ZONE_NORMAL we'll fail easily if any part contains something unmovable although we don't even want to allocate that part. I actually have that on my list (to be able to fully support pageblock_order instead of MAX_ORDER -1 chunks in virtio-mem), however didn't have time to look into it.
So in your mind, for gigantic page allocation (> MAX_ORDER), alloc_contig_range()
should be used instead of buddy allocator while pageblock_order is kept at a small
granularity like 2MB. Is that the case? Isn’t it going to have high fail rate
when any of the pageblocks within a gigantic page range (like 1GB) becomes unmovable?
Are you thinking additional mechanism/policy to prevent such thing happening as
an additional step for gigantic page allocation? Like your ZONE_PREFER_MOVABLE idea?
>
> Further, page onlining / offlining code and early init code most probably also needs care if MAX_ORDER - 1 crosses sections. Memory holes we might suddenly have in MAX_ORDER - 1 pages might become a problem and will have to be handled. Not sure which other code has to be tweaked (compaction? page isolation?).
Can you elaborate it a little more? From what I understand, memory holes mean valid
PFNs are not contiguous before and after a hole, so pfn++ will not work, but
struct pages are still virtually contiguous assuming SPARSE_VMEMMAP, meaning page++
would still work. So when MAX_ORDER - 1 crosses sections, additional code would be
needed instead of simple pfn++. Is there anything I am missing?
BTW, to test a system with memory holes, do you know is there an easy of adding
random memory holes to an x86_64 VM, which can help reveal potential missing pieces
in the code? Changing BIOS-e820 table might be one way, but I have no idea on
how to do it on QEMU.
>
> Figuring out what needs care itself might take quite some effort.
>
> One thing I was thinking about as well: The bigger our MAX_ORDER, the slower it could be to allocate smaller pages. If we have 1G pages, splitting them down to 4k then takes 8 additional steps if I'm, not wrong. Of course, that's the worst case. Would be interesting to evaluate.
Sure. I am planning to check it too. As a simple start, I am going to run will it scale
benchmarks to see if there is any performance difference between different MAX_ORDERs.
Thank you for all these valuable inputs. They are very helpful. I appreciate them.
—
Best Regards,
Yan Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
^ permalink raw reply
* [PATCH 1/1] powerpc/pseries/ras: Delete a redundant condition branch
From: Zhen Lei @ 2021-05-10 13:19 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev
Cc: Zhen Lei
The statement of the last "if (xxx)" branch is the same as the "else"
branch. Delete it to simplify code.
No functional change.
Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
arch/powerpc/platforms/pseries/ras.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 9d4ef65da7f395f..2f636308cf60430 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -593,8 +593,6 @@ static int mce_handle_err_virtmode(struct pt_regs *regs,
mce_err.severity = MCE_SEV_SEVERE;
else if (severity == RTAS_SEVERITY_ERROR)
mce_err.severity = MCE_SEV_SEVERE;
- else if (severity == RTAS_SEVERITY_FATAL)
- mce_err.severity = MCE_SEV_FATAL;
else
mce_err.severity = MCE_SEV_FATAL;
--
2.26.0.106.g9fadedd
^ permalink raw reply related
* Re: [PATCH] ppc64/numa: consider the max numa node for migratable LPAR
From: Laurent Dufour @ 2021-05-10 13:01 UTC (permalink / raw)
To: Srikar Dronamraju; +Cc: nathanl, linux-kernel, paulus, linuxppc-dev
In-Reply-To: <20210510102107.GR2633526@linux.vnet.ibm.com>
Le 10/05/2021 à 12:21, Srikar Dronamraju a écrit :
> * Laurent Dufour <ldufour@linux.ibm.com> [2021-04-29 20:19:01]:
>
>> When a LPAR is migratable, we should consider the maximum possible NUMA
>> node instead the number of NUMA node from the actual system.
>>
>> The DT property 'ibm,current-associativity-domains' is defining the maximum
>> number of nodes the LPAR can see when running on that box. But if the LPAR
>> is being migrated on another box, it may seen up to the nodes defined by
>> 'ibm,max-associativity-domains'. So if a LPAR is migratable, that value
>> should be used.
>>
>> Unfortunately, there is no easy way to know if a LPAR is migratable or
>> not. The hypervisor is exporting the property 'ibm,migratable-partition' in
>> the case it set to migrate partition, but that would not mean that the
>> current partition is migratable.
>>
>> Without that patch, when a LPAR is started on a 2 nodes box and then
>> migrated to a 3 nodes box, the hypervisor may spread the LPAR's CPUs on the
>> 3rd node. In that case if a CPU from that 3rd node is added to the LPAR, it
>> will be wrongly assigned to the node because the kernel has been set to use
>
>
>> up to 2 nodes (the configuration of the departure node). With that patch
>> applies, the CPU is correctly added to the 3rd node.
>
> You probably meant, "With this patch applied"
>
> Also you may want to add a fixes tag:
I'll fix "that" and add the fixes tag.
>> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
>> Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
>> ---
>> arch/powerpc/mm/numa.c | 14 +++++++++++---
>> 1 file changed, 11 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
>> index f2bf98bdcea2..673fa6e47850 100644
>> --- a/arch/powerpc/mm/numa.c
>> +++ b/arch/powerpc/mm/numa.c
>> @@ -893,7 +893,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
>> static void __init find_possible_nodes(void)
>> {
>> struct device_node *rtas;
>> - const __be32 *domains;
>> + const __be32 *domains = NULL;
>> int prop_length, max_nodes;
>> u32 i;
>>
>> @@ -909,9 +909,14 @@ static void __init find_possible_nodes(void)
>> * it doesn't exist, then fallback on ibm,max-associativity-domains.
>> * Current denotes what the platform can support compared to max
>> * which denotes what the Hypervisor can support.
>> + *
>> + * If the LPAR is migratable, new nodes might be activated after a LPM,
>> + * so we should consider the max number in that case.
>> */
>> - domains = of_get_property(rtas, "ibm,current-associativity-domains",
>> - &prop_length);
>> + if (!of_get_property(of_root, "ibm,migratable-partition", NULL))
>> + domains = of_get_property(rtas,
>> + "ibm,current-associativity-domains",
>> + &prop_length);
>> if (!domains) {
>> domains = of_get_property(rtas, "ibm,max-associativity-domains",
>> &prop_length);
>> @@ -920,6 +925,9 @@ static void __init find_possible_nodes(void)
>> }
>>
>> max_nodes = of_read_number(&domains[min_common_depth], 1);
>> + printk(KERN_INFO "Partition configured for %d NUMA nodes.\n",
>> + max_nodes);
>> +
>
> Another nit:
> you may want to make this pr_info instead of printk
Sure !
>> for (i = 0; i < max_nodes; i++) {
>> if (!node_possible(i))
>> node_set(i, node_possible_map);
>> --
>> 2.31.1
>>
>
> Otherwise looks good to me.
>
> Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Thanks Srikar, I'll add you review tag in the v2.
^ permalink raw reply
* Re: [PATCH 01/11] PCI: Use sysfs_emit() and sysfs_emit_at() in "show" functions
From: Krzysztof Wilczyński @ 2021-05-10 10:30 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Tyrel Datwyler, linux-pci, linuxppc-dev, Oliver O'Halloran,
Joe Perches, Paul Mackerras, Kurt Schwemmer, Logan Gunthorpe
In-Reply-To: <20210510041424.233565-1-kw@linux.com>
[+cc Joe for visibility]
[...]
> spin_lock(&resource_alignment_lock);
> if (resource_alignment_param)
> - count = scnprintf(buf, PAGE_SIZE, "%s", resource_alignment_param);
> + count = sysfs_emit(buf, "%s", resource_alignment_param);
> spin_unlock(&resource_alignment_lock);
Following the work that Joe did recently, see:
https://lore.kernel.org/lkml/aa1819fa5faf786573df298e5e2e7d357ba7d4ad.camel@perches.com/
I think we ought to also add the missing newline to our sysfs_emit() and
sysfs_emit_at() users, like the one above and the following:
drivers/pci/pci-sysfs.c
540: return sysfs_emit(buf, "%pOF", np);
To keep things correct and consistent.
Bjorn, I can follow-up with a small patch after this one, or send a v2,
or, if that would be OK with you, then you could fix it during merging,
provided you decide to merge things as-is.
Krzysztof
^ permalink raw reply
* Re: [PATCH] ppc64/numa: consider the max numa node for migratable LPAR
From: Srikar Dronamraju @ 2021-05-10 10:21 UTC (permalink / raw)
To: Laurent Dufour; +Cc: nathanl, linux-kernel, paulus, linuxppc-dev
In-Reply-To: <20210429181901.17674-1-ldufour@linux.ibm.com>
* Laurent Dufour <ldufour@linux.ibm.com> [2021-04-29 20:19:01]:
> When a LPAR is migratable, we should consider the maximum possible NUMA
> node instead the number of NUMA node from the actual system.
>
> The DT property 'ibm,current-associativity-domains' is defining the maximum
> number of nodes the LPAR can see when running on that box. But if the LPAR
> is being migrated on another box, it may seen up to the nodes defined by
> 'ibm,max-associativity-domains'. So if a LPAR is migratable, that value
> should be used.
>
> Unfortunately, there is no easy way to know if a LPAR is migratable or
> not. The hypervisor is exporting the property 'ibm,migratable-partition' in
> the case it set to migrate partition, but that would not mean that the
> current partition is migratable.
>
> Without that patch, when a LPAR is started on a 2 nodes box and then
> migrated to a 3 nodes box, the hypervisor may spread the LPAR's CPUs on the
> 3rd node. In that case if a CPU from that 3rd node is added to the LPAR, it
> will be wrongly assigned to the node because the kernel has been set to use
> up to 2 nodes (the configuration of the departure node). With that patch
> applies, the CPU is correctly added to the 3rd node.
You probably meant, "With this patch applied"
Also you may want to add a fixes tag:
> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
> ---
> arch/powerpc/mm/numa.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
> index f2bf98bdcea2..673fa6e47850 100644
> --- a/arch/powerpc/mm/numa.c
> +++ b/arch/powerpc/mm/numa.c
> @@ -893,7 +893,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
> static void __init find_possible_nodes(void)
> {
> struct device_node *rtas;
> - const __be32 *domains;
> + const __be32 *domains = NULL;
> int prop_length, max_nodes;
> u32 i;
>
> @@ -909,9 +909,14 @@ static void __init find_possible_nodes(void)
> * it doesn't exist, then fallback on ibm,max-associativity-domains.
> * Current denotes what the platform can support compared to max
> * which denotes what the Hypervisor can support.
> + *
> + * If the LPAR is migratable, new nodes might be activated after a LPM,
> + * so we should consider the max number in that case.
> */
> - domains = of_get_property(rtas, "ibm,current-associativity-domains",
> - &prop_length);
> + if (!of_get_property(of_root, "ibm,migratable-partition", NULL))
> + domains = of_get_property(rtas,
> + "ibm,current-associativity-domains",
> + &prop_length);
> if (!domains) {
> domains = of_get_property(rtas, "ibm,max-associativity-domains",
> &prop_length);
> @@ -920,6 +925,9 @@ static void __init find_possible_nodes(void)
> }
>
> max_nodes = of_read_number(&domains[min_common_depth], 1);
> + printk(KERN_INFO "Partition configured for %d NUMA nodes.\n",
> + max_nodes);
> +
Another nit:
you may want to make this pr_info instead of printk
> for (i = 0; i < max_nodes; i++) {
> if (!node_possible(i))
> node_set(i, node_possible_map);
> --
> 2.31.1
>
Otherwise looks good to me.
Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* Re: [PATCH v5 00/16] Restricted DMA
From: Claire Chang @ 2021-05-10 9:53 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Frank Rowand, Konrad Rzeszutek Wilk,
boris.ostrovsky, jgross, Christoph Hellwig, Marek Szyprowski
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, mingo, Jianxiong Gao,
sstabellini, Saravana Kannan, xypron.glpk, Rafael J . Wysocki,
Bartosz Golaszewski, bskeggs, linux-pci, xen-devel,
Thierry Reding, intel-gfx, matthew.auld, linux-devicetree,
Daniel Vetter, airlied, maarten.lankhorst, linuxppc-dev,
jani.nikula, Nicolas Boichat, rodrigo.vivi, Bjorn Helgaas,
Dan Williams, Andy Shevchenko, nouveau, Greg KH, Randy Dunlap,
lkml, Tomasz Figa, list@263.net:IOMMU DRIVERS, Jim Quinlan,
Robin Murphy, bauerman
In-Reply-To: <20210422081508.3942748-1-tientzu@chromium.org>
v6: https://lore.kernel.org/patchwork/cover/1423201/
^ permalink raw reply
* [PATCH v6 15/15] of: Add plumbing for restricted DMA pool
From: Claire Chang @ 2021-05-10 9:50 UTC (permalink / raw)
To: Rob Herring, mpe, Joerg Roedel, Will Deacon, Frank Rowand,
Konrad Rzeszutek Wilk, boris.ostrovsky, jgross, Christoph Hellwig,
Marek Szyprowski
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, mingo, jxgao, sstabellini,
Saravana Kannan, xypron.glpk, Rafael J . Wysocki,
Bartosz Golaszewski, bskeggs, linux-pci, xen-devel,
Thierry Reding, intel-gfx, matthew.auld, linux-devicetree, daniel,
airlied, maarten.lankhorst, linuxppc-dev, jani.nikula,
Nicolas Boichat, rodrigo.vivi, bhelgaas, tientzu, Dan Williams,
Andy Shevchenko, nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-1-tientzu@chromium.org>
If a device is not behind an IOMMU, we look up the device node and set
up the restricted DMA when the restricted-dma-pool is presented.
Signed-off-by: Claire Chang <tientzu@chromium.org>
---
drivers/of/address.c | 25 +++++++++++++++++++++++++
drivers/of/device.c | 3 +++
drivers/of/of_private.h | 5 +++++
3 files changed, 33 insertions(+)
diff --git a/drivers/of/address.c b/drivers/of/address.c
index aca94c348bd4..c562a9ff5f0b 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -8,6 +8,7 @@
#include <linux/logic_pio.h>
#include <linux/module.h>
#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/sizes.h>
@@ -1112,6 +1113,30 @@ bool of_dma_is_coherent(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_dma_is_coherent);
+int of_dma_set_restricted_buffer(struct device *dev)
+{
+ struct device_node *node;
+ int count, i;
+
+ if (!dev->of_node)
+ return 0;
+
+ count = of_property_count_elems_of_size(dev->of_node, "memory-region",
+ sizeof(phandle));
+ for (i = 0; i < count; i++) {
+ node = of_parse_phandle(dev->of_node, "memory-region", i);
+ /* There might be multiple memory regions, but only one
+ * restriced-dma-pool region is allowed.
+ */
+ if (of_device_is_compatible(node, "restricted-dma-pool") &&
+ of_device_is_available(node))
+ return of_reserved_mem_device_init_by_idx(
+ dev, dev->of_node, i);
+ }
+
+ return 0;
+}
+
/**
* of_mmio_is_nonposted - Check if device uses non-posted MMIO
* @np: device node
diff --git a/drivers/of/device.c b/drivers/of/device.c
index c5a9473a5fb1..d8d865223e51 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -165,6 +165,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
+ if (!iommu)
+ return of_dma_set_restricted_buffer(dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(of_dma_configure_id);
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index d717efbd637d..e9237f5eff48 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -163,12 +163,17 @@ struct bus_dma_region;
#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA)
int of_dma_get_range(struct device_node *np,
const struct bus_dma_region **map);
+int of_dma_set_restricted_buffer(struct device *dev);
#else
static inline int of_dma_get_range(struct device_node *np,
const struct bus_dma_region **map)
{
return -ENODEV;
}
+static inline int of_dma_get_restricted_buffer(struct device *dev)
+{
+ return -ENODEV;
+}
#endif
#endif /* _LINUX_OF_PRIVATE_H */
--
2.31.1.607.g51e8a6a459-goog
^ permalink raw reply related
* [PATCH v6 14/15] dt-bindings: of: Add restricted DMA pool
From: Claire Chang @ 2021-05-10 9:50 UTC (permalink / raw)
To: Rob Herring, mpe, Joerg Roedel, Will Deacon, Frank Rowand,
Konrad Rzeszutek Wilk, boris.ostrovsky, jgross, Christoph Hellwig,
Marek Szyprowski
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, mingo, jxgao, sstabellini,
Saravana Kannan, xypron.glpk, Rafael J . Wysocki,
Bartosz Golaszewski, bskeggs, linux-pci, xen-devel,
Thierry Reding, intel-gfx, matthew.auld, linux-devicetree, daniel,
airlied, maarten.lankhorst, linuxppc-dev, jani.nikula,
Nicolas Boichat, rodrigo.vivi, bhelgaas, tientzu, Dan Williams,
Andy Shevchenko, nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-1-tientzu@chromium.org>
Introduce the new compatible string, restricted-dma-pool, for restricted
DMA. One can specify the address and length of the restricted DMA memory
region by restricted-dma-pool in the reserved-memory node.
Signed-off-by: Claire Chang <tientzu@chromium.org>
---
.../reserved-memory/reserved-memory.txt | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
index e8d3096d922c..284aea659015 100644
--- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -51,6 +51,23 @@ compatible (optional) - standard definition
used as a shared pool of DMA buffers for a set of devices. It can
be used by an operating system to instantiate the necessary pool
management subsystem if necessary.
+ - restricted-dma-pool: This indicates a region of memory meant to be
+ used as a pool of restricted DMA buffers for a set of devices. The
+ memory region would be the only region accessible to those devices.
+ When using this, the no-map and reusable properties must not be set,
+ so the operating system can create a virtual mapping that will be used
+ for synchronization. The main purpose for restricted DMA is to
+ mitigate the lack of DMA access control on systems without an IOMMU,
+ which could result in the DMA accessing the system memory at
+ unexpected times and/or unexpected addresses, possibly leading to data
+ leakage or corruption. The feature on its own provides a basic level
+ of protection against the DMA overwriting buffer contents at
+ unexpected times. However, to protect against general data leakage and
+ system memory corruption, the system needs to provide way to lock down
+ the memory access, e.g., MPU. Note that since coherent allocation
+ needs remapping, one must set up another device coherent pool by
+ shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic
+ coherent allocation.
- vendor specific string in the form <vendor>,[<device>-]<usage>
no-map (optional) - empty property
- Indicates the operating system must not create a virtual mapping
@@ -120,6 +137,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
compatible = "acme,multimedia-memory";
reg = <0x77000000 0x4000000>;
};
+
+ restricted_dma_mem_reserved: restricted_dma_mem_reserved {
+ compatible = "restricted-dma-pool";
+ reg = <0x50000000 0x400000>;
+ };
};
/* ... */
@@ -138,4 +160,9 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
memory-region = <&multimedia_reserved>;
/* ... */
};
+
+ pcie_device: pcie_device@0,0 {
+ memory-region = <&restricted_dma_mem_reserved>;
+ /* ... */
+ };
};
--
2.31.1.607.g51e8a6a459-goog
^ permalink raw reply related
* [PATCH v6 13/15] dma-direct: Allocate memory from restricted DMA pool if available
From: Claire Chang @ 2021-05-10 9:50 UTC (permalink / raw)
To: Rob Herring, mpe, Joerg Roedel, Will Deacon, Frank Rowand,
Konrad Rzeszutek Wilk, boris.ostrovsky, jgross, Christoph Hellwig,
Marek Szyprowski
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, mingo, jxgao, sstabellini,
Saravana Kannan, xypron.glpk, Rafael J . Wysocki,
Bartosz Golaszewski, bskeggs, linux-pci, xen-devel,
Thierry Reding, intel-gfx, matthew.auld, linux-devicetree, daniel,
airlied, maarten.lankhorst, linuxppc-dev, jani.nikula,
Nicolas Boichat, rodrigo.vivi, bhelgaas, tientzu, Dan Williams,
Andy Shevchenko, nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-1-tientzu@chromium.org>
The restricted DMA pool is preferred if available.
The restricted DMA pools provide a basic level of protection against the
DMA overwriting buffer contents at unexpected times. However, to protect
against general data leakage and system memory corruption, the system
needs to provide a way to lock down the memory access, e.g., MPU.
Note that since coherent allocation needs remapping, one must set up
another device coherent pool by shared-dma-pool and use
dma_alloc_from_dev_coherent instead for atomic coherent allocation.
Signed-off-by: Claire Chang <tientzu@chromium.org>
---
kernel/dma/direct.c | 38 +++++++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index eb4098323bbc..0d521f78c7b9 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -78,6 +78,10 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
static void __dma_direct_free_pages(struct device *dev, struct page *page,
size_t size)
{
+#ifdef CONFIG_DMA_RESTRICTED_POOL
+ if (swiotlb_free(dev, page, size))
+ return;
+#endif
dma_free_contiguous(dev, page, size);
}
@@ -92,7 +96,17 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
&phys_limit);
- page = dma_alloc_contiguous(dev, size, gfp);
+
+#ifdef CONFIG_DMA_RESTRICTED_POOL
+ page = swiotlb_alloc(dev, size);
+ if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+ __dma_direct_free_pages(dev, page, size);
+ page = NULL;
+ }
+#endif
+
+ if (!page)
+ page = dma_alloc_contiguous(dev, size, gfp);
if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
dma_free_contiguous(dev, page, size);
page = NULL;
@@ -148,7 +162,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
gfp |= __GFP_NOWARN;
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
- !force_dma_unencrypted(dev)) {
+ !force_dma_unencrypted(dev) && !is_dev_swiotlb_force(dev)) {
page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
if (!page)
return NULL;
@@ -161,18 +175,23 @@ void *dma_direct_alloc(struct device *dev, size_t size,
}
if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
- !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
- !dev_is_dma_coherent(dev))
+ !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) &&
+ !is_dev_swiotlb_force(dev))
return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
/*
* Remapping or decrypting memory may block. If either is required and
* we can't block, allocate the memory from the atomic pools.
+ * If restricted DMA (i.e., is_dev_swiotlb_force) is required, one must
+ * set up another device coherent pool by shared-dma-pool and use
+ * dma_alloc_from_dev_coherent instead.
*/
if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
!gfpflags_allow_blocking(gfp) &&
(force_dma_unencrypted(dev) ||
- (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev))))
+ (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
+ !dev_is_dma_coherent(dev))) &&
+ !is_dev_swiotlb_force(dev))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
/* we always manually zero the memory once we are done */
@@ -253,15 +272,15 @@ void dma_direct_free(struct device *dev, size_t size,
unsigned int page_order = get_order(size);
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
- !force_dma_unencrypted(dev)) {
+ !force_dma_unencrypted(dev) && !is_dev_swiotlb_force(dev)) {
/* cpu_addr is a struct page cookie, not a kernel address */
dma_free_contiguous(dev, cpu_addr, size);
return;
}
if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
- !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
- !dev_is_dma_coherent(dev)) {
+ !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) &&
+ !is_dev_swiotlb_force(dev)) {
arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
return;
}
@@ -289,7 +308,8 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
void *ret;
if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
- force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp))
+ force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp) &&
+ !is_dev_swiotlb_force(dev))
return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
page = __dma_direct_alloc_pages(dev, size, gfp);
--
2.31.1.607.g51e8a6a459-goog
^ permalink raw reply related
* [PATCH v6 12/15] swiotlb: Add restricted DMA alloc/free support.
From: Claire Chang @ 2021-05-10 9:50 UTC (permalink / raw)
To: Rob Herring, mpe, Joerg Roedel, Will Deacon, Frank Rowand,
Konrad Rzeszutek Wilk, boris.ostrovsky, jgross, Christoph Hellwig,
Marek Szyprowski
Cc: heikki.krogerus, thomas.hellstrom, peterz, joonas.lahtinen,
dri-devel, chris, grant.likely, paulus, mingo, jxgao, sstabellini,
Saravana Kannan, xypron.glpk, Rafael J . Wysocki,
Bartosz Golaszewski, bskeggs, linux-pci, xen-devel,
Thierry Reding, intel-gfx, matthew.auld, linux-devicetree, daniel,
airlied, maarten.lankhorst, linuxppc-dev, jani.nikula,
Nicolas Boichat, rodrigo.vivi, bhelgaas, tientzu, Dan Williams,
Andy Shevchenko, nouveau, Greg KH, Randy Dunlap, lkml, tfiga,
list@263.net:IOMMU DRIVERS, Jim Quinlan, Robin Murphy, bauerman
In-Reply-To: <20210510095026.3477496-1-tientzu@chromium.org>
Add the functions, swiotlb_{alloc,free} to support the memory allocation
from restricted DMA pool.
Signed-off-by: Claire Chang <tientzu@chromium.org>
---
include/linux/swiotlb.h | 4 ++++
kernel/dma/swiotlb.c | 35 +++++++++++++++++++++++++++++++++--
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 0c5a18d9cf89..e8cf49bd90c5 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -134,6 +134,10 @@ unsigned int swiotlb_max_segment(void);
size_t swiotlb_max_mapping_size(struct device *dev);
bool is_swiotlb_active(struct device *dev);
void __init swiotlb_adjust_size(unsigned long size);
+#ifdef CONFIG_DMA_RESTRICTED_POOL
+struct page *swiotlb_alloc(struct device *dev, size_t size);
+bool swiotlb_free(struct device *dev, struct page *page, size_t size);
+#endif /* CONFIG_DMA_RESTRICTED_POOL */
#else
#define swiotlb_force SWIOTLB_NO_FORCE
static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index fa11787e4b95..d99d5f902259 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -457,8 +457,9 @@ static int find_slots(struct device *dev, phys_addr_t orig_addr,
index = wrap = wrap_index(mem, ALIGN(mem->index, stride));
do {
- if ((slot_addr(tbl_dma_addr, index) & iotlb_align_mask) !=
- (orig_addr & iotlb_align_mask)) {
+ if (orig_addr &&
+ (slot_addr(tbl_dma_addr, index) & iotlb_align_mask) !=
+ (orig_addr & iotlb_align_mask)) {
index = wrap_index(mem, index + 1);
continue;
}
@@ -701,6 +702,36 @@ late_initcall(swiotlb_create_default_debugfs);
#endif
#ifdef CONFIG_DMA_RESTRICTED_POOL
+struct page *swiotlb_alloc(struct device *dev, size_t size)
+{
+ struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
+ phys_addr_t tlb_addr;
+ int index;
+
+ if (!mem)
+ return NULL;
+
+ index = find_slots(dev, 0, size);
+ if (index == -1)
+ return NULL;
+
+ tlb_addr = slot_addr(mem->start, index);
+
+ return pfn_to_page(PFN_DOWN(tlb_addr));
+}
+
+bool swiotlb_free(struct device *dev, struct page *page, size_t size)
+{
+ phys_addr_t tlb_addr = page_to_phys(page);
+
+ if (!is_swiotlb_buffer(dev, tlb_addr))
+ return false;
+
+ release_slots(dev, tlb_addr);
+
+ return true;
+}
+
static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
struct device *dev)
{
--
2.31.1.607.g51e8a6a459-goog
^ 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