* [PATCH 07/19] powerpc/powermac: Make some functions static
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
These functions can all be static, make it so. Fix warnings treated as
errors with W=1:
arch/powerpc/platforms/powermac/pci.c:1022:6: error: no previous prototype for ‘pmac_pci_fixup_ohci’ [-Werror=missing-prototypes]
arch/powerpc/platforms/powermac/pci.c:1057:6: error: no previous prototype for ‘pmac_pci_fixup_cardbus’ [-Werror=missing-prototypes]
arch/powerpc/platforms/powermac/pci.c:1094:6: error: no previous prototype for ‘pmac_pci_fixup_pciata’ [-Werror=missing-prototypes]
Also add gcc attribute unused to fix a warning treated as error with W=1:
arch/powerpc/platforms/powermac/pci.c:784:19: error: variable ‘has_address’ set but not used [-Werror=unused-but-set-variable]
arch/powerpc/platforms/powermac/pci.c:907:22: error: variable ‘ht’ set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/platforms/powermac/pci.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 0b8174a79993..d3b9818dd880 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -781,7 +781,7 @@ static int __init pmac_add_bridge(struct device_node *dev)
struct resource rsrc;
char *disp_name;
const int *bus_range;
- int primary = 1, has_address = 0;
+ int primary = 1, has_address __maybe_unused = 0;
DBG("Adding PCI host bridge %pOF\n", dev);
@@ -904,7 +904,7 @@ static int pmac_pci_root_bridge_prepare(struct pci_host_bridge *bridge)
void __init pmac_pci_init(void)
{
struct device_node *np, *root;
- struct device_node *ht = NULL;
+ struct device_node *ht __maybe_unused = NULL;
pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
@@ -1019,7 +1019,7 @@ static bool pmac_pci_enable_device_hook(struct pci_dev *dev)
return true;
}
-void pmac_pci_fixup_ohci(struct pci_dev *dev)
+static void pmac_pci_fixup_ohci(struct pci_dev *dev)
{
struct device_node *node = pci_device_to_OF_node(dev);
@@ -1054,7 +1054,7 @@ void __init pmac_pcibios_after_init(void)
}
}
-void pmac_pci_fixup_cardbus(struct pci_dev* dev)
+static void pmac_pci_fixup_cardbus(struct pci_dev *dev)
{
if (!machine_is(powermac))
return;
@@ -1091,7 +1091,7 @@ void pmac_pci_fixup_cardbus(struct pci_dev* dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
-void pmac_pci_fixup_pciata(struct pci_dev* dev)
+static void pmac_pci_fixup_pciata(struct pci_dev *dev)
{
u8 progif = 0;
--
2.11.0
^ permalink raw reply related
* [PATCH 06/19] powerpc: Make function btext_initialize static
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
This function can be static, make it so, this fix a warning treated as
error with W=1:
arch/powerpc/kernel/btext.c:173:5: error: no previous prototype for ‘btext_initialize’ [-Werror=missing-prototypes]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/kernel/btext.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index 6537cba1a758..38ae3ffe44f6 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -170,7 +170,7 @@ void btext_map(void)
boot_text_mapped = 1;
}
-int btext_initialize(struct device_node *np)
+static int btext_initialize(struct device_node *np)
{
unsigned int width, height, depth, pitch;
unsigned long address = 0;
--
2.11.0
^ permalink raw reply related
* [PATCH 05/19] powerpc/chrp/setup: Add attribute unused and make some functions static
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
Add gcc attribute unused to silence a warning.
These functions can all be static, make it so. Fix warnings treated as
errors with W=1:
arch/powerpc/platforms/chrp/setup.c:97:6: error: no previous prototype for ‘chrp_show_cpuinfo’ [-Werror=missing-prototypes]
arch/powerpc/platforms/chrp/setup.c:302:13: error: no previous prototype for ‘chrp_setup_arch’ [-Werror=missing-prototypes]
arch/powerpc/platforms/chrp/setup.c:385:16: error: variable ‘idu_size’ set but not used [-Werror=unused-but-set-variable]
arch/powerpc/platforms/chrp/setup.c:526:13: error: no previous prototype for ‘chrp_init_IRQ’ [-Werror=missing-prototypes]
arch/powerpc/platforms/chrp/setup.c:559:1: error: no previous prototype for ‘chrp_init2’ [-Werror=missing-prototypes]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/platforms/chrp/setup.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 481ed133e04b..85df479fd631 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -94,7 +94,7 @@ static const char *chrp_names[] = {
"Total Impact Briq"
};
-void chrp_show_cpuinfo(struct seq_file *m)
+static void chrp_show_cpuinfo(struct seq_file *m)
{
int i, sdramen;
unsigned int t;
@@ -299,7 +299,7 @@ static __init void chrp_init(void)
of_node_put(node);
}
-void __init chrp_setup_arch(void)
+static void __init chrp_setup_arch(void)
{
struct device_node *root = of_find_node_by_path("/");
const char *machine = NULL;
@@ -382,7 +382,7 @@ static void __init chrp_find_openpic(void)
{
struct device_node *np, *root;
int len, i, j;
- int isu_size, idu_size;
+ int isu_size, idu_size __maybe_unused;
const unsigned int *iranges, *opprop = NULL;
int oplen = 0;
unsigned long opaddr;
@@ -523,7 +523,7 @@ static void __init chrp_find_8259(void)
}
}
-void __init chrp_init_IRQ(void)
+static void __init chrp_init_IRQ(void)
{
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON)
struct device_node *kbd;
@@ -555,7 +555,7 @@ void __init chrp_init_IRQ(void)
#endif
}
-void __init
+static void __init
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
--
2.11.0
^ permalink raw reply related
* [PATCH 04/19] powerpc/kvm: Mark variable tmp unused
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
Add gcc attribute unused to variable tmp. Fix warning treated as error with
W=1:
arch/powerpc/kernel/kvm.c:675:6: error: variable ‘tmp’ set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/kernel/kvm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
index 9ad37f827a97..cd3c088283f9 100644
--- a/arch/powerpc/kernel/kvm.c
+++ b/arch/powerpc/kernel/kvm.c
@@ -672,7 +672,7 @@ static void kvm_use_magic_page(void)
{
u32 *p;
u32 *start, *end;
- u32 tmp;
+ u32 tmp __maybe_unused;
u32 features;
/* Tell the host to map the magic page to -4096 on all CPUs */
--
2.11.0
^ permalink raw reply related
* [PATCH 03/19] powerpc: Mark variables as unused
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
Add gcc attribute unused for two variables. Fix warnings treated as errors
with W=1:
arch/powerpc/kernel/prom_init.c:1388:8: error: variable ‘path’ set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/kernel/prom_init.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index acf4b2e0530c..6a3ac4522144 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -603,7 +603,7 @@ static void __init early_cmdline_parse(void)
const char *opt;
char *p;
- int l = 0;
+ int l __maybe_unused = 0;
prom_cmd_line[0] = 0;
p = prom_cmd_line;
@@ -1385,7 +1385,7 @@ static void __init reserve_mem(u64 base, u64 size)
static void __init prom_init_mem(void)
{
phandle node;
- char *path, type[64];
+ char *path __maybe_unused, type[64];
unsigned int plen;
cell_t *p, *endp;
__be32 val;
--
2.11.0
^ permalink raw reply related
* [PATCH 02/19] powerpc/powermac: Mark variable x as unused
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
Since the value of x is never intended to be read, declare it with gcc
attribute as unused. Fix warning treated as error with W=1:
arch/powerpc/platforms/powermac/udbg_scc.c:76:9: error: variable ‘x’ set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/platforms/powermac/udbg_scc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index d83135a9830e..c38ca406df1a 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -73,7 +73,7 @@ void udbg_scc_init(int force_scc)
struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
const char *path;
- int i, x;
+ int i, x __maybe_unused;
escc = of_find_node_by_name(NULL, "escc");
if (escc == NULL)
--
2.11.0
^ permalink raw reply related
* [PATCH 01/19] powerpc/powermac: Mark variable x as unused
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
In-Reply-To: <20180322202007.23088-1-malat@debian.org>
Since the value of x is never intended to be read, declare it with gcc
attribute as unused. Fix warning treated as error with W=1:
arch/powerpc/platforms/powermac/bootx_init.c:471:21: error: variable ‘x’ set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Mathieu Malaterre <malat@debian.org>
---
arch/powerpc/platforms/powermac/bootx_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index c3c9bbb3573a..d3ce55dae78f 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -468,7 +468,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
boot_infos_t *bi = (boot_infos_t *) r4;
unsigned long hdr;
unsigned long space;
- unsigned long ptr, x;
+ unsigned long ptr, x __maybe_unused;
char *model;
unsigned long offset = reloc_offset();
--
2.11.0
^ permalink raw reply related
* [PATCH 00/19] powerpc/ppc32: make W=1 compilation errors free
From: Mathieu Malaterre @ 2018-03-22 20:19 UTC (permalink / raw)
To: Michael Ellerman
Cc: Mathieu Malaterre, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev, linux-kernel, kvm-ppc
Here is another batch for warnings treated as error on ppc32. Tested with:
$ make ARCH=powerpc ppc32_defconfig
$ make -j8 ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- W=1
Using:
$ powerpc-linux-gnu-gcc --version
powerpc-linux-gnu-gcc (Debian 6.3.0-18) 6.3.0 20170516
Mathieu Malaterre (19):
powerpc/powermac: Mark variable x as unused
powerpc/powermac: Mark variable x as unused
powerpc: Mark variables as unused
powerpc/kvm: Mark variable tmp unused
powerpc/chrp/setup: Add attribute unused and make some functions
static
powerpc: Make function btext_initialize static
powerpc/powermac: Make some functions static
powerpc/tau: Make some function static
powerpc/chrp/pci: Make some functions static
powerpc/chrp/time: Make some functions static, add missing header
include
powerpc/powermac: Move pmac_pfunc_base_install prototype to header
file
powerpc/powermac: Add missing prototype for note_bootable_part()
powerpc/52xx: Add missing functions prototypes
powerpc/altivec: Add missing prototypes for altivec
powerpc: Add missing prototype
powerpc/powermac: Add missing include of header pmac.h
powerpc/32: Add a missing include header
powerpc: Add a missing include header
powerpc/tau: Synchronize function prototypes and body
arch/powerpc/include/asm/mpc52xx.h | 6 +++---
arch/powerpc/include/asm/pmac_pfunc.h | 1 +
arch/powerpc/include/asm/rheap.h | 3 +++
arch/powerpc/kernel/btext.c | 2 +-
arch/powerpc/kernel/irq.c | 2 +-
arch/powerpc/kernel/kvm.c | 2 +-
arch/powerpc/kernel/pci_32.c | 1 +
arch/powerpc/kernel/prom_init.c | 4 ++--
arch/powerpc/kernel/setup-common.c | 6 ------
arch/powerpc/kernel/setup.h | 6 ++++++
arch/powerpc/kernel/tau_6xx.c | 15 +++++++++------
arch/powerpc/kernel/vecemu.c | 1 +
arch/powerpc/lib/xor_vmx.h | 14 ++++++++++++++
arch/powerpc/platforms/chrp/pci.c | 8 ++++----
arch/powerpc/platforms/chrp/setup.c | 10 +++++-----
arch/powerpc/platforms/chrp/time.c | 6 ++++--
arch/powerpc/platforms/powermac/bootx_init.c | 2 +-
arch/powerpc/platforms/powermac/pci.c | 10 +++++-----
arch/powerpc/platforms/powermac/setup.c | 1 +
arch/powerpc/platforms/powermac/smp.c | 1 -
arch/powerpc/platforms/powermac/time.c | 4 +++-
arch/powerpc/platforms/powermac/udbg_scc.c | 2 +-
22 files changed, 67 insertions(+), 40 deletions(-)
--
2.11.0
^ permalink raw reply
* Re: RFC on writel and writel_relaxed
From: Sinan Kaya @ 2018-03-22 17:51 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Oliver
Cc: open list:LINUX FOR POWERPC (32-BIT AND 64-BIT),
linux-rdma@vger.kernel.org
In-Reply-To: <1521726722.16434.312.camel@kernel.crashing.org>
On 3/22/2018 8:52 AM, Benjamin Herrenschmidt wrote:
>>> No, it's not sufficient.
> Just to clarify ... barrier() is just a compiler barrier, it means the
> compiler will generate things in the order they are written. This isn't
> sufficient on archs with an OO memory model, where an actual memory
> barrier instruction needs to be emited.
Surprisingly, ARM64 GCC compiler generates a write barrier as
opposed to preventing code reordering.
I was curious if this is an ARM only thing or not.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH v2 21/38] cxlflash: Setup function OCXL link
From: Frederic Barrat @ 2018-03-22 17:31 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683777-17510-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:22, Uma Krishnan a écrit :
> After reading and modifying the function configuration, setup the OCXL
> link using the OCXL provider services. The link is released when the
> adapter is unconfigured.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 25 ++++++++++++++++++++++---
> drivers/scsi/cxlflash/ocxl_hw.h | 1 +
> 2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index a1d58fc..ea2906d 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -412,11 +412,28 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> ocxl_config_set_actag(pdev, fcfg->dvsec_function_pos, base, enabled);
> dev_dbg(dev, "%s: Function acTag range base=%u enabled=%u\n",
> __func__, base, enabled);
> +
> + rc = ocxl_link_setup(pdev, 0, &afu->link_token);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxl_link_setup failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> out:
> return rc;
> }
>
> /**
> + * ocxlflash_unconfig_fn() - unconfigure the host function
> + * @pdev: PCI device associated with the host.
> + * @afu: AFU associated with the host.
> + */
> +static void ocxlflash_unconfig_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> +{
> + ocxl_link_release(pdev, afu->link_token);
> +}
> +
> +/**
> * ocxlflash_map_mmio() - map the AFU MMIO space
> * @afu: AFU associated with the host.
> *
> @@ -552,7 +569,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> if (unlikely(rc)) {
> dev_err(dev, "%s: AFU configuration failed rc=%d\n",
> __func__, rc);
> - goto err1;
> + goto err2;
> }
>
> ctx = ocxlflash_dev_context_init(pdev, afu);
> @@ -560,15 +577,17 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> rc = PTR_ERR(ctx);
> dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n",
> __func__, rc);
> - goto err2;
> + goto err3;
> }
>
> idr_init(&afu->idr);
> afu->ocxl_ctx = ctx;
> out:
> return afu;
> -err2:
> +err3:
> ocxlflash_unconfig_afu(afu);
> +err2:
> + ocxlflash_unconfig_fn(pdev, afu);
> err1:
> kfree(afu);
> afu = NULL;
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 18f402a..4d43650 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -31,6 +31,7 @@ struct ocxl_hw_afu {
> phys_addr_t gmmio_phys; /* Global AFU MMIO space */
> void __iomem *gmmio_virt; /* Global MMIO map */
>
> + void *link_token; /* Link token for the SPA */
> struct idr idr; /* IDR to manage contexts */
> int max_pasid; /* Maximum number of contexts */
> };
>
^ permalink raw reply
* Re: [PATCH v2 19/38] cxlflash: Support AFU state toggling
From: Frederic Barrat @ 2018-03-22 17:26 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683763-17438-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:22, Uma Krishnan a écrit :
> The AFU should be enabled following a successful configuration and
> disabled near the end of the cleanup path.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 67f0252..364e7a5 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -342,12 +342,18 @@ static void ocxlflash_unconfig_afu(struct ocxl_hw_afu *afu)
> static void ocxlflash_destroy_afu(void *afu_cookie)
> {
> struct ocxl_hw_afu *afu = afu_cookie;
> + int pos;
>
> if (!afu)
> return;
>
> ocxlflash_release_context(afu->ocxl_ctx);
> idr_destroy(&afu->idr);
> +
> + /* Disable the AFU */
> + pos = afu->acfg.dvsec_afu_control_pos;
> + ocxl_config_set_afu_state(afu->pdev, pos, 0);
> +
> ocxlflash_unconfig_afu(afu);
> kfree(afu);
> }
> @@ -492,6 +498,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> __func__, rc);
> goto out;
> }
> +
> + /* Enable the AFU */
> + ocxl_config_set_afu_state(pdev, acfg->dvsec_afu_control_pos, 1);
> out:
> return rc;
> }
>
^ permalink raw reply
* Re: [PATCH v2 16/38] cxlflash: MMIO map the AFU
From: Frederic Barrat @ 2018-03-22 17:19 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683741-17330-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:22, Uma Krishnan a écrit :
> When the AFU is configured, the global and per process MMIO regions
> are presented by the configuration space. Save these regions and
> map the global MMIO region that is used to access all of the control
> and provisioning data in the AFU.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 74 ++++++++++++++++++++++++++++++++++++++++-
> drivers/scsi/cxlflash/ocxl_hw.h | 4 +++
> 2 files changed, 77 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 7717a63..3917aa1 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -264,6 +264,18 @@ static void ocxlflash_perst_reloads_same_image(void *afu_cookie, bool image)
> }
>
> /**
> + * ocxlflash_unconfig_afu() - unconfigure the AFU
> + * @afu: AFU associated with the host.
> + */
> +static void ocxlflash_unconfig_afu(struct ocxl_hw_afu *afu)
> +{
> + if (afu->gmmio_virt) {
> + iounmap(afu->gmmio_virt);
> + afu->gmmio_virt = NULL;
> + }
> +}
> +
> +/**
> * ocxlflash_destroy_afu() - destroy the AFU structure
> * @afu_cookie: AFU to be freed.
> */
> @@ -276,6 +288,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
>
> ocxlflash_release_context(afu->ocxl_ctx);
> idr_destroy(&afu->idr);
> + ocxlflash_unconfig_afu(afu);
> kfree(afu);
> }
>
> @@ -324,6 +337,56 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> }
>
> /**
> + * ocxlflash_map_mmio() - map the AFU MMIO space
> + * @afu: AFU associated with the host.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +static int ocxlflash_map_mmio(struct ocxl_hw_afu *afu)
> +{
> + struct ocxl_afu_config *acfg = &afu->acfg;
> + struct pci_dev *pdev = afu->pdev;
> + struct device *dev = afu->dev;
> + phys_addr_t gmmio, ppmmio;
> + int rc = 0;
> +
> + rc = pci_request_region(pdev, acfg->global_mmio_bar, "ocxlflash");
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: pci_request_region for global failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> + gmmio = pci_resource_start(pdev, acfg->global_mmio_bar);
> + gmmio += acfg->global_mmio_offset;
> +
> + rc = pci_request_region(pdev, acfg->pp_mmio_bar, "ocxlflash");
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: pci_request_region for pp bar failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> + ppmmio = pci_resource_start(pdev, acfg->pp_mmio_bar);
> + ppmmio += acfg->pp_mmio_offset;
> +
> + afu->gmmio_virt = ioremap(gmmio, acfg->global_mmio_size);
> + if (unlikely(!afu->gmmio_virt)) {
> + dev_err(dev, "%s: MMIO mapping failed\n", __func__);
> + rc = -ENOMEM;
> + goto err2;
> + }
> +
> + afu->gmmio_phys = gmmio;
> + afu->ppmmio_phys = ppmmio;
> +out:
> + return rc;
> +err2:
> + pci_release_region(pdev, acfg->pp_mmio_bar);
> +err1:
> + pci_release_region(pdev, acfg->global_mmio_bar);
> + goto out;
> +}
> +
> +/**
> * ocxlflash_config_afu() - configure the host AFU
> * @pdev: PCI device associated with the host.
> * @afu: AFU associated with the host.
> @@ -362,6 +425,13 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> afu->max_pasid = 1 << acfg->pasid_supported_log;
>
> ocxl_config_set_afu_pasid(pdev, pos, 0, acfg->pasid_supported_log);
> +
> + rc = ocxlflash_map_mmio(afu);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxlflash_map_mmio failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> out:
> return rc;
> }
> @@ -407,13 +477,15 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> rc = PTR_ERR(ctx);
> dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n",
> __func__, rc);
> - goto err1;
> + goto err2;
> }
>
> idr_init(&afu->idr);
> afu->ocxl_ctx = ctx;
> out:
> return afu;
> +err2:
> + ocxlflash_unconfig_afu(afu);
> err1:
> kfree(afu);
> afu = NULL;
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index fd1a8df..29c75c4 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -27,6 +27,10 @@ struct ocxl_hw_afu {
> int afu_actag_base; /* AFU acTag base */
> int afu_actag_enabled; /* AFU acTag number enabled */
>
> + phys_addr_t ppmmio_phys; /* Per process MMIO space */
> + phys_addr_t gmmio_phys; /* Global AFU MMIO space */
> + void __iomem *gmmio_virt; /* Global MMIO map */
> +
> struct idr idr; /* IDR to manage contexts */
> int max_pasid; /* Maximum number of contexts */
> };
>
^ permalink raw reply
* Re: [PATCH v2 13/38] cxlflash: Support adapter file descriptors for OCXL
From: Frederic Barrat @ 2018-03-22 17:12 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683719-17222-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> Allocate a file descriptor for an adapter context when requested. In order
> to allocate inodes for the file descriptors, a pseudo filesystem is created
> and used.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
We've touched the subject before, and I don't have a magic solution, but
it feels like something could be shared here with cxl, or maybe even
other drivers?
I only took a quick read of the inode allocator.
Fred
> drivers/scsi/cxlflash/ocxl_hw.c | 200 ++++++++++++++++++++++++++++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 1 +
> 2 files changed, 201 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 6472210..59e9003 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -12,13 +12,144 @@
> * 2 of the License, or (at your option) any later version.
> */
>
> +#include <linux/file.h>
> #include <linux/idr.h>
> +#include <linux/module.h>
> +#include <linux/mount.h>
>
> #include <misc/ocxl.h>
>
> #include "backend.h"
> #include "ocxl_hw.h"
>
> +/*
> + * Pseudo-filesystem to allocate inodes.
> + */
> +
> +#define OCXLFLASH_FS_MAGIC 0x1697698f
> +
> +static int ocxlflash_fs_cnt;
> +static struct vfsmount *ocxlflash_vfs_mount;
> +
> +static const struct dentry_operations ocxlflash_fs_dops = {
> + .d_dname = simple_dname,
> +};
> +
> +/*
> + * ocxlflash_fs_mount() - mount the pseudo-filesystem
> + * @fs_type: File system type.
> + * @flags: Flags for the filesystem.
> + * @dev_name: Device name associated with the filesystem.
> + * @data: Data pointer.
> + *
> + * Return: pointer to the directory entry structure
> + */
> +static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type,
> + int flags, const char *dev_name,
> + void *data)
> +{
> + return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops,
> + OCXLFLASH_FS_MAGIC);
> +}
> +
> +static struct file_system_type ocxlflash_fs_type = {
> + .name = "ocxlflash",
> + .owner = THIS_MODULE,
> + .mount = ocxlflash_fs_mount,
> + .kill_sb = kill_anon_super,
> +};
> +
> +/*
> + * ocxlflash_release_mapping() - release the memory mapping
> + * @ctx: Context whose mapping is to be released.
> + */
> +static void ocxlflash_release_mapping(struct ocxlflash_context *ctx)
> +{
> + if (ctx->mapping)
> + simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
> + ctx->mapping = NULL;
> +}
> +
> +/*
> + * ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file
> + * @dev: Generic device of the host.
> + * @name: Name of the pseudo filesystem.
> + * @fops: File operations.
> + * @priv: Private data.
> + * @flags: Flags for the file.
> + *
> + * Return: pointer to the file on success, ERR_PTR on failure
> + */
> +static struct file *ocxlflash_getfile(struct device *dev, const char *name,
> + const struct file_operations *fops,
> + void *priv, int flags)
> +{
> + struct qstr this;
> + struct path path;
> + struct file *file;
> + struct inode *inode = NULL;
> + int rc;
> +
> + if (fops->owner && !try_module_get(fops->owner)) {
> + dev_err(dev, "%s: Owner does not exist\n", __func__);
> + rc = -ENOENT;
> + goto err1;
> + }
> +
> + rc = simple_pin_fs(&ocxlflash_fs_type, &ocxlflash_vfs_mount,
> + &ocxlflash_fs_cnt);
> + if (unlikely(rc < 0)) {
> + dev_err(dev, "%s: Cannot mount ocxlflash pseudofs rc=%d\n",
> + __func__, rc);
> + goto err2;
> + }
> +
> + inode = alloc_anon_inode(ocxlflash_vfs_mount->mnt_sb);
> + if (IS_ERR(inode)) {
> + rc = PTR_ERR(inode);
> + dev_err(dev, "%s: alloc_anon_inode failed rc=%d\n",
> + __func__, rc);
> + goto err3;
> + }
> +
> + this.name = name;
> + this.len = strlen(name);
> + this.hash = 0;
> + path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, &this);
> + if (!path.dentry) {
> + dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__);
> + rc = -ENOMEM;
> + goto err4;
> + }
> +
> + path.mnt = mntget(ocxlflash_vfs_mount);
> + d_instantiate(path.dentry, inode);
> +
> + file = alloc_file(&path, OPEN_FMODE(flags), fops);
> + if (IS_ERR(file)) {
> + rc = PTR_ERR(file);
> + dev_err(dev, "%s: alloc_file failed rc=%d\n",
> + __func__, rc);
> + goto err5;
> + }
> +
> + file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
> + file->private_data = priv;
> +out:
> + return file;
> +err5:
> + path_put(&path);
> +err4:
> + iput(inode);
> +err3:
> + simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
> +err2:
> + module_put(fops->owner);
> +err1:
> + file = ERR_PTR(rc);
> + goto out;
> +}
> +
> /**
> * ocxlflash_set_master() - sets the context as master
> * @ctx_cookie: Adapter context to set as master.
> @@ -75,6 +206,7 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
>
> ctx->pe = rc;
> ctx->master = false;
> + ctx->mapping = NULL;
> ctx->hw_afu = afu;
> out:
> return ctx;
> @@ -100,6 +232,7 @@ static int ocxlflash_release_context(void *ctx_cookie)
> goto out;
>
> idr_remove(&ctx->hw_afu->idr, ctx->pe);
> + ocxlflash_release_mapping(ctx);
> kfree(ctx);
> out:
> return rc;
> @@ -262,6 +395,72 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> goto out;
> }
>
> +static const struct file_operations ocxl_afu_fops = {
> + .owner = THIS_MODULE,
> +};
> +
> +/**
> + * ocxlflash_get_fd() - get file descriptor for an adapter context
> + * @ctx_cookie: Adapter context.
> + * @fops: File operations to be associated.
> + * @fd: File descriptor to be returned back.
> + *
> + * Return: pointer to the file on success, ERR_PTR on failure
> + */
> +static struct file *ocxlflash_get_fd(void *ctx_cookie,
> + struct file_operations *fops, int *fd)
> +{
> + struct ocxlflash_context *ctx = ctx_cookie;
> + struct device *dev = ctx->hw_afu->dev;
> + struct file *file;
> + int flags, fdtmp;
> + int rc = 0;
> + char *name = NULL;
> +
> + /* Only allow one fd per context */
> + if (ctx->mapping) {
> + dev_err(dev, "%s: Context is already mapped to an fd\n",
> + __func__);
> + rc = -EEXIST;
> + goto err1;
> + }
> +
> + flags = O_RDWR | O_CLOEXEC;
> +
> + /* This code is similar to anon_inode_getfd() */
> + rc = get_unused_fd_flags(flags);
> + if (unlikely(rc < 0)) {
> + dev_err(dev, "%s: get_unused_fd_flags failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> + fdtmp = rc;
> +
> + /* Use default ops if there is no fops */
> + if (!fops)
> + fops = (struct file_operations *)&ocxl_afu_fops;
> +
> + name = kasprintf(GFP_KERNEL, "ocxlflash:%d", ctx->pe);
> + file = ocxlflash_getfile(dev, name, fops, ctx, flags);
> + kfree(name);
> + if (IS_ERR(file)) {
> + rc = PTR_ERR(file);
> + dev_err(dev, "%s: ocxlflash_getfile failed rc=%d\n",
> + __func__, rc);
> + goto err2;
> + }
> +
> + ctx->mapping = file->f_mapping;
> + *fd = fdtmp;
> +out:
> + return file;
> +err2:
> + put_unused_fd(fdtmp);
> +err1:
> + file = ERR_PTR(rc);
> + goto out;
> +}
> +
> /* Backend ops to ocxlflash services */
> const struct cxlflash_backend_ops cxlflash_ocxl_ops = {
> .module = THIS_MODULE,
> @@ -271,4 +470,5 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = {
> .release_context = ocxlflash_release_context,
> .create_afu = ocxlflash_create_afu,
> .destroy_afu = ocxlflash_destroy_afu,
> + .get_fd = ocxlflash_get_fd,
> };
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 0381682..7abc532 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -32,6 +32,7 @@ struct ocxl_hw_afu {
>
> struct ocxlflash_context {
> struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */
> + struct address_space *mapping; /* Mapping for pseudo filesystem */
> bool master; /* Whether this is a master context */
> int pe; /* Process element */
> };
>
^ permalink raw reply
* Re: [PATCH v2 12/38] cxlflash: Use IDR to manage adapter contexts
From: Frederic Barrat @ 2018-03-22 16:40 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683712-17186-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> A range of PASIDs are used as identifiers for the adapter contexts. These
> contexts may be destroyed and created randomly. Use an IDR to keep track
> of contexts that are in use and assign a unique identifier to new ones.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
> drivers/scsi/cxlflash/ocxl_hw.c | 20 ++++++++++++++++++--
> drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
> 2 files changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index d75b873..6472210 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -12,6 +12,8 @@
> * 2 of the License, or (at your option) any later version.
> */
>
> +#include <linux/idr.h>
> +
> #include <misc/ocxl.h>
>
> #include "backend.h"
> @@ -60,14 +62,25 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
> if (unlikely(!ctx)) {
> dev_err(dev, "%s: Context allocation failed\n", __func__);
> rc = -ENOMEM;
> - goto err;
> + goto err1;
> + }
> +
> + idr_preload(GFP_KERNEL);
> + rc = idr_alloc(&afu->idr, ctx, 0, afu->max_pasid, GFP_NOWAIT);
> + idr_preload_end();
I believe we can call idr_alloc(... GFP_KERNEL) directly in that
context now.
> + if (unlikely(rc < 0)) {
> + dev_err(dev, "%s: idr_alloc failed rc=%d\n", __func__, rc);
> + goto err2;
> }
>
> + ctx->pe = rc;
> ctx->master = false;
> ctx->hw_afu = afu;
> out:
> return ctx;
> -err:
> +err2:
> + kfree(ctx);
> +err1:
> ctx = ERR_PTR(rc);
> goto out;
> }
> @@ -86,6 +99,7 @@ static int ocxlflash_release_context(void *ctx_cookie)
> if (!ctx)
> goto out;
>
> + idr_remove(&ctx->hw_afu->idr, ctx->pe);
> kfree(ctx);
> out:
> return rc;
> @@ -103,6 +117,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
> return;
>
> ocxlflash_release_context(afu->ocxl_ctx);
> + idr_destroy(&afu->idr);
> kfree(afu);
> }
>
> @@ -237,6 +252,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> goto err1;
> }
>
> + idr_init(&afu->idr);
You initialize the IDR too late. ocxlflash_dev_context_init() was called
just above and allocated a PE.
Fred
> afu->ocxl_ctx = ctx;
> out:
> return afu;
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index de43c04..0381682 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -26,10 +26,12 @@ struct ocxl_hw_afu {
> int afu_actag_base; /* AFU acTag base */
> int afu_actag_enabled; /* AFU acTag number enabled */
>
> + struct idr idr; /* IDR to manage contexts */
> int max_pasid; /* Maximum number of contexts */
> };
>
> struct ocxlflash_context {
> struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */
> bool master; /* Whether this is a master context */
> + int pe; /* Process element */
> };
>
^ permalink raw reply
* [PATCH] cxl: disable the lazy approach for irqs in POWERVM environment.
From: Christophe Lombard @ 2018-03-22 16:37 UTC (permalink / raw)
To: linuxppc-dev, fbarrat, vaibhav, andrew.donnellan
The cxl driver cannot disable the interrupt at the device level and has
to use disable_irq[_nosync] instead.
To avoid the implementation of the lazy optimisation (the interrupt is
marked disabled, but the hardware is left unmasked), we can disable it,
for a particular irq line, by calling
'irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY)'.
Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
drivers/misc/cxl/guest.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index f58b4b6c..dc476e1 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -389,6 +389,7 @@ static void disable_afu_irqs(struct cxl_context *ctx)
hwirq = ctx->irqs.offset[r];
for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
virq = irq_find_mapping(NULL, hwirq);
+ irq_set_status_flags(virq, IRQ_DISABLE_UNLAZY);
disable_irq(virq);
}
}
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v2 2/2] Architecture defined limit on memory region random shift.
From: Ilya Smith @ 2018-03-22 16:36 UTC (permalink / raw)
To: rth, ink, mattst88, vgupta, linux, tony.luck, fenghua.yu, jhogan,
ralf, jejb, deller, benh, paulus, mpe, schwidefsky,
heiko.carstens, ysato, dalias, davem, tglx, mingo, hpa, x86, nyc,
viro, arnd, blackzert, gregkh, deepa.kernel, mhocko, hughd,
kstewart, pombredanne, akpm, steve.capper, punit.agrawal,
paul.burton, aneesh.kumar, npiggin, keescook, bhsharma, riel,
nitin.m.gupta, kirill.shutemov, dan.j.williams, jack,
ross.zwisler, jglisse, willy, aarcange, oleg, linux-alpha,
linux-kernel, linux-snps-arc, linux-arm-kernel, linux-ia64,
linux-metag, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-mm
In-Reply-To: <1521736598-12812-1-git-send-email-blackzert@gmail.com>
Signed-off-by: Ilya Smith <blackzert@gmail.com>
---
arch/alpha/kernel/osf_sys.c | 1 +
arch/arc/mm/mmap.c | 1 +
arch/arm/mm/mmap.c | 2 ++
arch/frv/mm/elf-fdpic.c | 1 +
arch/ia64/kernel/sys_ia64.c | 1 +
arch/ia64/mm/hugetlbpage.c | 1 +
arch/metag/mm/hugetlbpage.c | 1 +
arch/mips/mm/mmap.c | 1 +
arch/parisc/kernel/sys_parisc.c | 2 ++
arch/powerpc/mm/hugetlbpage-radix.c | 1 +
arch/powerpc/mm/mmap.c | 2 ++
arch/powerpc/mm/slice.c | 2 ++
arch/s390/mm/mmap.c | 2 ++
arch/sh/mm/mmap.c | 2 ++
arch/sparc/kernel/sys_sparc_32.c | 1 +
arch/sparc/kernel/sys_sparc_64.c | 2 ++
arch/sparc/mm/hugetlbpage.c | 2 ++
arch/tile/mm/hugetlbpage.c | 2 ++
arch/x86/kernel/sys_x86_64.c | 4 ++++
arch/x86/mm/hugetlbpage.c | 4 ++++
fs/hugetlbfs/inode.c | 1 +
include/linux/mm.h | 1 +
mm/mmap.c | 3 ++-
23 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index fa1a392..0ab9f31 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1301,6 +1301,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
info.high_limit = limit;
info.align_mask = 0;
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c
index 2e13683..45225fc 100644
--- a/arch/arc/mm/mmap.c
+++ b/arch/arc/mm/mmap.c
@@ -75,5 +75,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index eb1de66..1eb660c 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -101,6 +101,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
@@ -152,6 +153,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
/*
diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
index 46aa289..a2ce2ce 100644
--- a/arch/frv/mm/elf-fdpic.c
+++ b/arch/frv/mm/elf-fdpic.c
@@ -86,6 +86,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.high_limit = (current->mm->start_stack - 0x00200000);
info.align_mask = 0;
info.align_offset = 0;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
goto success;
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 085adfc..15fa4fb 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -64,6 +64,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
info.high_limit = TASK_SIZE;
info.align_mask = align_mask;
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index d16e419..ec7822d 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -162,6 +162,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
info.high_limit = HPAGE_REGION_BASE + RGN_MAP_LIMIT;
info.align_mask = PAGE_MASK & (HPAGE_SIZE - 1);
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
index 012ee4c..babd325 100644
--- a/arch/metag/mm/hugetlbpage.c
+++ b/arch/metag/mm/hugetlbpage.c
@@ -191,6 +191,7 @@ hugetlb_get_unmapped_area_new_pmd(unsigned long len)
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & HUGEPT_MASK;
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 33d3251..5a3d384 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -122,6 +122,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
info.flags = 0;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 378a754..abf4b05 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -130,6 +130,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = mmap_upper_limit();
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
found_addr:
@@ -192,6 +193,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
goto found_addr;
diff --git a/arch/powerpc/mm/hugetlbpage-radix.c b/arch/powerpc/mm/hugetlbpage-radix.c
index 2486bee..1d61a88 100644
--- a/arch/powerpc/mm/hugetlbpage-radix.c
+++ b/arch/powerpc/mm/hugetlbpage-radix.c
@@ -87,6 +87,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index d503f34..7fe98c7 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -136,6 +136,7 @@ radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.low_limit = mm->mmap_base;
info.high_limit = high_limit;
info.align_mask = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
@@ -180,6 +181,7 @@ radix__arch_get_unmapped_area_topdown(struct file *filp,
info.low_limit = max(PAGE_SIZE, mmap_min_addr);
info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
info.align_mask = 0;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 23ec2c5..2005845 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -284,6 +284,7 @@ static unsigned long slice_find_area_bottomup(struct mm_struct *mm,
info.length = len;
info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
info.align_offset = 0;
+ info.random_shift = 0;
addr = TASK_UNMAPPED_BASE;
/*
@@ -330,6 +331,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
info.length = len;
info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
info.align_offset = 0;
+ info.random_shift = 0;
addr = mm->mmap_base;
/*
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 831bdcf..141823f 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -95,6 +95,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
+ info.random_shift = 0;
if (filp || (flags & MAP_SHARED))
info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
else
@@ -146,6 +147,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = max(PAGE_SIZE, mmap_min_addr);
info.high_limit = mm->mmap_base;
+ info.random_shift = 0;
if (filp || (flags & MAP_SHARED))
info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
else
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 6a1a129..d9206c2 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -74,6 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
@@ -124,6 +125,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
/*
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 990703b7..af664ba3 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -66,6 +66,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.align_mask = (flags & MAP_SHARED) ?
(PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 55416db..3d12e3d 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -131,6 +131,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
info.high_limit = min(task_size, VA_EXCLUDE_START);
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
@@ -194,6 +195,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
/*
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 0112d69..6d0c032 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -43,6 +43,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
info.high_limit = min(task_size, VA_EXCLUDE_START);
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
@@ -75,6 +76,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
/*
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index 0986d42..2b3a9b6 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -176,6 +176,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
@@ -193,6 +194,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
info.high_limit = current->mm->mmap_base;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
addr = vm_unmapped_area(&info);
/*
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 676774b..0eda047 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -163,6 +163,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = end;
info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = in_compat_syscall() ?
+ 256 : 0x1000000;
if (filp) {
info.align_mask = get_align_mask();
info.align_offset += get_align_bits();
@@ -224,6 +226,8 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
+ info.random_shift = in_compat_syscall() ?
+ 256 : 0x1000000;
if (filp) {
info.align_mask = get_align_mask();
info.align_offset += get_align_bits();
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 00b2966..f4f6436 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -97,6 +97,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = in_compat_syscall() ?
+ 256 : 0x1000000;
return vm_unmapped_area(&info);
}
@@ -121,6 +123,8 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = in_compat_syscall() ?
+ 256 : 0x1000000;
addr = vm_unmapped_area(&info);
/*
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8fe1b0a..83e962e 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -200,6 +200,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c716257..f869e6d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2252,6 +2252,7 @@ struct vm_unmapped_area_info {
unsigned long high_limit;
unsigned long align_mask;
unsigned long align_offset;
+ unsigned long random_shift;
};
#ifndef CONFIG_MMU
diff --git a/mm/mmap.c b/mm/mmap.c
index ba9cebb..425fa09 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1938,7 +1938,7 @@ unsigned long unmapped_area_random(struct vm_unmapped_area_info *info)
if (gap_end == gap_start)
return gap_start;
addr = entropy[1] % (min((gap_end - gap_start) >> PAGE_SHIFT,
- 0x10000UL));
+ info->random_shift));
addr = gap_end - (addr << PAGE_SHIFT);
addr += (info->align_offset - addr) & info->align_mask;
return addr;
@@ -2186,6 +2186,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
info.align_mask = 0;
+ info.random_shift = 0;
return vm_unmapped_area(&info);
}
#endif
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v2 1/2] Randomization of address chosen by mmap.
From: Ilya Smith @ 2018-03-22 16:36 UTC (permalink / raw)
To: rth, ink, mattst88, vgupta, linux, tony.luck, fenghua.yu, jhogan,
ralf, jejb, deller, benh, paulus, mpe, schwidefsky,
heiko.carstens, ysato, dalias, davem, tglx, mingo, hpa, x86, nyc,
viro, arnd, blackzert, gregkh, deepa.kernel, mhocko, hughd,
kstewart, pombredanne, akpm, steve.capper, punit.agrawal,
paul.burton, aneesh.kumar, npiggin, keescook, bhsharma, riel,
nitin.m.gupta, kirill.shutemov, dan.j.williams, jack,
ross.zwisler, jglisse, willy, aarcange, oleg, linux-alpha,
linux-kernel, linux-snps-arc, linux-arm-kernel, linux-ia64,
linux-metag, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-mm
In-Reply-To: <1521736598-12812-1-git-send-email-blackzert@gmail.com>
Signed-off-by: Ilya Smith <blackzert@gmail.com>
---
include/linux/mm.h | 16 ++++--
mm/mmap.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 5 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ad06d42..c716257 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/page_ref.h>
#include <linux/memremap.h>
+#include <linux/sched.h>
struct mempolicy;
struct anon_vma;
@@ -2253,6 +2254,13 @@ struct vm_unmapped_area_info {
unsigned long align_offset;
};
+#ifndef CONFIG_MMU
+#define randomize_va_space 0
+#else
+extern int randomize_va_space;
+#endif
+
+extern unsigned long unmapped_area_random(struct vm_unmapped_area_info *info);
extern unsigned long unmapped_area(struct vm_unmapped_area_info *info);
extern unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info);
@@ -2268,6 +2276,9 @@ extern unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info);
static inline unsigned long
vm_unmapped_area(struct vm_unmapped_area_info *info)
{
+ /* How about 32 bit process?? */
+ if ((current->flags & PF_RANDOMIZE) && randomize_va_space > 3)
+ return unmapped_area_random(info);
if (info->flags & VM_UNMAPPED_AREA_TOPDOWN)
return unmapped_area_topdown(info);
else
@@ -2529,11 +2540,6 @@ int drop_caches_sysctl_handler(struct ctl_table *, int,
void drop_slab(void);
void drop_slab_node(int nid);
-#ifndef CONFIG_MMU
-#define randomize_va_space 0
-#else
-extern int randomize_va_space;
-#endif
const char * arch_vma_name(struct vm_area_struct *vma);
void print_vma_addr(char *prefix, unsigned long rip);
diff --git a/mm/mmap.c b/mm/mmap.c
index 9efdc021..ba9cebb 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -45,6 +45,7 @@
#include <linux/moduleparam.h>
#include <linux/pkeys.h>
#include <linux/oom.h>
+#include <linux/random.h>
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
@@ -1780,6 +1781,169 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
return error;
}
+unsigned long unmapped_area_random(struct vm_unmapped_area_info *info)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma = NULL;
+ struct vm_area_struct *visited_vma = NULL;
+ unsigned long entropy[2];
+ unsigned long length, low_limit, high_limit, gap_start, gap_end;
+ unsigned long addr = 0;
+
+ /* get entropy with prng */
+ prandom_bytes(&entropy, sizeof(entropy));
+ /* small hack to prevent EPERM result */
+ info->low_limit = max(info->low_limit, mmap_min_addr);
+
+ /* Adjust search length to account for worst case alignment overhead */
+ length = info->length + info->align_mask;
+ if (length < info->length)
+ return -ENOMEM;
+
+ /*
+ * Adjust search limits by the desired length.
+ * See implementation comment at top of unmapped_area().
+ */
+ gap_end = info->high_limit;
+ if (gap_end < length)
+ return -ENOMEM;
+ high_limit = gap_end - length;
+
+ low_limit = info->low_limit + info->align_mask;
+ if (low_limit >= high_limit)
+ return -ENOMEM;
+
+ /* Choose random addr in limit range */
+ addr = entropy[0] % ((high_limit - low_limit) >> PAGE_SHIFT);
+ addr = low_limit + (addr << PAGE_SHIFT);
+ addr += (info->align_offset - addr) & info->align_mask;
+
+ /* Check if rbtree root looks promising */
+ if (RB_EMPTY_ROOT(&mm->mm_rb))
+ return -ENOMEM;
+
+ vma = rb_entry(mm->mm_rb.rb_node, struct vm_area_struct, vm_rb);
+ if (vma->rb_subtree_gap < length)
+ return -ENOMEM;
+ /* use randomly chosen address to find closest suitable gap */
+ while (true) {
+ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
+ gap_end = vm_start_gap(vma);
+ if (gap_end < low_limit)
+ break;
+ if (addr < vm_start_gap(vma)) {
+ /* random said check left */
+ if (vma->vm_rb.rb_left) {
+ struct vm_area_struct *left =
+ rb_entry(vma->vm_rb.rb_left,
+ struct vm_area_struct, vm_rb);
+ if (addr <= vm_start_gap(left) &&
+ left->rb_subtree_gap >= length) {
+ vma = left;
+ continue;
+ }
+ }
+ } else if (addr >= vm_end_gap(vma)) {
+ /* random said check right */
+ if (vma->vm_rb.rb_right) {
+ struct vm_area_struct *right =
+ rb_entry(vma->vm_rb.rb_right,
+ struct vm_area_struct, vm_rb);
+ /* it want go to the right */
+ if (right->rb_subtree_gap >= length) {
+ vma = right;
+ continue;
+ }
+ }
+ }
+ if (gap_start < low_limit) {
+ if (gap_end <= low_limit)
+ break;
+ gap_start = low_limit;
+ } else if (gap_end > info->high_limit) {
+ if (gap_start >= info->high_limit)
+ break;
+ gap_end = info->high_limit;
+ }
+ if (gap_end > gap_start &&
+ gap_end - gap_start >= length)
+ goto found;
+ visited_vma = vma;
+ break;
+ }
+ /* not found */
+ while (true) {
+ gap_start = vma->vm_prev ? vm_end_gap(vma->vm_prev) : 0;
+
+ if (gap_start <= high_limit && vma->vm_rb.rb_right) {
+ struct vm_area_struct *right =
+ rb_entry(vma->vm_rb.rb_right,
+ struct vm_area_struct, vm_rb);
+ if (right->rb_subtree_gap >= length &&
+ right != visited_vma) {
+ vma = right;
+ continue;
+ }
+ }
+
+check_current:
+ /* Check if current node has a suitable gap */
+ gap_end = vm_start_gap(vma);
+ if (gap_end <= low_limit)
+ goto go_back;
+
+ if (gap_start < low_limit)
+ gap_start = low_limit;
+
+ if (gap_start <= high_limit &&
+ gap_end > gap_start && gap_end - gap_start >= length)
+ goto found;
+
+ /* Visit left subtree if it looks promising */
+ if (vma->vm_rb.rb_left) {
+ struct vm_area_struct *left =
+ rb_entry(vma->vm_rb.rb_left,
+ struct vm_area_struct, vm_rb);
+ if (left->rb_subtree_gap >= length &&
+ vm_end_gap(left) > low_limit &&
+ left != visited_vma) {
+ vma = left;
+ continue;
+ }
+ }
+go_back:
+ /* Go back up the rbtree to find next candidate node */
+ while (true) {
+ struct rb_node *prev = &vma->vm_rb;
+
+ if (!rb_parent(prev))
+ return -ENOMEM;
+ visited_vma = vma;
+ vma = rb_entry(rb_parent(prev),
+ struct vm_area_struct, vm_rb);
+ if (prev == vma->vm_rb.rb_right) {
+ gap_start = vma->vm_prev ?
+ vm_end_gap(vma->vm_prev) : low_limit;
+ goto check_current;
+ }
+ }
+ }
+found:
+ /* We found a suitable gap. Clip it with the original high_limit. */
+ if (gap_end > info->high_limit)
+ gap_end = info->high_limit;
+ gap_end -= info->length;
+ gap_end -= (gap_end - info->align_offset) & info->align_mask;
+ /* only one suitable page */
+ if (gap_end == gap_start)
+ return gap_start;
+ addr = entropy[1] % (min((gap_end - gap_start) >> PAGE_SHIFT,
+ 0x10000UL));
+ addr = gap_end - (addr << PAGE_SHIFT);
+ addr += (info->align_offset - addr) & info->align_mask;
+ return addr;
+}
+
unsigned long unmapped_area(struct vm_unmapped_area_info *info)
{
/*
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v2 0/2] Randomization of address chosen by mmap.
From: Ilya Smith @ 2018-03-22 16:36 UTC (permalink / raw)
To: rth, ink, mattst88, vgupta, linux, tony.luck, fenghua.yu, jhogan,
ralf, jejb, deller, benh, paulus, mpe, schwidefsky,
heiko.carstens, ysato, dalias, davem, tglx, mingo, hpa, x86, nyc,
viro, arnd, blackzert, gregkh, deepa.kernel, mhocko, hughd,
kstewart, pombredanne, akpm, steve.capper, punit.agrawal,
paul.burton, aneesh.kumar, npiggin, keescook, bhsharma, riel,
nitin.m.gupta, kirill.shutemov, dan.j.williams, jack,
ross.zwisler, jglisse, willy, aarcange, oleg, linux-alpha,
linux-kernel, linux-snps-arc, linux-arm-kernel, linux-ia64,
linux-metag, linux-mips, linux-parisc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, linux-mm
Current implementation doesn't randomize address returned by mmap.
All the entropy ends with choosing mmap_base_addr at the process
creation. After that mmap build very predictable layout of address
space. It allows to bypass ASLR in many cases. This patch make
randomization of address on any mmap call.
---
v2: Changed the way how gap was chosen. Now we don't get all possible
gaps. Random address generated and used as a tree walking direction.
Tree walked with backtracking till suitable gap will be found.
When the gap was found, address randomly shifted from next vma start.
The vm_unmapped_area_info structure was extended with new field random_shift
what might be used to set arch-depended limit on shift to next vma start.
In case of x86-64 architecture this shift is 256 pages for 32 bit applications
and 0x1000000 pages for 64 bit.
To get the entropy pseudo-random is used. This is because on Intel x86-64
processors instruction RDRAND works very slow if buffer is consumed -
after about 10000 iterations.
This feature could be enabled by setting randomize_va_space with 4.
---
Performance:
After applying this patch single mmap took about 7% longer according to
following test:
before = rdtsc();
addr = mmap(0, SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
after = rdtsc();
diff = after - before;
munmap(addr, SIZE)
...
unsigned long long total = 0;
for(int i = 0; i < count; ++i) {
total += one_iteration();
}
printf("%lld\n", total);
Time is consumed by div instruction in computation of the address.
make kernel:
echo 2 > /proc/sys/kernel/randomize_va_space
make mrproper && make defconfig && time make
real 11m9.925s
user 10m17.829s
sys 1m4.969s
echo 4 > /proc/sys/kernel/randomize_va_space
make mrproper && make defconfig && time make
real 11m12.806s
user 10m18.305s
sys 1m4.281s
Ilya Smith (2):
Randomization of address chosen by mmap.
Architecture defined limit on memory region random shift.
arch/alpha/kernel/osf_sys.c | 1 +
arch/arc/mm/mmap.c | 1 +
arch/arm/mm/mmap.c | 2 +
arch/frv/mm/elf-fdpic.c | 1 +
arch/ia64/kernel/sys_ia64.c | 1 +
arch/ia64/mm/hugetlbpage.c | 1 +
arch/metag/mm/hugetlbpage.c | 1 +
arch/mips/mm/mmap.c | 1 +
arch/parisc/kernel/sys_parisc.c | 2 +
arch/powerpc/mm/hugetlbpage-radix.c | 1 +
arch/powerpc/mm/mmap.c | 2 +
arch/powerpc/mm/slice.c | 2 +
arch/s390/mm/mmap.c | 2 +
arch/sh/mm/mmap.c | 2 +
arch/sparc/kernel/sys_sparc_32.c | 1 +
arch/sparc/kernel/sys_sparc_64.c | 2 +
arch/sparc/mm/hugetlbpage.c | 2 +
arch/tile/mm/hugetlbpage.c | 2 +
arch/x86/kernel/sys_x86_64.c | 4 +
arch/x86/mm/hugetlbpage.c | 4 +
fs/hugetlbfs/inode.c | 1 +
include/linux/mm.h | 17 ++--
mm/mmap.c | 165 ++++++++++++++++++++++++++++++++++++
23 files changed, 213 insertions(+), 5 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH v2 11/38] cxlflash: Adapter context support for OCXL
From: Frederic Barrat @ 2018-03-22 16:32 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683703-17149-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> Add support to create and release the adapter contexts for OCXL and
> provide means to specify certain contexts as a master.
>
> The existing cxlflash core has a design requirement that each host will
> have a single host context available by default. To satisfy this
> requirement, one host adapter context is created when the hardware AFU is
> initialized. This is returned by the get_context() fop.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 90 +++++++++++++++++++++++++++++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 6 +++
> 2 files changed, 96 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index bd86eef..d75b873 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -18,6 +18,80 @@
> #include "ocxl_hw.h"
>
> /**
> + * ocxlflash_set_master() - sets the context as master
> + * @ctx_cookie: Adapter context to set as master.
> + */
> +static void ocxlflash_set_master(void *ctx_cookie)
> +{
> + struct ocxlflash_context *ctx = ctx_cookie;
> +
> + ctx->master = true;
> +}
> +
> +/**
> + * ocxlflash_get_context() - obtains the context associated with the host
> + * @pdev: PCI device associated with the host.
> + * @afu_cookie: Hardware AFU associated with the host.
> + *
> + * Return: returns the pointer to host adapter context
> + */
> +static void *ocxlflash_get_context(struct pci_dev *pdev, void *afu_cookie)
> +{
> + struct ocxl_hw_afu *afu = afu_cookie;
> +
> + return afu->ocxl_ctx;
> +}
> +
> +/**
> + * ocxlflash_dev_context_init() - allocate and initialize an adapter context
> + * @pdev: PCI device associated with the host.
> + * @afu_cookie: Hardware AFU associated with the host.
> + *
> + * Return: returns the adapter context on success, ERR_PTR on failure
> + */
> +static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie)
> +{
> + struct ocxl_hw_afu *afu = afu_cookie;
> + struct device *dev = afu->dev;
> + struct ocxlflash_context *ctx;
> + int rc;
> +
> + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> + if (unlikely(!ctx)) {
> + dev_err(dev, "%s: Context allocation failed\n", __func__);
> + rc = -ENOMEM;
> + goto err;
> + }
> +
> + ctx->master = false;
> + ctx->hw_afu = afu;
> +out:
> + return ctx;
> +err:
> + ctx = ERR_PTR(rc);
> + goto out;
> +}
> +
> +/**
> + * ocxlflash_release_context() - releases an adapter context
> + * @ctx_cookie: Adapter context to be released.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +static int ocxlflash_release_context(void *ctx_cookie)
> +{
> + struct ocxlflash_context *ctx = ctx_cookie;
> + int rc = 0;
> +
> + if (!ctx)
> + goto out;
> +
> + kfree(ctx);
> +out:
> + return rc;
> +}
> +
> +/**
> * ocxlflash_destroy_afu() - destroy the AFU structure
> * @afu_cookie: AFU to be freed.
> */
> @@ -28,6 +102,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
> if (!afu)
> return;
>
> + ocxlflash_release_context(afu->ocxl_ctx);
> kfree(afu);
> }
>
> @@ -127,6 +202,7 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> static void *ocxlflash_create_afu(struct pci_dev *pdev)
> {
> struct device *dev = &pdev->dev;
> + struct ocxlflash_context *ctx;
> struct ocxl_hw_afu *afu;
> int rc;
>
> @@ -152,6 +228,16 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> __func__, rc);
> goto err1;
> }
> +
> + ctx = ocxlflash_dev_context_init(pdev, afu);
> + if (IS_ERR(ctx)) {
> + rc = PTR_ERR(ctx);
> + dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> +
> + afu->ocxl_ctx = ctx;
> out:
> return afu;
> err1:
> @@ -163,6 +249,10 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> /* Backend ops to ocxlflash services */
> const struct cxlflash_backend_ops cxlflash_ocxl_ops = {
> .module = THIS_MODULE,
> + .set_master = ocxlflash_set_master,
> + .get_context = ocxlflash_get_context,
> + .dev_context_init = ocxlflash_dev_context_init,
> + .release_context = ocxlflash_release_context,
> .create_afu = ocxlflash_create_afu,
> .destroy_afu = ocxlflash_destroy_afu,
> };
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index a6f7796..de43c04 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -14,6 +14,7 @@
>
> /* OCXL hardware AFU associated with the host */
> struct ocxl_hw_afu {
> + struct ocxlflash_context *ocxl_ctx; /* Host context */
> struct pci_dev *pdev; /* PCI device */
> struct device *dev; /* Generic device */
>
> @@ -27,3 +28,8 @@ struct ocxl_hw_afu {
>
> int max_pasid; /* Maximum number of contexts */
> };
> +
> +struct ocxlflash_context {
> + struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */
> + bool master; /* Whether this is a master context */
> +};
>
^ permalink raw reply
* Re: [PATCH v2 10/38] cxlflash: Setup AFU PASID
From: Frederic Barrat @ 2018-03-22 16:23 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683693-17113-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> Per the OCXL specification, the maximum PASID supported by the AFU is
> indicated by a field within the configuration space. Similar to acTags,
> implementations can choose to use any sub-range of PASID within their
> assigned range. For cxlflash, the entire range is used.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
It sure helps to know you've got only one function/AFU :-)
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 3 +++
> drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
> 2 files changed, 5 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index d01847d9..bd86eef 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -111,6 +111,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> dev_dbg(dev, "%s: acTag base=%d enabled=%d\n", __func__, base, count);
> afu->afu_actag_base = base;
> afu->afu_actag_enabled = count;
> + afu->max_pasid = 1 << acfg->pasid_supported_log;
> +
> + ocxl_config_set_afu_pasid(pdev, pos, 0, acfg->pasid_supported_log);
> out:
> return rc;
> }
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 9c675fa..a6f7796 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -24,4 +24,6 @@ struct ocxl_hw_afu {
> int fn_actag_enabled; /* Function acTag number enabled */
> int afu_actag_base; /* AFU acTag base */
> int afu_actag_enabled; /* AFU acTag number enabled */
> +
> + int max_pasid; /* Maximum number of contexts */
> };
>
^ permalink raw reply
* Re: [PATCH v2 09/38] cxlflash: Setup AFU acTag range
From: Frederic Barrat @ 2018-03-22 16:12 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683669-17075-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> The OCXL specification supports distributing acTags amongst different
> AFUs and functions on the link. As cxlflash devices are expected to only
> support a single AFU and function, the entire range that was assigned to
> the function is also assigned to the AFU.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 13 +++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
> 2 files changed, 15 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 2325030..d01847d9 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -89,6 +89,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> struct ocxl_afu_config *acfg = &afu->acfg;
> struct ocxl_fn_config *fcfg = &afu->fcfg;
> struct device *dev = &pdev->dev;
> + int count;
> + int base;
> + int pos;
> int rc = 0;
>
> /* Read AFU config at index 0 */
> @@ -98,6 +101,16 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> __func__, rc);
> goto out;
> }
> +
> + /* Only one AFU per function is supported, so actag_base is same */
> + base = afu->fn_actag_base;
> + count = min_t(int, acfg->actag_supported, afu->fn_actag_enabled);
> + pos = acfg->dvsec_afu_control_pos;
> +
> + ocxl_config_set_afu_actag(pdev, pos, base, count);
> + dev_dbg(dev, "%s: acTag base=%d enabled=%d\n", __func__, base, count);
> + afu->afu_actag_base = base;
> + afu->afu_actag_enabled = count;
> out:
> return rc;
> }
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index f6af247..9c675fa 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -22,4 +22,6 @@ struct ocxl_hw_afu {
>
> int fn_actag_base; /* Function acTag base */
> int fn_actag_enabled; /* Function acTag number enabled */
> + int afu_actag_base; /* AFU acTag base */
> + int afu_actag_enabled; /* AFU acTag number enabled */
> };
>
^ permalink raw reply
* Re: [PATCH v2 08/38] cxlflash: Read host AFU configuration
From: Frederic Barrat @ 2018-03-22 16:08 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683660-17039-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> The host AFU configuration is read on the initialization path to identify
> the features and configuration of the AFU. This data is cached for use in
> later configuration steps.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
> drivers/scsi/cxlflash/ocxl_hw.c | 34 ++++++++++++++++++++++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 1 +
> 2 files changed, 35 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 39cccb7..2325030 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -76,6 +76,33 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> }
>
> /**
> + * ocxlflash_config_afu() - configure the host AFU
> + * @pdev: PCI device associated with the host.
> + * @afu: AFU associated with the host.
> + *
> + * Must be called _after_ host function configuration.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> +{
> + struct ocxl_afu_config *acfg = &afu->acfg;
> + struct ocxl_fn_config *fcfg = &afu->fcfg;
> + struct device *dev = &pdev->dev;
> + int rc = 0;
> +
> + /* Read AFU config at index 0 */
> + rc = ocxl_config_read_afu(pdev, fcfg, acfg, 0);
Looking at other patches around this one, there's really the assumption
that we have only one AFU (which is fine). So similar to another
comment, we could harden that the AFU image really looks like what we
expect. Here, we read the config at index 0. Just a suggestion that
ocxl_fn_config gives you the maximum index of AFUs for the function
ocxl_fn_config->max_afu_index
So it should be 0 for cxlflash.
Fred
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxl_config_read_afu failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> +out:
> + return rc;
> +}
> +
> +/**
> * ocxlflash_create_afu() - create the AFU for OCXL
> * @pdev: PCI device associated with the host.
> *
> @@ -102,6 +129,13 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> __func__, rc);
> goto err1;
> }
> +
> + rc = ocxlflash_config_afu(pdev, afu);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: AFU configuration failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> out:
> return afu;
> err1:
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 190d71a..f6af247 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -18,6 +18,7 @@ struct ocxl_hw_afu {
> struct device *dev; /* Generic device */
>
> struct ocxl_fn_config fcfg; /* DVSEC config of the function */
> + struct ocxl_afu_config acfg; /* AFU configuration data */
>
> int fn_actag_base; /* Function acTag base */
> int fn_actag_enabled; /* Function acTag number enabled */
>
^ permalink raw reply
* Re: [PATCH v2 08/38] cxlflash: Read host AFU configuration
From: Frederic Barrat @ 2018-03-22 15:52 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683660-17039-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
> The host AFU configuration is read on the initialization path to identify
> the features and configuration of the AFU. This data is cached for use in
> later configuration steps.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 34 ++++++++++++++++++++++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 1 +
> 2 files changed, 35 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index 39cccb7..2325030 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -76,6 +76,33 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> }
>
> /**
> + * ocxlflash_config_afu() - configure the host AFU
> + * @pdev: PCI device associated with the host.
> + * @afu: AFU associated with the host.
> + *
> + * Must be called _after_ host function configuration.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> +{
> + struct ocxl_afu_config *acfg = &afu->acfg;
> + struct ocxl_fn_config *fcfg = &afu->fcfg;
> + struct device *dev = &pdev->dev;
> + int rc = 0;
> +
> + /* Read AFU config at index 0 */
> + rc = ocxl_config_read_afu(pdev, fcfg, acfg, 0);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxl_config_read_afu failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> +out:
> + return rc;
> +}
> +
> +/**
> * ocxlflash_create_afu() - create the AFU for OCXL
> * @pdev: PCI device associated with the host.
> *
> @@ -102,6 +129,13 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> __func__, rc);
> goto err1;
> }
> +
> + rc = ocxlflash_config_afu(pdev, afu);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: AFU configuration failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> out:
> return afu;
> err1:
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 190d71a..f6af247 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -18,6 +18,7 @@ struct ocxl_hw_afu {
> struct device *dev; /* Generic device */
>
> struct ocxl_fn_config fcfg; /* DVSEC config of the function */
> + struct ocxl_afu_config acfg; /* AFU configuration data */
>
> int fn_actag_base; /* Function acTag base */
> int fn_actag_enabled; /* Function acTag number enabled */
>
^ permalink raw reply
* Re: [PATCH v2 07/38] cxlflash: Setup function acTag range
From: Frederic Barrat @ 2018-03-22 15:48 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683651-17003-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:20, Uma Krishnan a écrit :
> The OCXL specification supports distributing acTags amongst different
> AFUs and functions on the link. The platform-specific acTag range for the
> link is obtained using the OCXL provider services and then assigned to the
> host function based on implementation. For cxlflash devices only a single
> function per host is expected and thus the entire range is assigned.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
> drivers/scsi/cxlflash/ocxl_hw.c | 15 +++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 3 +++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index dc32a73..39cccb7 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -42,6 +42,7 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> {
> struct ocxl_fn_config *fcfg = &afu->fcfg;
> struct device *dev = &pdev->dev;
> + u16 base, enabled, supported;
> int rc = 0;
>
> /* Read DVSEC config of the function */
> @@ -56,6 +57,20 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> if (fcfg->max_afu_index != 0)
> dev_warn(dev, "%s: Unexpected AFU index value %d\n",
> __func__, fcfg->max_afu_index);
> +
> + rc = ocxl_config_get_actag_info(pdev, &base, &enabled, &supported);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxl_config_get_actag_info failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> +
> + afu->fn_actag_base = base;
> + afu->fn_actag_enabled = enabled;
> +
Since you know your configuration (only 1 function with AFU, all actags
to that AFU), you could even have a warning if supported != enabled, to
detect suspicious AFU images.
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> + ocxl_config_set_actag(pdev, fcfg->dvsec_function_pos, base, enabled);
> + dev_dbg(dev, "%s: Function acTag range base=%u enabled=%u\n",
> + __func__, base, enabled);
> out:
> return rc;
> }
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index 658f420..190d71a 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -18,4 +18,7 @@ struct ocxl_hw_afu {
> struct device *dev; /* Generic device */
>
> struct ocxl_fn_config fcfg; /* DVSEC config of the function */
> +
> + int fn_actag_base; /* Function acTag base */
> + int fn_actag_enabled; /* Function acTag number enabled */
> };
>
^ permalink raw reply
* Re: [PATCH v2 06/38] cxlflash: Read host function configuration
From: Frederic Barrat @ 2018-03-22 15:43 UTC (permalink / raw)
To: Uma Krishnan, linux-scsi, James Bottomley, Martin K. Petersen,
Matthew R. Ochs, Manoj N. Kumar
Cc: linuxppc-dev, Andrew Donnellan, Christophe Lombard
In-Reply-To: <1519683641-16967-1-git-send-email-ukrishn@linux.vnet.ibm.com>
Le 26/02/2018 à 23:20, Uma Krishnan a écrit :
> Per the OCXL specification, the underlying host can have multiple AFUs
> per function with each function supporting its own configuration. The host
> function configuration is read on the initialization path to evaluate the
> number of functions present and identify the features and configuration of
> the functions present. This data is cached for use in later configuration
> steps. Note that for the OCXL hardware supported by the cxlflash driver,
> only one AFU per function is expected.
>
> Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
> Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
> ---
Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> drivers/scsi/cxlflash/ocxl_hw.c | 41 +++++++++++++++++++++++++++++++++++++++++
> drivers/scsi/cxlflash/ocxl_hw.h | 2 ++
> 2 files changed, 43 insertions(+)
>
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
> index e3a0a9b..dc32a73 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.c
> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
> @@ -32,6 +32,35 @@ static void ocxlflash_destroy_afu(void *afu_cookie)
> }
>
> /**
> + * ocxlflash_config_fn() - configure the host function
> + * @pdev: PCI device associated with the host.
> + * @afu: AFU associated with the host.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu)
> +{
> + struct ocxl_fn_config *fcfg = &afu->fcfg;
> + struct device *dev = &pdev->dev;
> + int rc = 0;
> +
> + /* Read DVSEC config of the function */
> + rc = ocxl_config_read_function(pdev, fcfg);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: ocxl_config_read_function failed rc=%d\n",
> + __func__, rc);
> + goto out;
> + }
> +
> + /* Only one AFU per function is supported by ocxlflash */
> + if (fcfg->max_afu_index != 0)
> + dev_warn(dev, "%s: Unexpected AFU index value %d\n",
> + __func__, fcfg->max_afu_index);
> +out:
> + return rc;
> +}
> +
> +/**
> * ocxlflash_create_afu() - create the AFU for OCXL
> * @pdev: PCI device associated with the host.
> *
> @@ -41,6 +70,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
> {
> struct device *dev = &pdev->dev;
> struct ocxl_hw_afu *afu;
> + int rc;
>
> afu = kzalloc(sizeof(*afu), GFP_KERNEL);
> if (unlikely(!afu)) {
> @@ -50,8 +80,19 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev)
>
> afu->pdev = pdev;
> afu->dev = dev;
> +
> + rc = ocxlflash_config_fn(pdev, afu);
> + if (unlikely(rc)) {
> + dev_err(dev, "%s: Function configuration failed rc=%d\n",
> + __func__, rc);
> + goto err1;
> + }
> out:
> return afu;
> +err1:
> + kfree(afu);
> + afu = NULL;
> + goto out;
> }
>
> /* Backend ops to ocxlflash services */
> diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h
> index c7e5c4d..658f420 100644
> --- a/drivers/scsi/cxlflash/ocxl_hw.h
> +++ b/drivers/scsi/cxlflash/ocxl_hw.h
> @@ -16,4 +16,6 @@
> struct ocxl_hw_afu {
> struct pci_dev *pdev; /* PCI device */
> struct device *dev; /* Generic device */
> +
> + struct ocxl_fn_config fcfg; /* DVSEC config of the function */
> };
>
^ permalink raw reply
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