* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-07-11 5:44 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
Here are a few more powerpc fixes for 3.16
There's a small series of 3 patches that fix saving/restoring MMUCR2
when using KVM without which perf goes completely bonkers in the host
system. Another perf fix from Anton that's been rotting away in patchwork
due to my poor eyesight, a couple of compile fixes, a little addition
to the WSP removal by Michael (removing a bit more dead stuff) and
a fix for an embarassing regression with our soft irq masking.
Cheers,
Ben.
The following changes since commit 6663a4fa6711050036562ddfd2086edf735fae21:
powerpc: Don't skip ePAPR spin-table CPUs (2014-06-25 13:10:49 +1000)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
for you to fetch changes up to f56029410a13cae3652d1f34788045c40a13ffc7:
powerpc/perf: Never program book3s PMCs with values >= 0x80000000 (2014-07-11 13:50:47 +1000)
----------------------------------------------------------------
Anton Blanchard (1):
powerpc/perf: Never program book3s PMCs with values >= 0x80000000
Guenter Roeck (1):
powerpc: Disable RELOCATABLE for COMPILE_TEST with PPC64
Joel Stanley (3):
powerpc/kvm: Remove redundant save of SIER AND MMCR2
powerpc/perf: Add PPMU_ARCH_207S define
powerpc/perf: Clear MMCR2 when enabling PMU
Michael Ellerman (2):
powerpc/cell: Fix compilation with CONFIG_COREDUMP=n
powerpc: Clean up MMU_FTRS_A2 and MMU_FTR_TYPE_3E
Preeti U Murthy (1):
powerpc/powernv: Check for IRQHAPPENED before sleeping
arch/powerpc/Kconfig | 3 ++-
arch/powerpc/include/asm/mmu.h | 10 +---------
arch/powerpc/include/asm/perf_event_server.h | 3 +--
arch/powerpc/kernel/idle_power7.S | 2 +-
arch/powerpc/kvm/book3s_hv_interrupts.S | 5 -----
arch/powerpc/mm/mmu_context_nohash.c | 12 +-----------
arch/powerpc/perf/core-book3s.c | 26 ++++++++++++++++++++++----
arch/powerpc/perf/power8-pmu.c | 2 +-
arch/powerpc/platforms/cell/spu_syscalls.c | 2 ++
arch/powerpc/platforms/cell/spufs/Makefile | 3 ++-
arch/powerpc/platforms/cell/spufs/syscalls.c | 6 ++++--
11 files changed, 37 insertions(+), 37 deletions(-)
^ permalink raw reply
* Re: [RFC][PATCH 1/2] dma: imx-sdma: Add device to device support
From: Nicolin Chen @ 2014-07-11 10:11 UTC (permalink / raw)
To: vinod.koul
Cc: mark.rutland, alsa-devel, linux-doc, tiwai, timur, lgirdwood,
b42378, b02247, grant.likely, devicetree, pawel.moll,
ijc+devicetree, s.hauer, b38343, Nicolin Chen, robh+dt,
dan.j.williams, perex, rdunlap, linux-kernel, broonie, galak,
dmaengine, linuxppc-dev
In-Reply-To: <42744e778ce8a4b424d5642f86d18ef047bcc7cd.1402653667.git.nicoleotsuka@gmail.com>
On Fri, Jun 13, 2014 at 06:07:04PM +0800, Nicolin Chen wrote:
> This patch adds DEV_TO_DEV support for i.MX SDMA driver to support data
> tranfer between two peripheral FIFOs. The per_2_per script requires two
> peripheral addresses and two DMA requests. So this patch also adds them
> into private structure.
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Hi Vinod,
The patch has been here for a month without any comment.
Could you please help on the review or give me an ack?
I really hope my ASRC driver will be merged within this cycle.
Thank you,
Nicolin
> ---
> drivers/dma/imx-sdma.c | 40 ++++++++++++++++++++++++++++++-----
> include/linux/platform_data/dma-imx.h | 1 +
> 2 files changed, 36 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 85561dc..5af1a69 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -258,8 +258,9 @@ struct sdma_channel {
> struct sdma_buffer_descriptor *bd;
> dma_addr_t bd_phys;
> unsigned int pc_from_device, pc_to_device;
> + unsigned int device_to_device;
> unsigned long flags;
> - dma_addr_t per_address;
> + dma_addr_t per_address, per_address2;
> unsigned long event_mask[2];
> unsigned long watermark_level;
> u32 shp_addr, per_addr;
> @@ -696,6 +697,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
>
> sdmac->pc_from_device = 0;
> sdmac->pc_to_device = 0;
> + sdmac->device_to_device = 0;
>
> switch (peripheral_type) {
> case IMX_DMATYPE_MEMORY:
> @@ -770,6 +772,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
>
> sdmac->pc_from_device = per_2_emi;
> sdmac->pc_to_device = emi_2_per;
> + sdmac->device_to_device = per_2_per;
> }
>
> static int sdma_load_context(struct sdma_channel *sdmac)
> @@ -782,11 +785,12 @@ static int sdma_load_context(struct sdma_channel *sdmac)
> int ret;
> unsigned long flags;
>
> - if (sdmac->direction == DMA_DEV_TO_MEM) {
> + if (sdmac->direction == DMA_DEV_TO_MEM)
> load_address = sdmac->pc_from_device;
> - } else {
> + else if (sdmac->direction == DMA_DEV_TO_DEV)
> + load_address = sdmac->device_to_device;
> + else
> load_address = sdmac->pc_to_device;
> - }
>
> if (load_address < 0)
> return load_address;
> @@ -850,6 +854,12 @@ static int sdma_config_channel(struct sdma_channel *sdmac)
> sdma_event_enable(sdmac, sdmac->event_id0);
> }
>
> + if (sdmac->event_id1) {
> + if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
> + return -EINVAL;
> + sdma_event_enable(sdmac, sdmac->event_id1);
> + }
> +
> switch (sdmac->peripheral_type) {
> case IMX_DMATYPE_DSP:
> sdma_config_ownership(sdmac, false, true, true);
> @@ -880,7 +890,12 @@ static int sdma_config_channel(struct sdma_channel *sdmac)
> /* Watermark Level */
> sdmac->watermark_level |= sdmac->watermark_level;
> /* Address */
> - sdmac->shp_addr = sdmac->per_address;
> + if (sdmac->direction == DMA_DEV_TO_DEV) {
> + sdmac->shp_addr = sdmac->per_address2;
> + sdmac->per_addr = sdmac->per_address;
> + } else {
> + sdmac->shp_addr = sdmac->per_address;
> + }
> } else {
> sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
> }
> @@ -974,6 +989,7 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
>
> sdmac->peripheral_type = data->peripheral_type;
> sdmac->event_id0 = data->dma_request;
> + sdmac->event_id1 = data->dma_request2;
>
> clk_enable(sdmac->sdma->clk_ipg);
> clk_enable(sdmac->sdma->clk_ahb);
> @@ -1213,6 +1229,19 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> sdmac->watermark_level = dmaengine_cfg->src_maxburst *
> dmaengine_cfg->src_addr_width;
> sdmac->word_size = dmaengine_cfg->src_addr_width;
> + } else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
> + sdmac->per_address = dmaengine_cfg->src_addr;
> + sdmac->per_address2 = dmaengine_cfg->dst_addr;
> + /*
> + * For per_2_per sciprt, register r7 requires two
> + * watermark levels: the lower placed at bits [0-7]
> + * and the higher one placed at bits [16-23].
> + */
> + sdmac->watermark_level =
> + dmaengine_cfg->src_maxburst & 0xff;
> + sdmac->watermark_level |=
> + (dmaengine_cfg->dst_maxburst & 0xff) << 16;
> + sdmac->word_size = dmaengine_cfg->dst_addr_width;
> } else {
> sdmac->per_address = dmaengine_cfg->dst_addr;
> sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
> @@ -1433,6 +1462,7 @@ static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
> data.dma_request = dma_spec->args[0];
> data.peripheral_type = dma_spec->args[1];
> data.priority = dma_spec->args[2];
> + data.dma_request2 = 0;
>
> return dma_request_channel(mask, sdma_filter_fn, &data);
> }
> diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h
> index 7aa0e89..6a1357d 100644
> --- a/include/linux/platform_data/dma-imx.h
> +++ b/include/linux/platform_data/dma-imx.h
> @@ -51,6 +51,7 @@ enum imx_dma_prio {
>
> struct imx_dma_data {
> int dma_request; /* DMA request line */
> + int dma_request2; /* secondary DMA request line */
> enum sdma_peripheral_type peripheral_type;
> int priority;
> };
> --
> 1.8.4
>
^ permalink raw reply
* [RFC, prePATCH] crypto: talitos modified for powerpc 88x security engine
From: Christophe Leroy @ 2014-07-11 12:09 UTC (permalink / raw)
To: Kim Phillips, Herbert Xu, David S. Miller, Benjamin Herrenschmidt,
Paul Mackerras
Cc: linux-crypto, linuxppc-dev, linux-kernel
Here is a pre-patch for the support of the SEC ENGINE of MPC88x/MPC82xx
I have tried to make use of defines in order to keep a single driver for the two
TALITOS variants as suggested by Kim, but I'm not too happy about the quantity
of #ifdef
For the time being, it only supports basic crypto operations, not the combined
authentication/encryption ones.
Note that it has been tested on MPC885, but not on MPC82xx
I would be happy to receive comments and suggestions in order to improve this
first try.
Not-yet-signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Index: b/drivers/crypto/talitos.c
===================================================================
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -53,10 +53,26 @@
#include "talitos.h"
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+static u8 padded_hash[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#endif
+
static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr)
{
talitos_ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ talitos_ptr->res = 0;
+#else
talitos_ptr->eptr = upper_32_bits(dma_addr);
+#endif
}
/*
@@ -72,7 +88,11 @@
talitos_ptr->len = cpu_to_be16(len);
to_talitos_ptr(talitos_ptr, dma_addr);
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ talitos_ptr->res = 0;
+#else
talitos_ptr->j_extent = extent;
+#endif
}
/*
@@ -91,9 +111,17 @@
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_RESET);
+#else
setbits32(priv->chan[ch].reg + TALITOS_CCCR, TALITOS_CCCR_RESET);
+#endif
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR_LO) & TALITOS_CCCR_LO_RESET)
+#else
while ((in_be32(priv->chan[ch].reg + TALITOS_CCCR) & TALITOS_CCCR_RESET)
+#endif
&& --timeout)
cpu_relax();
@@ -101,10 +129,11 @@
dev_err(dev, "failed to reset channel %d\n", ch);
return -EIO;
}
+dev_err(dev, "success to reset channel %d\n", ch);
/* set 36-bit addressing, done writeback enable and done IRQ enable */
setbits32(priv->chan[ch].reg + TALITOS_CCCR_LO, TALITOS_CCCR_LO_EAE |
- TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
+ TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE /*| TALITOS_CCCR_LO_NT*/);
/* and ICCR writeback, if available */
if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
@@ -169,8 +198,15 @@
}
/* enable channel done and error interrupts */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT);
+ clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
+ /* disable parity error check in DEU because of erroneous? test vectors */
+ setbits32(priv->reg + TALITOS_DEUICR, TALITOS_DEUICR_KPE);
+#else
setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT);
setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
+#endif
/* disable integrity check error interrupts (use writeback instead) */
if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
@@ -228,6 +264,7 @@
/* GO! */
wmb();
+
out_be32(priv->chan[ch].reg + TALITOS_FF,
upper_32_bits(request->dma_desc));
out_be32(priv->chan[ch].reg + TALITOS_FF_LO,
@@ -300,6 +337,7 @@
/*
* process completed requests for channels that have done status
*/
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
#define DEF_TALITOS_DONE(name, ch_done_mask) \
static void talitos_done_##name(unsigned long data) \
{ \
@@ -307,6 +345,33 @@
struct talitos_private *priv = dev_get_drvdata(dev); \
unsigned long flags; \
\
+ if (ch_done_mask & 0x10000000) \
+ flush_channel(dev, 0, 0, 0); \
+ if (priv->num_channels == 1) \
+ goto out; \
+ if (ch_done_mask & 0x40000000) \
+ flush_channel(dev, 1, 0, 0); \
+ if (ch_done_mask & 0x00010000) \
+ flush_channel(dev, 2, 0, 0); \
+ if (ch_done_mask & 0x00040000) \
+ flush_channel(dev, 3, 0, 0); \
+ \
+out: \
+ /* At this point, all completed channels have been processed */ \
+ /* Unmask done interrupts for channels completed later on. */ \
+ spin_lock_irqsave(&priv->reg_lock, flags); \
+ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
+ clrbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+}
+#else
+#define DEF_TALITOS_DONE(name, ch_done_mask) \
+static void talitos_done_##name(unsigned long data) \
+{ \
+ struct device *dev = (struct device *)data; \
+ struct talitos_private *priv = dev_get_drvdata(dev); \
+ unsigned long flags; \
+ \
if (ch_done_mask & 1) \
flush_channel(dev, 0, 0, 0); \
if (priv->num_channels == 1) \
@@ -326,6 +391,7 @@
setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
spin_unlock_irqrestore(&priv->reg_lock, flags); \
}
+#endif
DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE)
@@ -433,13 +499,24 @@
static void talitos_error(struct device *dev, u32 isr, u32 isr_lo)
{
struct talitos_private *priv = dev_get_drvdata(dev);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
unsigned int timeout = TALITOS_TIMEOUT;
+#endif
int ch, error, reset_dev = 0, reset_ch = 0;
u32 v, v_lo;
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ reset_ch = 1;
+#endif
for (ch = 0; ch < priv->num_channels; ch++) {
/* skip channels without errors */
+
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ /* 29 , 31, 17, 19 */
+ if (!(isr & (1 << (29 + (ch & 1) * 2 - (ch & 2) * 6))))
+#else
if (!(isr & (1 << (ch * 2 + 1))))
+#endif
continue;
error = -EINVAL;
@@ -447,6 +524,14 @@
v = in_be32(priv->chan[ch].reg + TALITOS_CCPSR);
v_lo = in_be32(priv->chan[ch].reg + TALITOS_CCPSR_LO);
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ if (v_lo & TALITOS_CCPSR_LO_TEA)
+ dev_err(dev, "master data transfer error\n");
+ if (v_lo & TALITOS_CCPSR_LO_PNC)
+ dev_err(dev, "pointeur not complete error\n");
+ if (v_lo & TALITOS_CCPSR_LO_PAR)
+ dev_err(dev, "parity error\n");
+#else
if (v_lo & TALITOS_CCPSR_LO_DOF) {
dev_err(dev, "double fetch fifo overflow error\n");
error = -EAGAIN;
@@ -463,12 +548,19 @@
dev_err(dev, "s/g data length zero error\n");
if (v_lo & TALITOS_CCPSR_LO_FPZ)
dev_err(dev, "fetch pointer zero error\n");
+#endif
if (v_lo & TALITOS_CCPSR_LO_IDH)
dev_err(dev, "illegal descriptor header error\n");
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ if (v_lo & TALITOS_CCPSR_LO_SA)
+ dev_err(dev, "static assignment error\n");
+#else
if (v_lo & TALITOS_CCPSR_LO_IEU)
dev_err(dev, "invalid execution unit error\n");
+#endif
if (v_lo & TALITOS_CCPSR_LO_EU)
report_eu_error(dev, ch, current_desc_hdr(dev, ch));
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
if (v_lo & TALITOS_CCPSR_LO_GB)
dev_err(dev, "gather boundary error\n");
if (v_lo & TALITOS_CCPSR_LO_GRL)
@@ -477,9 +569,13 @@
dev_err(dev, "scatter boundary error\n");
if (v_lo & TALITOS_CCPSR_LO_SRL)
dev_err(dev, "scatter return/length error\n");
+#endif
flush_channel(dev, ch, error, reset_ch);
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ reset_channel(dev, ch);
+#else
if (reset_ch) {
reset_channel(dev, ch);
} else {
@@ -495,10 +591,17 @@
reset_dev = 1;
}
}
+#endif
}
if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) {
- dev_err(dev, "done overflow, internal time out, or rngu error: "
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ if (isr_lo & TALITOS_ISR_TEA_ERR)
+ dev_err(dev, "TEA error: "
"ISR 0x%08x_%08x\n", isr, isr_lo);
+ else
+#endif
+ dev_err(dev, "done overflow, internal time out, or rngu error: "
+ "ISR 0x%08x_%08x\n", isr, isr_lo);
/* purge request queues */
for (ch = 0; ch < priv->num_channels; ch++)
@@ -509,6 +612,7 @@
}
}
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
#define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
{ \
@@ -523,7 +627,39 @@
/* Acknowledge interrupt */ \
out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
+ if (unlikely(isr & ch_err_mask || isr_lo & TALITOS_IMR_LO_INIT)) { \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ talitos_error(dev, isr & ch_err_mask, isr_lo); \
+ } \
+ else { \
+ if (likely(isr & ch_done_mask)) { \
+ /* mask further done interrupts. */ \
+ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
+ /* done_task will unmask done interrupts at exit */ \
+ tasklet_schedule(&priv->done_task[tlet]); \
+ } \
+ spin_unlock_irqrestore(&priv->reg_lock, flags); \
+ } \
\
+ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
+ IRQ_NONE; \
+}
+#else
+#define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
+static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
+{ \
+ struct device *dev = data; \
+ struct talitos_private *priv = dev_get_drvdata(dev); \
+ u32 isr, isr_lo; \
+ unsigned long flags; \
+ \
+ spin_lock_irqsave(&priv->reg_lock, flags); \
+ isr = in_be32(priv->reg + TALITOS_ISR); \
+ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
+ /* Acknowledge interrupt */ \
+ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
+ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
+ \
if (unlikely(isr & ch_err_mask || isr_lo)) { \
spin_unlock_irqrestore(&priv->reg_lock, flags); \
talitos_error(dev, isr & ch_err_mask, isr_lo); \
@@ -541,6 +677,7 @@
return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
IRQ_NONE; \
}
+#endif
DEF_TALITOS_INTERRUPT(4ch, TALITOS_ISR_4CHDONE, TALITOS_ISR_4CHERR, 0)
DEF_TALITOS_INTERRUPT(ch0_2, TALITOS_ISR_CH_0_2_DONE, TALITOS_ISR_CH_0_2_ERR, 0)
DEF_TALITOS_INTERRUPT(ch1_3, TALITOS_ISR_CH_1_3_DONE, TALITOS_ISR_CH_1_3_ERR, 1)
@@ -638,6 +775,10 @@
unsigned int enckeylen;
unsigned int authkeylen;
unsigned int authsize;
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ u8 *ptr_in;
+ u8 *ptr_out;
+#endif
};
#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
@@ -646,7 +787,7 @@
struct talitos_ahash_req_ctx {
u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
unsigned int hw_context_size;
- u8 buf[HASH_MAX_BLOCK_SIZE];
+ u8 buf[4096];
u8 bufnext[HASH_MAX_BLOCK_SIZE];
unsigned int swinit;
unsigned int first;
@@ -657,6 +798,7 @@
struct scatterlist *psrc;
};
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
static int aead_setauthsize(struct crypto_aead *authenc,
unsigned int authsize)
{
@@ -711,6 +853,7 @@
crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
+#endif
/*
* talitos_edesc - s/w-extended descriptor
@@ -796,6 +939,7 @@
dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
}
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
static void ipsec_esp_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct aead_request *areq)
@@ -1091,6 +1235,7 @@
}
return ret;
}
+#endif
/*
* derive number of elements in scatterlist
@@ -1213,6 +1358,7 @@
return edesc;
}
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, u8 *iv,
int icv_stashing)
{
@@ -1315,6 +1461,7 @@
return ipsec_esp(edesc, areq, req->seq, ipsec_esp_encrypt_done);
}
+#endif
static int ablkcipher_setkey(struct crypto_ablkcipher *cipher,
const u8 *key, unsigned int keylen)
@@ -1331,7 +1478,21 @@
struct talitos_edesc *edesc,
struct ablkcipher_request *areq)
{
+ struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
+ struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE);
+ if (ctx->ptr_out) {
+ unsigned int cryptlen = areq->nbytes;
+
+ sg_copy_from_buffer(areq->dst, edesc->dst_nents ? : 1, ctx->ptr_out, cryptlen);
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[4], DMA_FROM_DEVICE);
+ kfree(ctx->ptr_out);
+ }
+ if (ctx->ptr_in) {
+ unmap_single_talitos_ptr(dev, &edesc->desc.ptr[3], DMA_TO_DEVICE);
+ kfree(ctx->ptr_in);
+ }
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], DMA_TO_DEVICE);
@@ -1375,13 +1536,16 @@
/* first DWORD empty */
desc->ptr[0].len = 0;
to_talitos_ptr(&desc->ptr[0], 0);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[0].j_extent = 0;
+#endif
/* cipher iv */
to_talitos_ptr(&desc->ptr[1], edesc->iv_dma);
desc->ptr[1].len = cpu_to_be16(ivsize);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[1].j_extent = 0;
-
+#endif
/* cipher key */
map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
(char *)&ctx->key, 0, DMA_TO_DEVICE);
@@ -1390,7 +1554,9 @@
* cipher in
*/
desc->ptr[3].len = cpu_to_be16(cryptlen);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[3].j_extent = 0;
+#endif
sg_count = talitos_map_sg(dev, areq->src, edesc->src_nents ? : 1,
(areq->src == areq->dst) ? DMA_BIDIRECTIONAL
@@ -1398,8 +1564,17 @@
edesc->src_chained);
if (sg_count == 1) {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ ctx->ptr_in = NULL;
+#endif
to_talitos_ptr(&desc->ptr[3], sg_dma_address(areq->src));
} else {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ ctx->ptr_in = kzalloc(cryptlen, GFP_DMA);
+ sg_copy_to_buffer(areq->src, sg_count, ctx->ptr_in, cryptlen);
+ map_single_talitos_ptr(dev, &desc->ptr[3], cryptlen,
+ (char *)ctx->ptr_in, 0, DMA_TO_DEVICE);
+#else
sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
&edesc->link_tbl[0]);
if (sg_count > 1) {
@@ -1412,12 +1587,17 @@
/* Only one segment now, so no link tbl needed */
to_talitos_ptr(&desc->ptr[3],
sg_dma_address(areq->src));
+#endif
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
}
+#endif
}
/* cipher out */
desc->ptr[4].len = cpu_to_be16(cryptlen);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[4].j_extent = 0;
+#endif
if (areq->src != areq->dst)
sg_count = talitos_map_sg(dev, areq->dst,
@@ -1425,8 +1605,16 @@
DMA_FROM_DEVICE, edesc->dst_chained);
if (sg_count == 1) {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ ctx->ptr_out = NULL;
+#endif
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->dst));
} else {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ ctx->ptr_out = kzalloc(cryptlen, GFP_DMA);
+ map_single_talitos_ptr(dev, &desc->ptr[4], cryptlen,
+ (char *)ctx->ptr_out, 0, DMA_FROM_DEVICE);
+#else
struct talitos_ptr *link_tbl_ptr =
&edesc->link_tbl[edesc->src_nents + 1];
@@ -1438,6 +1626,7 @@
link_tbl_ptr);
dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
+#endif
}
/* iv out */
@@ -1447,7 +1636,12 @@
/* last DWORD empty */
desc->ptr[6].len = 0;
to_talitos_ptr(&desc->ptr[6], 0);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[6].j_extent = 0;
+#endif
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ desc->next_desc = 0;
+#endif
ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
if (ret != -EINPROGRESS) {
@@ -1578,9 +1772,10 @@
}
/* HMAC key */
- if (ctx->keylen)
+ if (ctx->keylen) {
map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen,
(char *)&ctx->key, 0, DMA_TO_DEVICE);
+ }
else
desc->ptr[2] = zero_entry;
@@ -1588,7 +1783,9 @@
* data in
*/
desc->ptr[3].len = cpu_to_be16(length);
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
desc->ptr[3].j_extent = 0;
+#endif
sg_count = talitos_map_sg(dev, req_ctx->psrc,
edesc->src_nents ? : 1,
@@ -1597,6 +1794,7 @@
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[3], sg_dma_address(req_ctx->psrc));
} else {
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
sg_count = sg_to_link_tbl(req_ctx->psrc, sg_count, length,
&edesc->link_tbl[0]);
if (sg_count > 1) {
@@ -1611,6 +1809,7 @@
to_talitos_ptr(&desc->ptr[3],
sg_dma_address(req_ctx->psrc));
}
+#endif
}
/* fifth DWORD empty */
@@ -1628,7 +1827,22 @@
/* last DWORD empty */
desc->ptr[6] = zero_entry;
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ desc->next_desc = 0;
+#endif
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ /*
+ * SEC1 doesn't like hashing of 0 sized message, so we do the padding
+ * ourself and submit a padded block
+ */
+ if (desc->ptr[3].len == 0) {
+ pr_err_once("Bug in SEC1, padding ourself\n");
+ edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
+ map_single_talitos_ptr(dev, &desc->ptr[3], sizeof(padded_hash),
+ (char *)padded_hash, 0, DMA_TO_DEVICE);
+ }
+#endif
ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
if (ret != -EINPROGRESS) {
common_nonsnoop_hash_unmap(dev, edesc, areq);
@@ -1702,7 +1916,10 @@
crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
unsigned int nbytes_to_hash;
unsigned int to_hash_later;
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
unsigned int nsg;
+#endif
+ int nents;
bool chained;
if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
@@ -1730,6 +1947,16 @@
}
/* Chain in any previously buffered data */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ if ((nents = sg_count(areq->src, nbytes, &chained)) > 1 || req_ctx->nbuf) {
+ sg_copy_to_buffer(areq->src, nents,
+ req_ctx->buf + req_ctx->nbuf,
+ nbytes_to_hash - req_ctx->nbuf);
+ sg_init_one(req_ctx->bufsl, req_ctx->buf, nbytes_to_hash);
+ req_ctx->psrc = req_ctx->bufsl;
+ } else
+ req_ctx->psrc = areq->src;
+#else
if (req_ctx->nbuf) {
nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
sg_init_table(req_ctx->bufsl, nsg);
@@ -1739,9 +1966,9 @@
req_ctx->psrc = req_ctx->bufsl;
} else
req_ctx->psrc = areq->src;
-
+#endif
if (to_hash_later) {
- int nents = sg_count(areq->src, nbytes, &chained);
+ nents = sg_count(areq->src, nbytes, &chained);
sg_pcopy_to_buffer(areq->src, nents,
req_ctx->bufnext,
to_hash_later,
@@ -2407,6 +2634,7 @@
return 0;
}
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
static int talitos_cra_init_aead(struct crypto_tfm *tfm)
{
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
@@ -2418,6 +2646,7 @@
return 0;
}
+#endif
static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
{
@@ -2524,6 +2753,7 @@
alg->cra_ablkcipher.decrypt = ablkcipher_decrypt;
alg->cra_ablkcipher.geniv = "eseqiv";
break;
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
case CRYPTO_ALG_TYPE_AEAD:
alg = &t_alg->algt.alg.crypto;
alg->cra_init = talitos_cra_init_aead;
@@ -2535,6 +2765,7 @@
alg->cra_aead.givencrypt = aead_givencrypt;
alg->cra_aead.geniv = "<built-in>";
break;
+#endif
case CRYPTO_ALG_TYPE_AHASH:
alg = &t_alg->algt.alg.hash.halg.base;
alg->cra_init = talitos_cra_init_ahash;
@@ -2698,6 +2929,9 @@
TALITOS_FTR_SHA224_HWINIT |
TALITOS_FTR_HMAC_OK;
+ if (of_device_is_compatible(np, "fsl,sec1.2"))
+ priv->features |= TALITOS_FTR_HMAC_OK;
+
priv->chan = kzalloc(sizeof(struct talitos_channel) *
priv->num_channels, GFP_KERNEL);
if (!priv->chan) {
@@ -2801,9 +3035,15 @@
}
static const struct of_device_id talitos_match[] = {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
{
+ .compatible = "fsl,sec1.0",
+ },
+#else
+ {
.compatible = "fsl,sec2.0",
},
+#endif
{},
};
MODULE_DEVICE_TABLE(of, talitos_match);
Index: b/drivers/crypto/talitos.h
===================================================================
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -28,8 +28,16 @@
*
*/
+#if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC_82xx)
+#define CONFIG_CRYPTO_DEV_TALITOS1
+#endif
+
#define TALITOS_TIMEOUT 100000
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_MAX_DATA_LEN 32768
+#else
#define TALITOS_MAX_DATA_LEN 65535
+#endif
#define DESC_TYPE(desc_hdr) ((be32_to_cpu(desc_hdr) >> 3) & 0x1f)
#define PRIMARY_EU(desc_hdr) ((be32_to_cpu(desc_hdr) >> 28) & 0xf)
@@ -37,24 +45,39 @@
/* descriptor pointer entry */
struct talitos_ptr {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ __be16 res; /* reserved */
__be16 len; /* length */
+ __be32 ptr; /* address */
+#else
+ __be16 len; /* length */
u8 j_extent; /* jump to sg link table and/or extent */
u8 eptr; /* extended address */
__be32 ptr; /* address */
+#endif
};
static const struct talitos_ptr zero_entry = {
.len = 0,
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ .res = 0,
+#else
.j_extent = 0,
.eptr = 0,
+#endif
.ptr = 0
};
/* descriptor */
struct talitos_desc {
__be32 hdr; /* header high bits */
+#ifndef CONFIG_CRYPTO_DEV_TALITOS1
__be32 hdr_lo; /* header low bits */
+#endif
struct talitos_ptr ptr[7]; /* ptr/len pair array */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+ __be32 next_desc;
+#endif
};
/**
@@ -155,42 +178,84 @@
#define TALITOS_MCR_RCA1 (1 << 14) /* remap channel 1 */
#define TALITOS_MCR_RCA2 (1 << 13) /* remap channel 2 */
#define TALITOS_MCR_RCA3 (1 << 12) /* remap channel 3 */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_MCR_SWR 0x01000000 /* s/w reset */
+#else
#define TALITOS_MCR_SWR 0x1 /* s/w reset */
+#endif
#define TALITOS_MCR_LO 0x1034
#define TALITOS_IMR 0x1008 /* interrupt mask register */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_IMR_INIT 0xf00f0000 /* enable channel IRQs */
+#define TALITOS_IMR_DONE 0x50050000 /* done IRQs */
+#else
#define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */
#define TALITOS_IMR_DONE 0x00055 /* done IRQs */
+#endif
#define TALITOS_IMR_LO 0x100C
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_IMR_LO_INIT 0x2000000 /* allow RNGU error IRQs */
+#else
#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */
+#endif
#define TALITOS_ISR 0x1010 /* interrupt status register */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_ISR_4CHERR 0xa00a0000 /* 4 channel errors mask */
+#define TALITOS_ISR_4CHDONE 0x50050000 /* 4 channel done mask */
+#define TALITOS_ISR_CH_0_2_ERR 0x20020000 /* channels 0, 2 errors mask */
+#define TALITOS_ISR_CH_0_2_DONE 0x10010000 /* channels 0, 2 done mask */
+#define TALITOS_ISR_CH_1_3_ERR 0x80080000 /* channels 1, 3 errors mask */
+#define TALITOS_ISR_CH_1_3_DONE 0x40040000 /* channels 1, 3 done mask */
+#define TALITOS_ISR_TEA_ERR 0x00000040
+#else
#define TALITOS_ISR_4CHERR 0xaa /* 4 channel errors mask */
#define TALITOS_ISR_4CHDONE 0x55 /* 4 channel done mask */
#define TALITOS_ISR_CH_0_2_ERR 0x22 /* channels 0, 2 errors mask */
#define TALITOS_ISR_CH_0_2_DONE 0x11 /* channels 0, 2 done mask */
#define TALITOS_ISR_CH_1_3_ERR 0x88 /* channels 1, 3 errors mask */
#define TALITOS_ISR_CH_1_3_DONE 0x44 /* channels 1, 3 done mask */
+#endif
#define TALITOS_ISR_LO 0x1014
#define TALITOS_ICR 0x1018 /* interrupt clear register */
#define TALITOS_ICR_LO 0x101C
/* channel register address stride */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
#define TALITOS_CH_BASE_OFFSET 0x1000 /* default channel map base */
+#define TALITOS_CH_STRIDE 0x1000
+#else
+#define TALITOS_CH_BASE_OFFSET 0x1000 /* default channel map base */
#define TALITOS_CH_STRIDE 0x100
+#endif
/* channel configuration register */
#define TALITOS_CCCR 0x8
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#else
#define TALITOS_CCCR_CONT 0x2 /* channel continue */
#define TALITOS_CCCR_RESET 0x1 /* channel reset */
+#endif
#define TALITOS_CCCR_LO 0xc
#define TALITOS_CCCR_LO_IWSE 0x80 /* chan. ICCR writeback enab. */
#define TALITOS_CCCR_LO_EAE 0x20 /* extended address enable */
#define TALITOS_CCCR_LO_CDWE 0x10 /* chan. done writeback enab. */
#define TALITOS_CCCR_LO_NT 0x4 /* notification type */
#define TALITOS_CCCR_LO_CDIE 0x2 /* channel done IRQ enable */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_CCCR_LO_RESET 0x1 /* channel reset */
+#endif
/* CCPSR: channel pointer status register */
#define TALITOS_CCPSR 0x10
#define TALITOS_CCPSR_LO 0x14
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_CCPSR_LO_TEA 0x2000 /* master data transfer error */
+#define TALITOS_CCPSR_LO_PNC 0x1000 /* pointeur not complete error */
+#define TALITOS_CCPSR_LO_PAR 0x0800 /* parity error */
+#define TALITOS_CCPSR_LO_IDH 0x0400 /* illegal desc hdr error */
+#define TALITOS_CCPSR_LO_SA 0x0200 /* static assignment error */
+#define TALITOS_CCPSR_LO_EU 0x0100 /* EU error detected */
+#else
#define TALITOS_CCPSR_LO_DOF 0x8000 /* double FF write oflow error */
#define TALITOS_CCPSR_LO_SOF 0x4000 /* single FF write oflow error */
#define TALITOS_CCPSR_LO_MDTE 0x2000 /* master data transfer error */
@@ -203,6 +268,7 @@
#define TALITOS_CCPSR_LO_GRL 0x0040 /* gather return/length error */
#define TALITOS_CCPSR_LO_SB 0x0020 /* scatter boundary error */
#define TALITOS_CCPSR_LO_SRL 0x0010 /* scatter return/length error */
+#endif
/* channel fetch fifo register */
#define TALITOS_FF 0x48
@@ -225,8 +291,16 @@
#define TALITOS_SCATTER_LO 0xe4
/* execution unit interrupt status registers */
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+#define TALITOS_DEUISR 0x5030 /* DES unit */
+#define TALITOS_DEUISR_LO 0x5034
+#define TALITOS_DEUICR 0x5038 /* interrupt control */
+#define TALITOS_DEUICR_KPE 0x00200000 /* Key Parity Error */
+#else
#define TALITOS_DEUISR 0x2030 /* DES unit */
#define TALITOS_DEUISR_LO 0x2034
+#endif
+
#define TALITOS_AESUISR 0x4030 /* AES unit */
#define TALITOS_AESUISR_LO 0x4034
#define TALITOS_MDEUISR 0x6030 /* message digest unit */
@@ -234,6 +308,7 @@
#define TALITOS_MDEUICR 0x6038 /* interrupt control */
#define TALITOS_MDEUICR_LO 0x603c
#define TALITOS_MDEUICR_LO_ICE 0x4000 /* integrity check IRQ enable */
+
#define TALITOS_AFEUISR 0x8030 /* arc4 unit */
#define TALITOS_AFEUISR_LO 0x8034
#define TALITOS_RNGUISR 0xa030 /* random number unit */
^ permalink raw reply
* Re: [PATCH tty-next 14/22] tty: Remove tty_wait_until_sent_from_close()
From: Peter Hurley @ 2014-07-11 15:03 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: One Thousand Gnomes, Karsten Keil, linuxppc-dev, linux-kernel,
linux-serial
In-Reply-To: <20140710230936.GA31181@kroah.com>
On 07/10/2014 07:09 PM, Greg Kroah-Hartman wrote:
> On Mon, Jun 16, 2014 at 09:17:11AM -0400, Peter Hurley wrote:
>> tty_wait_until_sent_from_close() drops the tty lock while waiting
>> for the tty driver to finish sending previously accepted data (ie.,
>> data remaining in its write buffer and transmit fifo).
>>
>> However, dropping the tty lock is a hold-over from when the tty
>> lock was system-wide; ie., one lock for all ttys.
>>
>> Since commit 89c8d91e31f267703e365593f6bfebb9f6d2ad01,
>> 'tty: localise the lock', dropping the tty lock has not been necessary.
>>
>> CC: Karsten Keil <isdn@linux-pingi.de>
>> CC: linuxppc-dev@lists.ozlabs.org
>> Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
>> ---
>> drivers/isdn/i4l/isdn_tty.c | 2 +-
>> drivers/tty/hvc/hvc_console.c | 2 +-
>> drivers/tty/hvc/hvcs.c | 2 +-
>> drivers/tty/tty_port.c | 11 ++---------
>> include/linux/tty.h | 18 ------------------
>> 5 files changed, 5 insertions(+), 30 deletions(-)
>
> I've applied the first 13 patches in this series, as it looks like you
> were going to split things up from here, right?
Yes, thanks for doing that.
> Can you refresh these and resend when you have that done?
Unfortunately, that probably won't be until after the 3.17 merge window,
for 3.18. The tty_open() rework is not trivial and there is an issue
with the ldisc flush removal patch.
I'm hoping to include the tty flow control fixes with that stuff as well.
Regards,
Peter Hurley
^ permalink raw reply
* Re: Fwd: Fwd: Allyesconfig for powerpc still Failing
From: Nick Krause @ 2014-07-12 3:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Guenter Roeck
Cc: mahesh, Alexander Graf, linux-kernel@vger.kernel.org,
Michael Ellerman, paulus, Anton Blanchard, linuxppc-dev
In-Reply-To: <1404798135.16156.50.camel@pasglop>
[-- Attachment #1: Type: text/plain, Size: 1641 bytes --]
>> > Guenter Roeck wrote on Mon, Jul 7, 2014 at 11:07 PM
>> > I submitted a patch to work around this problem a couple of weeks ago [1].
>> > Unfortunately, with this patch applied, allyesconfig still fails with
>> > relocation errors, but at least the above message is gone, and
>> > allmodconfig passes.
>> >
>> > Maybe we can convince Ben to accept the patch ...
>> >
>> > Thanks,
>> > Guenter
>> >
>> > ---
>> > [1] https://lkml.org/lkml/2014/6/30/607
>> >
>> > Hey Guenter,
>> > Would you mind sending me the patch that fixes these errors.
>> > I would like to test it before sending in to Ben.
>> > Cheers Nick
>> >
>>
>> Hi Nick,
>>
>> Just follow the link above, select 'forward', and follow the directions.
>> You'll get the patch per e-mail.
>>
>> Alternative:
>>
>> wget "http://download.gmane.org/gmane.linux.kernel/1736036/1736037"
>>
>> The patch will be in a file named '1736037'.
>>
>> I copied the list for others, in case the 'how to download a patch'
>> question comes up again.
>>
>> Guenter
>>
>> Guenter,
>> Your patch works for me in building the powerpc allyesconfig.
>> This is one news, I am going to send this patch to Ben.
>> Cheers Nick
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
>
>
Powerpc allyesconfig seems to be succeeding as of me pulling upstream
today. On the other hand I get one
randconfig build to succeed and the second fails. I will attach my log
of the failing build.
Cheers Nick
[-- Attachment #2: randconfig2 --]
[-- Type: application/octet-stream, Size: 2031 bytes --]
warning: (USB_OTG_FSM && FSL_USB2_OTG && USB_MV_OTG) selects USB_OTG which has unmet direct dependencies (USB_SUPPORT && USB && PM_RUNTIME)
warning: (MPC836x_RDK && MTD_NAND_FSL_ELBC && MTD_NAND_FSL_UPM) selects FSL_LBC which has unmet direct dependencies (FSL_SOC)
warning: (USB_OTG_FSM && FSL_USB2_OTG && USB_MV_OTG) selects USB_OTG which has unmet direct dependencies (USB_SUPPORT && USB && PM_RUNTIME)
warning: (MPC836x_RDK && MTD_NAND_FSL_ELBC && MTD_NAND_FSL_UPM) selects FSL_LBC which has unmet direct dependencies (FSL_SOC)
powerpc64-linux-gnu-ld: unrecognised emulation mode: elf64lppc
Supported emulations: elf64ppc elf32ppclinux elf32ppc elf32ppcsim
make[1]: *** [usr/built-in.o] Error 1
make: *** [usr] Error 2
make: *** Waiting for unfinished jobs....
powerpc64-linux-gnu-ld: unrecognised emulation mode: elf64lppc
Supported emulations: elf64ppc elf32ppclinux elf32ppc elf32ppcsim
make[1]: *** [init/mounts.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [init] Error 2
/usr/lib/gcc/powerpc64-linux-gnu/4.8.1/../../../../powerpc64-linux-gnu/bin/ld: unrecognised emulation mode: elf32lppclinux
Supported emulations: elf64ppc elf32ppclinux elf32ppc elf32ppcsim
collect2: error: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso32/vdso32.so.dbg] Error 1
make[1]: *** [arch/powerpc/kernel/vdso32] Error 2
make[1]: *** Waiting for unfinished jobs....
powerpc64-linux-gnu-ld: unrecognised emulation mode: elf64lppc
Supported emulations: elf64ppc elf32ppclinux elf32ppc elf32ppcsim
make[1]: *** [arch/powerpc/mm/built-in.o] Error 1
make: *** [arch/powerpc/mm] Error 2
/usr/lib/gcc/powerpc64-linux-gnu/4.8.1/../../../../powerpc64-linux-gnu/bin/ld: unrecognised emulation mode: elf64lppc
Supported emulations: elf64ppc elf32ppclinux elf32ppc elf32ppcsim
collect2: error: ld returned 1 exit status
make[2]: *** [arch/powerpc/kernel/vdso64/vdso64.so.dbg] Error 1
make[1]: *** [arch/powerpc/kernel/vdso64] Error 2
make: *** [arch/powerpc/kernel] Error 2
make: *** wait: No child processes. Stop.
^ permalink raw reply
* [PATCH 1/2] PCI/MSI/PPC: Remove arch_msi_check_device()
From: Alexander Gordeev @ 2014-07-12 11:21 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-pci, Alexander Gordeev, linuxppc-dev
In-Reply-To: <cover.1405160163.git.agordeev@redhat.com>
PowerPC is the only architecture that makes use of hook
arch_msi_check_device() and does perform some checks to
figure out if MSI/MSI-X could be enabled for a device.
However, there are no reasons why those checks could not
be done within arch_setup_msi_irqs() hook.
Moving MSI checks into arch_setup_msi_irqs() makes code
more readable and allows getting rid of unnecessary hook
arch_msi_check_device().
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-pci@vger.kernel.org
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
arch/powerpc/include/asm/machdep.h | 2 -
arch/powerpc/kernel/msi.c | 12 +--------
arch/powerpc/platforms/cell/axon_msi.c | 9 -------
arch/powerpc/platforms/powernv/pci.c | 19 ++++----------
arch/powerpc/platforms/pseries/msi.c | 42 ++++++++++++-------------------
arch/powerpc/sysdev/fsl_msi.c | 12 ++-------
arch/powerpc/sysdev/mpic_pasemi_msi.c | 11 +-------
arch/powerpc/sysdev/mpic_u3msi.c | 28 ++++++++-------------
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 18 ++++---------
arch/powerpc/sysdev/ppc4xx_msi.c | 19 ++++----------
10 files changed, 50 insertions(+), 122 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index f92b0b5..d05aa76 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -136,8 +136,6 @@ struct machdep_calls {
int (*pci_setup_phb)(struct pci_controller *host);
#ifdef CONFIG_PCI_MSI
- int (*msi_check_device)(struct pci_dev* dev,
- int nvec, int type);
int (*setup_msi_irqs)(struct pci_dev *dev,
int nvec, int type);
void (*teardown_msi_irqs)(struct pci_dev *dev);
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 8bbc12d..71bd161 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@
#include <asm/machdep.h>
-int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
@@ -24,16 +24,6 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;
- if (ppc_md.msi_check_device) {
- pr_debug("msi: Using platform check routine.\n");
- return ppc_md.msi_check_device(dev, nvec, type);
- }
-
- return 0;
-}
-
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
return ppc_md.setup_msi_irqs(dev, nvec, type);
}
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 85825b5..862b327 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -199,14 +199,6 @@ out_error:
return msic;
}
-static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type)
-{
- if (!find_msi_translator(dev))
- return -ENODEV;
-
- return 0;
-}
-
static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
{
struct device_node *dn;
@@ -416,7 +408,6 @@ static int axon_msi_probe(struct platform_device *device)
ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
- ppc_md.msi_check_device = axon_msi_check_device;
axon_msi_debug_setup(dn, msic);
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index f91a4e5..987b677 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -46,29 +46,21 @@
//#define cfg_dbg(fmt...) printk(fmt)
#ifdef CONFIG_PCI_MSI
-static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
-{
- struct pci_controller *hose = pci_bus_to_host(pdev->bus);
- struct pnv_phb *phb = hose->private_data;
- struct pci_dn *pdn = pci_get_pdn(pdev);
-
- if (pdn && pdn->force_32bit_msi && !phb->msi32_support)
- return -ENODEV;
-
- return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV;
-}
-
static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
{
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
struct pnv_phb *phb = hose->private_data;
+ struct pci_dn *pdn = pci_get_pdn(pdev);
struct msi_desc *entry;
struct msi_msg msg;
int hwirq;
unsigned int virq;
int rc;
- if (WARN_ON(!phb))
+ if (WARN_ON(!phb) || !phb->msi_bmp.bitmap)
+ return -ENODEV;
+
+ if (pdn && pdn->force_32bit_msi && !phb->msi32_support)
return -ENODEV;
list_for_each_entry(entry, &pdev->msi_list, list) {
@@ -810,7 +802,6 @@ void __init pnv_pci_init(void)
/* Configure MSIs */
#ifdef CONFIG_PCI_MSI
- ppc_md.msi_check_device = pnv_msi_check_device;
ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
#endif
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 0c882e8..24494fc 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -335,26 +335,6 @@ out:
return request;
}
-static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- int quota, rc;
-
- if (type == PCI_CAP_ID_MSIX)
- rc = check_req_msix(pdev, nvec);
- else
- rc = check_req_msi(pdev, nvec);
-
- if (rc)
- return rc;
-
- quota = msi_quota_for_device(pdev, nvec);
-
- if (quota && quota < nvec)
- return quota;
-
- return 0;
-}
-
static int check_msix_entries(struct pci_dev *pdev)
{
struct msi_desc *entry;
@@ -396,15 +376,24 @@ static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
{
struct pci_dn *pdn;
- int hwirq, virq, i, rc;
+ int hwirq, virq, i, quota, rc;
struct msi_desc *entry;
struct msi_msg msg;
int nvec = nvec_in;
int use_32bit_msi_hack = 0;
- pdn = pci_get_pdn(pdev);
- if (!pdn)
- return -ENODEV;
+ if (type == PCI_CAP_ID_MSIX)
+ rc = check_req_msix(pdev, nvec);
+ else
+ rc = check_req_msi(pdev, nvec);
+
+ if (rc)
+ return rc;
+
+ quota = msi_quota_for_device(pdev, nvec);
+
+ if (quota && quota < nvec)
+ return quota;
if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
return -EINVAL;
@@ -415,12 +404,14 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
*/
if (type == PCI_CAP_ID_MSIX) {
int m = roundup_pow_of_two(nvec);
- int quota = msi_quota_for_device(pdev, m);
+ quota = msi_quota_for_device(pdev, m);
if (quota >= m)
nvec = m;
}
+ pdn = pci_get_pdn(pdev);
+
/*
* Try the new more explicit firmware interface, if that fails fall
* back to the old interface. The old interface is known to never
@@ -525,7 +516,6 @@ static int rtas_msi_init(void)
WARN_ON(ppc_md.setup_msi_irqs);
ppc_md.setup_msi_irqs = rtas_setup_msi_irqs;
ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs;
- ppc_md.msi_check_device = rtas_msi_check_device;
WARN_ON(ppc_md.pci_irq_fixup);
ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 77efbae..b32e79d 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -109,14 +109,6 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
return 0;
}
-static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
-
- return 0;
-}
-
static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
@@ -173,6 +165,9 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
struct msi_msg msg;
struct fsl_msi *msi_data;
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+
/*
* If the PCI node has an fsl,msi property, then we need to use it
* to find the specific MSI.
@@ -527,7 +522,6 @@ static int fsl_of_msi_probe(struct platform_device *dev)
if (!ppc_md.setup_msi_irqs) {
ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
- ppc_md.msi_check_device = fsl_msi_check_device;
} else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
dev_err(&dev->dev, "Different MSI driver already installed!\n");
err = -ENODEV;
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 38e6238..15dccd3 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -63,14 +63,6 @@ static struct irq_chip mpic_pasemi_msi_chip = {
.name = "PASEMI-MSI",
};
-static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("pasemi_msi: MSI-X untested, trying anyway\n");
-
- return 0;
-}
-
static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
@@ -97,6 +89,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
struct msi_msg msg;
int hwirq;
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("pasemi_msi: MSI-X untested, trying anyway\n");
pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
pdev, nvec, type);
@@ -169,7 +163,6 @@ int mpic_pasemi_msi_init(struct mpic *mpic)
WARN_ON(ppc_md.setup_msi_irqs);
ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
- ppc_md.msi_check_device = pasemi_msi_check_device;
return 0;
}
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index 9a7aa0e..623d7fb 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -105,22 +105,6 @@ static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
return 0;
}
-static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("u3msi: MSI-X untested, trying anyway.\n");
-
- /* If we can't find a magic address then MSI ain't gonna work */
- if (find_ht_magic_addr(pdev, 0) == 0 &&
- find_u4_magic_addr(pdev, 0) == 0) {
- pr_debug("u3msi: no magic address found for %s\n",
- pci_name(pdev));
- return -ENXIO;
- }
-
- return 0;
-}
-
static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;
@@ -146,6 +130,17 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
u64 addr;
int hwirq;
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("u3msi: MSI-X untested, trying anyway.\n");
+
+ /* If we can't find a magic address then MSI ain't gonna work */
+ if (find_ht_magic_addr(pdev, 0) == 0 &&
+ find_u4_magic_addr(pdev, 0) == 0) {
+ pr_debug("u3msi: no magic address found for %s\n",
+ pci_name(pdev));
+ return -ENXIO;
+ }
+
list_for_each_entry(entry, &pdev->msi_list, list) {
hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
if (hwirq < 0) {
@@ -202,7 +197,6 @@ int mpic_u3msi_init(struct mpic *mpic)
WARN_ON(ppc_md.setup_msi_irqs);
ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs;
ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs;
- ppc_md.msi_check_device = u3msi_msi_check_device;
return 0;
}
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index 11c8884..a6a4dbd 100644
--- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -44,6 +44,12 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
int irq, hwirq;
u64 addr;
+ /* We don't support MSI-X */
+ if (type == PCI_CAP_ID_MSIX) {
+ pr_debug("%s: MSI-X not supported.\n", __func__);
+ return -EINVAL;
+ }
+
list_for_each_entry(entry, &dev->msi_list, list) {
irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1);
if (irq < 0) {
@@ -117,17 +123,6 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)
}
}
-static int hsta_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- /* We don't support MSI-X */
- if (type == PCI_CAP_ID_MSIX) {
- pr_debug("%s: MSI-X not supported.\n", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
static int hsta_msi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -178,7 +173,6 @@ static int hsta_msi_probe(struct platform_device *pdev)
ppc_md.setup_msi_irqs = hsta_setup_msi_irqs;
ppc_md.teardown_msi_irqs = hsta_teardown_msi_irqs;
- ppc_md.msi_check_device = hsta_msi_check_device;
return 0;
out2:
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 43948da..8577d82 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -85,8 +85,12 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
struct msi_desc *entry;
struct ppc4xx_msi *msi_data = &ppc4xx_msi;
- msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int),
- GFP_KERNEL);
+ dev_dbg(&pdev->dev, "PCIE-MSI:%s called. vec %x type %d\n",
+ __func__, nvec, type);
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n");
+
+ msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), GFP_KERNEL);
if (!msi_data->msi_virqs)
return -ENOMEM;
@@ -134,16 +138,6 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)
}
}
-static int ppc4xx_msi_check_device(struct pci_dev *pdev, int nvec, int type)
-{
- dev_dbg(&pdev->dev, "PCIE-MSI:%s called. vec %x type %d\n",
- __func__, nvec, type);
- if (type == PCI_CAP_ID_MSIX)
- pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n");
-
- return 0;
-}
-
static int ppc4xx_setup_pcieh_hw(struct platform_device *dev,
struct resource res, struct ppc4xx_msi *msi)
{
@@ -259,7 +253,6 @@ static int ppc4xx_msi_probe(struct platform_device *dev)
ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs;
ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;
- ppc_md.msi_check_device = ppc4xx_msi_check_device;
return err;
error_out:
--
1.7.7.6
^ permalink raw reply related
* [PATCH 2/2] PCI/MSI: Remove arch_msi_check_device()
From: Alexander Gordeev @ 2014-07-12 11:21 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-pci, Alexander Gordeev, linuxppc-dev
In-Reply-To: <cover.1405160163.git.agordeev@redhat.com>
There are no archs that override arch_msi_check_device()
hook. Remove it as it is completely redundant.
If an arch would need to check MSI/MSI-X possibility for a
device it should make it within arch_setup_msi_irqs() hook.
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-pci@vger.kernel.org
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
---
drivers/pci/msi.c | 49 +++++++++++++------------------------------------
include/linux/msi.h | 3 ---
2 files changed, 13 insertions(+), 39 deletions(-)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 13f3d30..19ac058 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -56,16 +56,6 @@ void __weak arch_teardown_msi_irq(unsigned int irq)
chip->teardown_irq(chip, irq);
}
-int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
-{
- struct msi_chip *chip = dev->bus->msi;
-
- if (!chip || !chip->check_device)
- return 0;
-
- return chip->check_device(chip, dev, nvec, type);
-}
-
int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
@@ -809,22 +799,23 @@ out_free:
}
/**
- * pci_msi_check_device - check whether MSI may be enabled on a device
+ * msi_check_device - check whether MSI may be enabled on a device
* @dev: pointer to the pci_dev data structure of MSI device function
* @nvec: how many MSIs have been requested ?
- * @type: are we checking for MSI or MSI-X ?
*
* Look at global flags, the device itself, and its parent buses
* to determine if MSI/-X are supported for the device. If MSI/-X is
* supported return 0, else return an error code.
**/
-static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
+static int msi_check_device(struct pci_dev *dev, int nvec)
{
struct pci_bus *bus;
- int ret;
/* MSI must be globally enabled and supported by the device */
- if (!pci_msi_enable || !dev || dev->no_msi)
+ if (!pci_msi_enable)
+ return -EINVAL;
+
+ if (!dev || dev->no_msi || dev->current_state != PCI_D0)
return -EINVAL;
/*
@@ -846,10 +837,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
return -EINVAL;
- ret = arch_msi_check_device(dev, nvec, type);
- if (ret)
- return ret;
-
return 0;
}
@@ -954,13 +941,13 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
int status, nr_entries;
int i, j;
- if (!entries || !dev->msix_cap || dev->current_state != PCI_D0)
- return -EINVAL;
-
- status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX);
+ status = msi_check_device(dev, nvec);
if (status)
return status;
+ if (!entries)
+ return -EINVAL;
+
nr_entries = pci_msix_vec_count(dev);
if (nr_entries < 0)
return nr_entries;
@@ -1085,8 +1072,9 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
int nvec;
int rc;
- if (dev->current_state != PCI_D0)
- return -EINVAL;
+ rc = msi_check_device(dev, minvec);
+ if (rc)
+ return rc;
WARN_ON(!!dev->msi_enabled);
@@ -1109,17 +1097,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
nvec = maxvec;
do {
- rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
- if (rc < 0) {
- return rc;
- } else if (rc > 0) {
- if (rc < minvec)
- return -ENOSPC;
- nvec = rc;
- }
- } while (rc);
-
- do {
rc = msi_capability_init(dev, nvec);
if (rc < 0) {
return rc;
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 92a2f99..3b873bc 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -59,7 +59,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
void arch_teardown_msi_irq(unsigned int irq);
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
void arch_teardown_msi_irqs(struct pci_dev *dev);
-int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
void arch_restore_msi_irqs(struct pci_dev *dev);
void default_teardown_msi_irqs(struct pci_dev *dev);
@@ -76,8 +75,6 @@ struct msi_chip {
int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
struct msi_desc *desc);
void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
- int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
- int nvec, int type);
};
#endif /* LINUX_MSI_H */
--
1.7.7.6
^ permalink raw reply related
* [PATCH 0/2] PCI/MSI: Remove arch_msi_check_device()
From: Alexander Gordeev @ 2014-07-12 11:21 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-pci, Alexander Gordeev, linuxppc-dev
Hello,
This is a cleanup effort to get rid of useless arch_msi_check_device().
I am not sure what were the reasons for its existence in the first place,
but at the moment it appears totally unnecessary.
Thanks!
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-pci@vger.kernel.org
Alexander Gordeev (2):
PCI/MSI/PPC: Remove arch_msi_check_device()
PCI/MSI: Remove arch_msi_check_device()
arch/powerpc/include/asm/machdep.h | 2 -
arch/powerpc/kernel/msi.c | 12 +-------
arch/powerpc/platforms/cell/axon_msi.c | 9 ------
arch/powerpc/platforms/powernv/pci.c | 19 +++---------
arch/powerpc/platforms/pseries/msi.c | 42 ++++++++++-----------------
arch/powerpc/sysdev/fsl_msi.c | 12 ++------
arch/powerpc/sysdev/mpic_pasemi_msi.c | 11 +------
arch/powerpc/sysdev/mpic_u3msi.c | 28 +++++++-----------
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 18 ++++--------
arch/powerpc/sysdev/ppc4xx_msi.c | 19 ++++--------
drivers/pci/msi.c | 49 ++++++++-----------------------
include/linux/msi.h | 3 --
12 files changed, 63 insertions(+), 161 deletions(-)
--
1.7.7.6
^ permalink raw reply
* [PATCH 0/7] arch/powerpc: convert single variable sscanf to kstrto<type>
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
Here is a small untested patchset to use the current string manipulation kstrto<type> functions
instead of sscanf like specified in checkpatch: "Prefer kstrto<type> to single variable sscanf"
autodetect base 0 has been used for both %d, %i, %ld, %lu, %u
and base 16 for %lx
Fabian Frederick (7):
powerpc: fadump: replace sscanf by kstrtoint
powerpc/mv64x60_pci: replace sscanf by kstrtou32
powerpc/powernv: replace sscanf %lx by kstrtoul 16
powerpc/sysfs: replace sscanf by kstrtol
hugetlb: replace sscanf by kstrtoul
powerpc/cell: replace sscanf by kstrtouint
powerpc/pseries: replace sscanf by kstrtoul
arch/powerpc/kernel/fadump.c | 5 +++--
arch/powerpc/kernel/sysfs.c | 7 +++----
arch/powerpc/mm/hugetlbpage.c | 2 +-
arch/powerpc/platforms/cell/cbe_thermal.c | 4 ++--
arch/powerpc/platforms/powernv/subcore.c | 6 +++---
arch/powerpc/platforms/pseries/power.c | 5 ++---
arch/powerpc/sysdev/mv64x60_pci.c | 7 +++++--
7 files changed, 19 insertions(+), 17 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 1/7] powerpc: fadump: replace sscanf by kstrtoint
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/kernel/fadump.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 742694c..3c40b5f 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -426,6 +426,7 @@ static inline int fadump_gpr_index(u64 id)
{
int i = -1;
char str[3];
+ int rc;
if ((id & GPR_MASK) == REG_ID("GPR")) {
/* get the digits at the end */
@@ -434,8 +435,8 @@ static inline int fadump_gpr_index(u64 id)
str[2] = '\0';
str[1] = id & 0xff;
str[0] = (id >> 8) & 0xff;
- sscanf(str, "%d", &i);
- if (i > 31)
+ rc = kstrtoint(str, 0, &i);
+ if (rc || i > 31)
i = -1;
}
return i;
--
1.9.1
^ permalink raw reply related
* [PATCH 2/7] powerpc/mv64x60_pci: replace sscanf by kstrtou32
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/sysdev/mv64x60_pci.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index 330d566..ca0b29c 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -52,14 +52,17 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
{
struct pci_dev *phb;
u32 v;
+ int rc;
if (off > 0)
return 0;
if (count <= 0)
return -EINVAL;
- if (sscanf(buf, "%i", &v) != 1)
- return -EINVAL;
+ rc = kstrtou32(buf, 0, &v);
+
+ if (rc)
+ return rc;
phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
if (!phb)
--
1.9.1
^ permalink raw reply related
* [PATCH 3/7] powerpc/powernv: replace sscanf %lx by kstrtoul 16
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/platforms/powernv/subcore.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c
index 894ecb3..79721b2 100644
--- a/arch/powerpc/platforms/powernv/subcore.c
+++ b/arch/powerpc/platforms/powernv/subcore.c
@@ -337,9 +337,9 @@ static ssize_t __used store_subcores_per_core(struct device *dev,
/* We are serialised by the attribute lock */
- rc = sscanf(buf, "%lx", &val);
- if (rc != 1)
- return -EINVAL;
+ rc = kstrtoul(buf, 16, &val);
+ if (rc)
+ return rc;
switch (val) {
case 1:
--
1.9.1
^ permalink raw reply related
* [PATCH 5/7] hugetlb: replace sscanf by kstrtoul
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/mm/hugetlbpage.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 7e70ae9..9118313 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -350,7 +350,7 @@ static int __init do_gpage_early_setup(char *param, char *val,
size = memparse(val, NULL);
} else if (strcmp(param, "hugepages") == 0) {
if (size != 0) {
- if (sscanf(val, "%lu", &npages) <= 0)
+ if (kstrtoul(val, 0, &npages))
npages = 0;
gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages;
size = 0;
--
1.9.1
^ permalink raw reply related
* [PATCH 4/7] powerpc/sysfs: replace sscanf by kstrtol
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/kernel/sysfs.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 67fd2fd..4293e4f 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -43,12 +43,11 @@ static ssize_t store_smt_snooze_delay(struct device *dev,
size_t count)
{
struct cpu *cpu = container_of(dev, struct cpu, dev);
- ssize_t ret;
long snooze;
+ int rc = kstrtol(buf, 0, &snooze);
- ret = sscanf(buf, "%ld", &snooze);
- if (ret != 1)
- return -EINVAL;
+ if (rc)
+ return rc;
per_cpu(smt_snooze_delay, cpu->dev.id) = snooze;
return count;
--
1.9.1
^ permalink raw reply related
* [PATCH 6/7] powerpc/cell: replace sscanf by kstrtouint
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/platforms/cell/cbe_thermal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c
index 2c15ff0..d71c3c4 100644
--- a/arch/powerpc/platforms/cell/cbe_thermal.c
+++ b/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -129,9 +129,9 @@ static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char
u64 new_value;
int ret;
- ret = sscanf(buf, "%u", &temp);
+ ret = kstrtouint(buf, 0, &temp);
- if (ret != 1 || temp < TEMP_MIN || temp > TEMP_MAX)
+ if (ret || temp < TEMP_MIN || temp > TEMP_MAX)
return -EINVAL;
new_value = temp_to_reg(temp);
--
1.9.1
^ permalink raw reply related
* [PATCH 7/7] powerpc/pseries: replace sscanf by kstrtoul
From: Fabian Frederick @ 2014-07-12 11:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Fabian Frederick, paulus, linuxppc-dev
In-Reply-To: <1405164980-9525-1-git-send-email-fabf@skynet.be>
See checkpatch warning
"Prefer kstrto<type> to single variable sscanf"
Signed-off-by: Fabian Frederick <fabf@skynet.be>
---
arch/powerpc/platforms/pseries/power.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
index 6d62662..27a3e9c 100644
--- a/arch/powerpc/platforms/pseries/power.c
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -38,11 +38,10 @@ static ssize_t auto_poweron_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t n)
{
- int ret;
unsigned long ups_restart;
- ret = sscanf(buf, "%lu", &ups_restart);
+ int ret = kstrtoul(buf, 0, &ups_restart);
- if ((ret == 1) && ((ups_restart == 1) || (ups_restart == 0))){
+ if ((!ret) && ((ups_restart == 1) || (ups_restart == 0))) {
rtas_poweron_auto = ups_restart;
return n;
}
--
1.9.1
^ permalink raw reply related
* bit fields && data tearing
From: Oleg Nesterov @ 2014-07-12 18:13 UTC (permalink / raw)
To: Jakub Jelinek, Paul E. McKenney, Richard Henderson
Cc: linuxppc-dev, Paul Mackerras, Miroslav Franc, linux-kernel
Hello,
I am not sure I should ask here, but since Documentation/memory-barriers.txt
mentions load/store tearing perhaps my question is not completely off-topic...
I am fighting with mysterious RHEL bug, it can be reproduced on ppc and s390
but not on x86. Finally I seem to understand the problem, and I even wrote the
stupid kernel module to ensure, see it below at the end.
It triggers the problem immediately, kt_2() sees the wrong value in freeze_stop.
(If I turn ->freeze_stop int "long", the problem goes away).
So the question is: is this gcc bug or the code below is buggy?
If it is buggy, then probably memory-barriers.txt could mention that you should
be carefull with bit fields, even ACCESS_ONCE() obviously can't help.
Or this just discloses my ignorance and you need at least aligned(long) after a
bit field to be thread-safe ? I thought that compiler should take care and add
the necessary alignment if (say) CPU can't update a single byte/uint.
gcc version 4.4.7 20120313 (Red Hat 4.4.7-9) (GCC). Asm:
0000000000000000 <.kt_2>:
0: 7c 08 02 a6 mflr r0
4: fb 81 ff e0 std r28,-32(r1)
8: fb a1 ff e8 std r29,-24(r1)
c: fb c1 ff f0 std r30,-16(r1)
10: fb e1 ff f8 std r31,-8(r1)
14: eb c2 00 00 ld r30,0(r2)
18: f8 01 00 10 std r0,16(r1)
1c: f8 21 ff 71 stdu r1,-144(r1)
20: 7c 7d 1b 78 mr r29,r3
24: 3b e0 00 00 li r31,0
28: 78 3c 04 64 rldicr r28,r1,0,49
2c: 3b 9c 00 80 addi r28,r28,128
30: 48 00 00 2c b 5c <.kt_2+0x5c>
34: 60 00 00 00 nop
38: 60 00 00 00 nop
3c: 60 00 00 00 nop
40: 93 fd 00 04 stw r31,4(r29)
44: e8 9d 00 06 lwa r4,4(r29)
48: 7f 84 f8 00 cmpw cr7,r4,r31
4c: 40 de 00 4c bne- cr7,98 <.kt_2+0x98>
50: e8 1c 00 00 ld r0,0(r28)
54: 78 09 f7 e3 rldicl. r9,r0,62,63
58: 40 c2 00 54 bne- ac <.kt_2+0xac>
5c: 48 00 00 01 bl 5c <.kt_2+0x5c>
60: 60 00 00 00 nop
64: 3b ff 00 01 addi r31,r31,1
68: 2f a3 00 00 cmpdi cr7,r3,0
6c: 7f ff 07 b4 extsw r31,r31
70: 41 9e ff d0 beq+ cr7,40 <.kt_2+0x40>
74: 38 21 00 90 addi r1,r1,144
78: 38 60 00 00 li r3,0
7c: e8 01 00 10 ld r0,16(r1)
80: eb 81 ff e0 ld r28,-32(r1)
84: eb a1 ff e8 ld r29,-24(r1)
88: eb c1 ff f0 ld r30,-16(r1)
8c: eb e1 ff f8 ld r31,-8(r1)
90: 7c 08 03 a6 mtlr r0
94: 4e 80 00 20 blr
98: e8 7e 80 28 ld r3,-32728(r30)
9c: 7f e5 fb 78 mr r5,r31
a0: 48 00 00 01 bl a0 <.kt_2+0xa0>
a4: 60 00 00 00 nop
a8: 4b ff ff a8 b 50 <.kt_2+0x50>
ac: 48 00 00 01 bl ac <.kt_2+0xac>
b0: 60 00 00 00 nop
b4: 4b ff ff a8 b 5c <.kt_2+0x5c>
b8: 60 00 00 00 nop
bc: 60 00 00 00 nop
00000000000000c0 <.kt_1>:
c0: 7c 08 02 a6 mflr r0
c4: fb 81 ff e0 std r28,-32(r1)
c8: fb a1 ff e8 std r29,-24(r1)
cc: fb c1 ff f0 std r30,-16(r1)
d0: fb e1 ff f8 std r31,-8(r1)
d4: eb c2 00 00 ld r30,0(r2)
d8: f8 01 00 10 std r0,16(r1)
dc: f8 21 ff 71 stdu r1,-144(r1)
e0: 7c 7d 1b 78 mr r29,r3
e4: 3b e0 00 00 li r31,0
e8: 78 3c 04 64 rldicr r28,r1,0,49
ec: 3b 9c 00 80 addi r28,r28,128
f0: 48 00 00 38 b 128 <.kt_1+0x68>
f4: 60 00 00 00 nop
f8: 60 00 00 00 nop
fc: 60 00 00 00 nop
100: e8 1d 00 00 ld r0,0(r29)
104: 79 20 e8 0e rldimi r0,r9,61,0
108: f8 1d 00 00 std r0,0(r29)
10c: 80 1d 00 00 lwz r0,0(r29)
110: 54 00 1f 7e rlwinm r0,r0,3,29,31
114: 7f 80 f8 00 cmpw cr7,r0,r31
118: 40 de 00 6c bne- cr7,184 <.kt_1+0xc4>
11c: e8 1c 00 00 ld r0,0(r28)
120: 78 09 f7 e3 rldicl. r9,r0,62,63
124: 40 c2 00 70 bne- 194 <.kt_1+0xd4>
128: 48 00 00 01 bl 128 <.kt_1+0x68>
12c: 60 00 00 00 nop
130: 3b ff 00 01 addi r31,r31,1
134: 2f a3 00 00 cmpdi cr7,r3,0
138: 7f ff 07 b4 extsw r31,r31
13c: 2f 1f 00 07 cmpwi cr6,r31,7
140: 7b e9 07 60 clrldi r9,r31,61
144: 40 9e 00 1c bne- cr7,160 <.kt_1+0xa0>
148: 40 9a ff b8 bne+ cr6,100 <.kt_1+0x40>
14c: 39 20 00 00 li r9,0
150: 3b e0 00 00 li r31,0
154: 4b ff ff ac b 100 <.kt_1+0x40>
158: 60 00 00 00 nop
15c: 60 00 00 00 nop
160: 38 21 00 90 addi r1,r1,144
164: 38 60 00 00 li r3,0
168: e8 01 00 10 ld r0,16(r1)
16c: eb 81 ff e0 ld r28,-32(r1)
170: eb a1 ff e8 ld r29,-24(r1)
174: eb c1 ff f0 ld r30,-16(r1)
178: eb e1 ff f8 ld r31,-8(r1)
17c: 7c 08 03 a6 mtlr r0
180: 4e 80 00 20 blr
184: e8 7e 80 30 ld r3,-32720(r30)
188: 48 00 00 01 bl 188 <.kt_1+0xc8>
18c: 60 00 00 00 nop
190: 4b ff ff 8c b 11c <.kt_1+0x5c>
194: 48 00 00 01 bl 194 <.kt_1+0xd4>
198: 60 00 00 00 nop
19c: 4b ff ff 8c b 128 <.kt_1+0x68>
Unfortunately it tells me nothing, I do not know ppc.
Oleg.
--------------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
struct utrace {
unsigned int resume:3;
int freeze_stop;
};
static int kt_1(void *arg)
{
struct utrace *u = arg;
int r = 0;
while (!kthread_should_stop()) {
if (++r == 7)
r = 0;
u->resume = r;
barrier();
if (u->resume != r)
printk(KERN_CRIT "BUG! bitfield\n");
if (need_resched())
schedule();
}
return 0;
}
static int kt_2(void *arg)
{
struct utrace *u = arg;
int f = 0;
while (!kthread_should_stop()) {
u->freeze_stop = ++f;
barrier();
if (u->freeze_stop != f)
printk(KERN_CRIT "BUG! freeze_stop %d != %d\n", u->freeze_stop, f);
if (need_resched())
schedule();
}
return 0;
}
static struct task_struct *t_1, *t_2;
static struct utrace utrace;
static int __init mod_init(void)
{
WARN_ON(IS_ERR(t_1 = kthread_run(kt_1, &utrace, "kt_1")));
WARN_ON(IS_ERR(t_2 = kthread_run(kt_2, &utrace, "kt_2")));
return 0;
}
static void __exit mod_exit(void)
{
kthread_stop(t_1);
kthread_stop(t_2);
}
MODULE_LICENSE("GPL");
module_init(mod_init);
module_exit(mod_exit);
^ permalink raw reply
* Re: bit fields && data tearing
From: Oleg Nesterov @ 2014-07-12 20:51 UTC (permalink / raw)
To: Jakub Jelinek, Paul E. McKenney, Richard Henderson
Cc: linux-kernel, Paul Mackerras, Dan, linuxppc-dev, Miroslav Franc
In-Reply-To: <20140712181328.GA8738@redhat.com>
OK, looks like this is compiler bug,
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
Thanks to Dan who informed me privately.
On 07/12, Oleg Nesterov wrote:
>
> Hello,
>
> I am not sure I should ask here, but since Documentation/memory-barriers.txt
> mentions load/store tearing perhaps my question is not completely off-topic...
>
> I am fighting with mysterious RHEL bug, it can be reproduced on ppc and s390
> but not on x86. Finally I seem to understand the problem, and I even wrote the
> stupid kernel module to ensure, see it below at the end.
>
> It triggers the problem immediately, kt_2() sees the wrong value in freeze_stop.
> (If I turn ->freeze_stop int "long", the problem goes away).
>
> So the question is: is this gcc bug or the code below is buggy?
>
> If it is buggy, then probably memory-barriers.txt could mention that you should
> be carefull with bit fields, even ACCESS_ONCE() obviously can't help.
>
> Or this just discloses my ignorance and you need at least aligned(long) after a
> bit field to be thread-safe ? I thought that compiler should take care and add
> the necessary alignment if (say) CPU can't update a single byte/uint.
>
> gcc version 4.4.7 20120313 (Red Hat 4.4.7-9) (GCC). Asm:
>
> 0000000000000000 <.kt_2>:
> 0: 7c 08 02 a6 mflr r0
> 4: fb 81 ff e0 std r28,-32(r1)
> 8: fb a1 ff e8 std r29,-24(r1)
> c: fb c1 ff f0 std r30,-16(r1)
> 10: fb e1 ff f8 std r31,-8(r1)
> 14: eb c2 00 00 ld r30,0(r2)
> 18: f8 01 00 10 std r0,16(r1)
> 1c: f8 21 ff 71 stdu r1,-144(r1)
> 20: 7c 7d 1b 78 mr r29,r3
> 24: 3b e0 00 00 li r31,0
> 28: 78 3c 04 64 rldicr r28,r1,0,49
> 2c: 3b 9c 00 80 addi r28,r28,128
> 30: 48 00 00 2c b 5c <.kt_2+0x5c>
> 34: 60 00 00 00 nop
> 38: 60 00 00 00 nop
> 3c: 60 00 00 00 nop
> 40: 93 fd 00 04 stw r31,4(r29)
> 44: e8 9d 00 06 lwa r4,4(r29)
> 48: 7f 84 f8 00 cmpw cr7,r4,r31
> 4c: 40 de 00 4c bne- cr7,98 <.kt_2+0x98>
> 50: e8 1c 00 00 ld r0,0(r28)
> 54: 78 09 f7 e3 rldicl. r9,r0,62,63
> 58: 40 c2 00 54 bne- ac <.kt_2+0xac>
> 5c: 48 00 00 01 bl 5c <.kt_2+0x5c>
> 60: 60 00 00 00 nop
> 64: 3b ff 00 01 addi r31,r31,1
> 68: 2f a3 00 00 cmpdi cr7,r3,0
> 6c: 7f ff 07 b4 extsw r31,r31
> 70: 41 9e ff d0 beq+ cr7,40 <.kt_2+0x40>
> 74: 38 21 00 90 addi r1,r1,144
> 78: 38 60 00 00 li r3,0
> 7c: e8 01 00 10 ld r0,16(r1)
> 80: eb 81 ff e0 ld r28,-32(r1)
> 84: eb a1 ff e8 ld r29,-24(r1)
> 88: eb c1 ff f0 ld r30,-16(r1)
> 8c: eb e1 ff f8 ld r31,-8(r1)
> 90: 7c 08 03 a6 mtlr r0
> 94: 4e 80 00 20 blr
> 98: e8 7e 80 28 ld r3,-32728(r30)
> 9c: 7f e5 fb 78 mr r5,r31
> a0: 48 00 00 01 bl a0 <.kt_2+0xa0>
> a4: 60 00 00 00 nop
> a8: 4b ff ff a8 b 50 <.kt_2+0x50>
> ac: 48 00 00 01 bl ac <.kt_2+0xac>
> b0: 60 00 00 00 nop
> b4: 4b ff ff a8 b 5c <.kt_2+0x5c>
> b8: 60 00 00 00 nop
> bc: 60 00 00 00 nop
>
> 00000000000000c0 <.kt_1>:
> c0: 7c 08 02 a6 mflr r0
> c4: fb 81 ff e0 std r28,-32(r1)
> c8: fb a1 ff e8 std r29,-24(r1)
> cc: fb c1 ff f0 std r30,-16(r1)
> d0: fb e1 ff f8 std r31,-8(r1)
> d4: eb c2 00 00 ld r30,0(r2)
> d8: f8 01 00 10 std r0,16(r1)
> dc: f8 21 ff 71 stdu r1,-144(r1)
> e0: 7c 7d 1b 78 mr r29,r3
> e4: 3b e0 00 00 li r31,0
> e8: 78 3c 04 64 rldicr r28,r1,0,49
> ec: 3b 9c 00 80 addi r28,r28,128
> f0: 48 00 00 38 b 128 <.kt_1+0x68>
> f4: 60 00 00 00 nop
> f8: 60 00 00 00 nop
> fc: 60 00 00 00 nop
> 100: e8 1d 00 00 ld r0,0(r29)
> 104: 79 20 e8 0e rldimi r0,r9,61,0
> 108: f8 1d 00 00 std r0,0(r29)
> 10c: 80 1d 00 00 lwz r0,0(r29)
> 110: 54 00 1f 7e rlwinm r0,r0,3,29,31
> 114: 7f 80 f8 00 cmpw cr7,r0,r31
> 118: 40 de 00 6c bne- cr7,184 <.kt_1+0xc4>
> 11c: e8 1c 00 00 ld r0,0(r28)
> 120: 78 09 f7 e3 rldicl. r9,r0,62,63
> 124: 40 c2 00 70 bne- 194 <.kt_1+0xd4>
> 128: 48 00 00 01 bl 128 <.kt_1+0x68>
> 12c: 60 00 00 00 nop
> 130: 3b ff 00 01 addi r31,r31,1
> 134: 2f a3 00 00 cmpdi cr7,r3,0
> 138: 7f ff 07 b4 extsw r31,r31
> 13c: 2f 1f 00 07 cmpwi cr6,r31,7
> 140: 7b e9 07 60 clrldi r9,r31,61
> 144: 40 9e 00 1c bne- cr7,160 <.kt_1+0xa0>
> 148: 40 9a ff b8 bne+ cr6,100 <.kt_1+0x40>
> 14c: 39 20 00 00 li r9,0
> 150: 3b e0 00 00 li r31,0
> 154: 4b ff ff ac b 100 <.kt_1+0x40>
> 158: 60 00 00 00 nop
> 15c: 60 00 00 00 nop
> 160: 38 21 00 90 addi r1,r1,144
> 164: 38 60 00 00 li r3,0
> 168: e8 01 00 10 ld r0,16(r1)
> 16c: eb 81 ff e0 ld r28,-32(r1)
> 170: eb a1 ff e8 ld r29,-24(r1)
> 174: eb c1 ff f0 ld r30,-16(r1)
> 178: eb e1 ff f8 ld r31,-8(r1)
> 17c: 7c 08 03 a6 mtlr r0
> 180: 4e 80 00 20 blr
> 184: e8 7e 80 30 ld r3,-32720(r30)
> 188: 48 00 00 01 bl 188 <.kt_1+0xc8>
> 18c: 60 00 00 00 nop
> 190: 4b ff ff 8c b 11c <.kt_1+0x5c>
> 194: 48 00 00 01 bl 194 <.kt_1+0xd4>
> 198: 60 00 00 00 nop
> 19c: 4b ff ff 8c b 128 <.kt_1+0x68>
>
> Unfortunately it tells me nothing, I do not know ppc.
>
> Oleg.
>
> --------------------------------------------------------------------------------
> #include <linux/module.h>
> #include <linux/kernel.h>
> #include <linux/kthread.h>
>
> struct utrace {
> unsigned int resume:3;
> int freeze_stop;
> };
>
> static int kt_1(void *arg)
> {
> struct utrace *u = arg;
> int r = 0;
>
> while (!kthread_should_stop()) {
> if (++r == 7)
> r = 0;
>
> u->resume = r;
> barrier();
> if (u->resume != r)
> printk(KERN_CRIT "BUG! bitfield\n");
>
> if (need_resched())
> schedule();
> }
>
> return 0;
> }
>
> static int kt_2(void *arg)
> {
> struct utrace *u = arg;
> int f = 0;
>
> while (!kthread_should_stop()) {
> u->freeze_stop = ++f;
> barrier();
> if (u->freeze_stop != f)
> printk(KERN_CRIT "BUG! freeze_stop %d != %d\n", u->freeze_stop, f);
>
> if (need_resched())
> schedule();
> }
>
> return 0;
> }
>
> static struct task_struct *t_1, *t_2;
>
> static struct utrace utrace;
>
> static int __init mod_init(void)
> {
> WARN_ON(IS_ERR(t_1 = kthread_run(kt_1, &utrace, "kt_1")));
> WARN_ON(IS_ERR(t_2 = kthread_run(kt_2, &utrace, "kt_2")));
>
> return 0;
> }
>
> static void __exit mod_exit(void)
> {
> kthread_stop(t_1);
> kthread_stop(t_2);
> }
>
> MODULE_LICENSE("GPL");
> module_init(mod_init);
> module_exit(mod_exit);
^ permalink raw reply
* Re: bit fields && data tearing
From: Benjamin Herrenschmidt @ 2014-07-12 23:34 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Jakub Jelinek, linux-kernel, Paul Mackerras, Dan,
Paul E. McKenney, linuxppc-dev, Miroslav Franc, Richard Henderson
In-Reply-To: <20140712205130.GA16437@redhat.com>
On Sat, 2014-07-12 at 22:51 +0200, Oleg Nesterov wrote:
> OK, looks like this is compiler bug,
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
>
> Thanks to Dan who informed me privately.
So yes, there's is this compiler bug which means a bitfield
access can cause a r-m-w access to a neighbouring field but
in general, I would be weary of bitfields anyway since accessing
them isn't going to be atomic anyway... it's too easy to get things
wrong and in most cases the benefit is yet to be demonstrated.
In your example, I don't see the point of the bitfield.
Cheers,
Ben.
> On 07/12, Oleg Nesterov wrote:
> >
> > Hello,
> >
> > I am not sure I should ask here, but since Documentation/memory-barriers.txt
> > mentions load/store tearing perhaps my question is not completely off-topic...
> >
> > I am fighting with mysterious RHEL bug, it can be reproduced on ppc and s390
> > but not on x86. Finally I seem to understand the problem, and I even wrote the
> > stupid kernel module to ensure, see it below at the end.
> >
> > It triggers the problem immediately, kt_2() sees the wrong value in freeze_stop.
> > (If I turn ->freeze_stop int "long", the problem goes away).
> >
> > So the question is: is this gcc bug or the code below is buggy?
> >
> > If it is buggy, then probably memory-barriers.txt could mention that you should
> > be carefull with bit fields, even ACCESS_ONCE() obviously can't help.
> >
> > Or this just discloses my ignorance and you need at least aligned(long) after a
> > bit field to be thread-safe ? I thought that compiler should take care and add
> > the necessary alignment if (say) CPU can't update a single byte/uint.
> >
> > gcc version 4.4.7 20120313 (Red Hat 4.4.7-9) (GCC). Asm:
> >
> > 0000000000000000 <.kt_2>:
> > 0: 7c 08 02 a6 mflr r0
> > 4: fb 81 ff e0 std r28,-32(r1)
> > 8: fb a1 ff e8 std r29,-24(r1)
> > c: fb c1 ff f0 std r30,-16(r1)
> > 10: fb e1 ff f8 std r31,-8(r1)
> > 14: eb c2 00 00 ld r30,0(r2)
> > 18: f8 01 00 10 std r0,16(r1)
> > 1c: f8 21 ff 71 stdu r1,-144(r1)
> > 20: 7c 7d 1b 78 mr r29,r3
> > 24: 3b e0 00 00 li r31,0
> > 28: 78 3c 04 64 rldicr r28,r1,0,49
> > 2c: 3b 9c 00 80 addi r28,r28,128
> > 30: 48 00 00 2c b 5c <.kt_2+0x5c>
> > 34: 60 00 00 00 nop
> > 38: 60 00 00 00 nop
> > 3c: 60 00 00 00 nop
> > 40: 93 fd 00 04 stw r31,4(r29)
> > 44: e8 9d 00 06 lwa r4,4(r29)
> > 48: 7f 84 f8 00 cmpw cr7,r4,r31
> > 4c: 40 de 00 4c bne- cr7,98 <.kt_2+0x98>
> > 50: e8 1c 00 00 ld r0,0(r28)
> > 54: 78 09 f7 e3 rldicl. r9,r0,62,63
> > 58: 40 c2 00 54 bne- ac <.kt_2+0xac>
> > 5c: 48 00 00 01 bl 5c <.kt_2+0x5c>
> > 60: 60 00 00 00 nop
> > 64: 3b ff 00 01 addi r31,r31,1
> > 68: 2f a3 00 00 cmpdi cr7,r3,0
> > 6c: 7f ff 07 b4 extsw r31,r31
> > 70: 41 9e ff d0 beq+ cr7,40 <.kt_2+0x40>
> > 74: 38 21 00 90 addi r1,r1,144
> > 78: 38 60 00 00 li r3,0
> > 7c: e8 01 00 10 ld r0,16(r1)
> > 80: eb 81 ff e0 ld r28,-32(r1)
> > 84: eb a1 ff e8 ld r29,-24(r1)
> > 88: eb c1 ff f0 ld r30,-16(r1)
> > 8c: eb e1 ff f8 ld r31,-8(r1)
> > 90: 7c 08 03 a6 mtlr r0
> > 94: 4e 80 00 20 blr
> > 98: e8 7e 80 28 ld r3,-32728(r30)
> > 9c: 7f e5 fb 78 mr r5,r31
> > a0: 48 00 00 01 bl a0 <.kt_2+0xa0>
> > a4: 60 00 00 00 nop
> > a8: 4b ff ff a8 b 50 <.kt_2+0x50>
> > ac: 48 00 00 01 bl ac <.kt_2+0xac>
> > b0: 60 00 00 00 nop
> > b4: 4b ff ff a8 b 5c <.kt_2+0x5c>
> > b8: 60 00 00 00 nop
> > bc: 60 00 00 00 nop
> >
> > 00000000000000c0 <.kt_1>:
> > c0: 7c 08 02 a6 mflr r0
> > c4: fb 81 ff e0 std r28,-32(r1)
> > c8: fb a1 ff e8 std r29,-24(r1)
> > cc: fb c1 ff f0 std r30,-16(r1)
> > d0: fb e1 ff f8 std r31,-8(r1)
> > d4: eb c2 00 00 ld r30,0(r2)
> > d8: f8 01 00 10 std r0,16(r1)
> > dc: f8 21 ff 71 stdu r1,-144(r1)
> > e0: 7c 7d 1b 78 mr r29,r3
> > e4: 3b e0 00 00 li r31,0
> > e8: 78 3c 04 64 rldicr r28,r1,0,49
> > ec: 3b 9c 00 80 addi r28,r28,128
> > f0: 48 00 00 38 b 128 <.kt_1+0x68>
> > f4: 60 00 00 00 nop
> > f8: 60 00 00 00 nop
> > fc: 60 00 00 00 nop
> > 100: e8 1d 00 00 ld r0,0(r29)
> > 104: 79 20 e8 0e rldimi r0,r9,61,0
> > 108: f8 1d 00 00 std r0,0(r29)
> > 10c: 80 1d 00 00 lwz r0,0(r29)
> > 110: 54 00 1f 7e rlwinm r0,r0,3,29,31
> > 114: 7f 80 f8 00 cmpw cr7,r0,r31
> > 118: 40 de 00 6c bne- cr7,184 <.kt_1+0xc4>
> > 11c: e8 1c 00 00 ld r0,0(r28)
> > 120: 78 09 f7 e3 rldicl. r9,r0,62,63
> > 124: 40 c2 00 70 bne- 194 <.kt_1+0xd4>
> > 128: 48 00 00 01 bl 128 <.kt_1+0x68>
> > 12c: 60 00 00 00 nop
> > 130: 3b ff 00 01 addi r31,r31,1
> > 134: 2f a3 00 00 cmpdi cr7,r3,0
> > 138: 7f ff 07 b4 extsw r31,r31
> > 13c: 2f 1f 00 07 cmpwi cr6,r31,7
> > 140: 7b e9 07 60 clrldi r9,r31,61
> > 144: 40 9e 00 1c bne- cr7,160 <.kt_1+0xa0>
> > 148: 40 9a ff b8 bne+ cr6,100 <.kt_1+0x40>
> > 14c: 39 20 00 00 li r9,0
> > 150: 3b e0 00 00 li r31,0
> > 154: 4b ff ff ac b 100 <.kt_1+0x40>
> > 158: 60 00 00 00 nop
> > 15c: 60 00 00 00 nop
> > 160: 38 21 00 90 addi r1,r1,144
> > 164: 38 60 00 00 li r3,0
> > 168: e8 01 00 10 ld r0,16(r1)
> > 16c: eb 81 ff e0 ld r28,-32(r1)
> > 170: eb a1 ff e8 ld r29,-24(r1)
> > 174: eb c1 ff f0 ld r30,-16(r1)
> > 178: eb e1 ff f8 ld r31,-8(r1)
> > 17c: 7c 08 03 a6 mtlr r0
> > 180: 4e 80 00 20 blr
> > 184: e8 7e 80 30 ld r3,-32720(r30)
> > 188: 48 00 00 01 bl 188 <.kt_1+0xc8>
> > 18c: 60 00 00 00 nop
> > 190: 4b ff ff 8c b 11c <.kt_1+0x5c>
> > 194: 48 00 00 01 bl 194 <.kt_1+0xd4>
> > 198: 60 00 00 00 nop
> > 19c: 4b ff ff 8c b 128 <.kt_1+0x68>
> >
> > Unfortunately it tells me nothing, I do not know ppc.
> >
> > Oleg.
> >
> > --------------------------------------------------------------------------------
> > #include <linux/module.h>
> > #include <linux/kernel.h>
> > #include <linux/kthread.h>
> >
> > struct utrace {
> > unsigned int resume:3;
> > int freeze_stop;
> > };
> >
> > static int kt_1(void *arg)
> > {
> > struct utrace *u = arg;
> > int r = 0;
> >
> > while (!kthread_should_stop()) {
> > if (++r == 7)
> > r = 0;
> >
> > u->resume = r;
> > barrier();
> > if (u->resume != r)
> > printk(KERN_CRIT "BUG! bitfield\n");
> >
> > if (need_resched())
> > schedule();
> > }
> >
> > return 0;
> > }
> >
> > static int kt_2(void *arg)
> > {
> > struct utrace *u = arg;
> > int f = 0;
> >
> > while (!kthread_should_stop()) {
> > u->freeze_stop = ++f;
> > barrier();
> > if (u->freeze_stop != f)
> > printk(KERN_CRIT "BUG! freeze_stop %d != %d\n", u->freeze_stop, f);
> >
> > if (need_resched())
> > schedule();
> > }
> >
> > return 0;
> > }
> >
> > static struct task_struct *t_1, *t_2;
> >
> > static struct utrace utrace;
> >
> > static int __init mod_init(void)
> > {
> > WARN_ON(IS_ERR(t_1 = kthread_run(kt_1, &utrace, "kt_1")));
> > WARN_ON(IS_ERR(t_2 = kthread_run(kt_2, &utrace, "kt_2")));
> >
> > return 0;
> > }
> >
> > static void __exit mod_exit(void)
> > {
> > kthread_stop(t_1);
> > kthread_stop(t_2);
> > }
> >
> > MODULE_LICENSE("GPL");
> > module_init(mod_init);
> > module_exit(mod_exit);
^ permalink raw reply
* Re: [PATCH] powerpc: Disable RELOCATABLE for COMPILE_TEST with PPC64
From: Nick Krause @ 2014-07-13 6:02 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev, Paul Mackerras, linux-kernel@vger.kernel.org,
Guenter Roeck
In-Reply-To: <1404789011.16156.39.camel@pasglop>
On Mon, Jul 7, 2014 at 11:10 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2014-07-07 at 20:03 -0700, Guenter Roeck wrote:
>> ping ...
>>
>> Ben, I know this is not perfect, but on the other side it is simple
>> and would be easy to backport. With this in place, a complete/clean
>> fix would not be as urgent. Any chance to get it applied ?
>
> Yes, that definitely helps, I'll include it as a band aid.
>
> Cheers,
> Ben.
>
>> Nick, this doesn't fix the allyesconfig build - it still fails with
>> relocation errors. But it does fix the allmodconfig build.
>>
>> Thanks,
>> Guenter
>>
>> On 06/30/2014 11:45 AM, Guenter Roeck wrote:
>> > powerpc:allmodconfig has been failing for some time with the following
>> > error.
>> >
>> > arch/powerpc/kernel/exceptions-64s.S: Assembler messages:
>> > arch/powerpc/kernel/exceptions-64s.S:1312: Error: attempt to move .org backwards
>> > make[1]: *** [arch/powerpc/kernel/head_64.o] Error 1
>> >
>> > A number of attempts to fix the problem by moving around code have been
>> > unsuccessful and resulted in failed builds for some configurations and
>> > the discovery of toolchain bugs.
>> >
>> > Fix the problem by disabling RELOCATABLE for COMPILE_TEST builds instead.
>> > While this is less than perfect, it avoids substantial code changes
>> > which would otherwise be necessary just to make COMPILE_TEST builds
>> > happy and might have undesired side effects.
>> >
>> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> > ---
>> > arch/powerpc/Kconfig | 3 ++-
>> > 1 file changed, 2 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> > index bd6dd6e..fefe7c8 100644
>> > --- a/arch/powerpc/Kconfig
>> > +++ b/arch/powerpc/Kconfig
>> > @@ -414,7 +414,7 @@ config KEXEC
>> > config CRASH_DUMP
>> > bool "Build a kdump crash kernel"
>> > depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP)
>> > - select RELOCATABLE if PPC64 || 44x || FSL_BOOKE
>> > + select RELOCATABLE if (PPC64 && !COMPILE_TEST) || 44x || FSL_BOOKE
>> > help
>> > Build a kernel suitable for use as a kdump capture kernel.
>> > The same kernel binary can be used as production kernel and dump
>> > @@ -1017,6 +1017,7 @@ endmenu
>> > if PPC64
>> > config RELOCATABLE
>> > bool "Build a relocatable kernel"
>> > + depends on !COMPILE_TEST
>> > select NONSTATIC_KERNEL
>> > help
>> > This builds a kernel image that is capable of running anywhere
>> >
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
>
>
Thanks for applying the patch. Works for me too.Sorry about the late
reply working on other build
issues and fix me messages.
Nick
^ permalink raw reply
* Re: bit fields && data tearing
From: Oleg Nesterov @ 2014-07-13 12:29 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Jakub Jelinek, linux-kernel, Paul Mackerras, Dan,
Paul E. McKenney, linuxppc-dev, Miroslav Franc, Richard Henderson
In-Reply-To: <1405208082.20996.54.camel@pasglop>
On 07/13, Benjamin Herrenschmidt wrote:
>
> On Sat, 2014-07-12 at 22:51 +0200, Oleg Nesterov wrote:
> > OK, looks like this is compiler bug,
> >
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
> >
> > Thanks to Dan who informed me privately.
>
> So yes, there's is this compiler bug which means a bitfield
> access can cause a r-m-w access to a neighbouring field
Thanks. So I can forward this all back to bugzilla.
> but
> in general, I would be weary of bitfields anyway since accessing
> them isn't going to be atomic anyway... it's too easy to get things
> wrong and in most cases the benefit is yet to be demonstrated.
Sure, bit fields should be used with care. But the same arguments apply
to bitmasks, they are often used without "atomic" set/clear_bit.
> In your example, I don't see the point of the bitfield.
This is just test-case. The real code has more adjacent bit fields, only
the tracee can modify them, and only debugger can change ->freeze_stop.
Thanks,
Oleg.
^ permalink raw reply
* Re: bit fields && data tearing
From: Peter Hurley @ 2014-07-13 13:15 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Oleg Nesterov
Cc: Jakub Jelinek, linux-kernel, Paul Mackerras, Dan,
Paul E. McKenney, linuxppc-dev, Miroslav Franc, Richard Henderson
In-Reply-To: <1405208082.20996.54.camel@pasglop>
On 07/12/2014 07:34 PM, Benjamin Herrenschmidt wrote:
> On Sat, 2014-07-12 at 22:51 +0200, Oleg Nesterov wrote:
>> OK, looks like this is compiler bug,
>>
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
>>
>> Thanks to Dan who informed me privately.
>
> So yes, there's is this compiler bug which means a bitfield
> access can cause a r-m-w access to a neighbouring field but
> in general, I would be weary of bitfields anyway since accessing
> them isn't going to be atomic anyway... it's too easy to get things
> wrong and in most cases the benefit is yet to be demonstrated.
I'm not sure I understand your point here, Ben.
Suppose that two different spinlocks are used independently to
protect r-m-w access to adjacent data. In Oleg's example,
suppose spinlock 1 is used for access to the bitfield and
spinlock 2 is used for access to freeze_stop.
What would prevent an accidental write to freeze_stop from the
kt_1 thread?
Regards,
Peter Hurley
> In your example, I don't see the point of the bitfield.
>
> Cheers,
> Ben.
>
>> On 07/12, Oleg Nesterov wrote:
>>>
>>> Hello,
>>>
>>> I am not sure I should ask here, but since Documentation/memory-barriers.txt
>>> mentions load/store tearing perhaps my question is not completely off-topic...
>>>
>>> I am fighting with mysterious RHEL bug, it can be reproduced on ppc and s390
>>> but not on x86. Finally I seem to understand the problem, and I even wrote the
>>> stupid kernel module to ensure, see it below at the end.
>>>
>>> It triggers the problem immediately, kt_2() sees the wrong value in freeze_stop.
>>> (If I turn ->freeze_stop int "long", the problem goes away).
>>>
>>> So the question is: is this gcc bug or the code below is buggy?
>>>
>>> If it is buggy, then probably memory-barriers.txt could mention that you should
>>> be carefull with bit fields, even ACCESS_ONCE() obviously can't help.
>>>
>>> Or this just discloses my ignorance and you need at least aligned(long) after a
>>> bit field to be thread-safe ? I thought that compiler should take care and add
>>> the necessary alignment if (say) CPU can't update a single byte/uint.
>>>
>>> gcc version 4.4.7 20120313 (Red Hat 4.4.7-9) (GCC). Asm:
>>>
>>> 0000000000000000 <.kt_2>:
>>> 0: 7c 08 02 a6 mflr r0
>>> 4: fb 81 ff e0 std r28,-32(r1)
>>> 8: fb a1 ff e8 std r29,-24(r1)
>>> c: fb c1 ff f0 std r30,-16(r1)
>>> 10: fb e1 ff f8 std r31,-8(r1)
>>> 14: eb c2 00 00 ld r30,0(r2)
>>> 18: f8 01 00 10 std r0,16(r1)
>>> 1c: f8 21 ff 71 stdu r1,-144(r1)
>>> 20: 7c 7d 1b 78 mr r29,r3
>>> 24: 3b e0 00 00 li r31,0
>>> 28: 78 3c 04 64 rldicr r28,r1,0,49
>>> 2c: 3b 9c 00 80 addi r28,r28,128
>>> 30: 48 00 00 2c b 5c <.kt_2+0x5c>
>>> 34: 60 00 00 00 nop
>>> 38: 60 00 00 00 nop
>>> 3c: 60 00 00 00 nop
>>> 40: 93 fd 00 04 stw r31,4(r29)
>>> 44: e8 9d 00 06 lwa r4,4(r29)
>>> 48: 7f 84 f8 00 cmpw cr7,r4,r31
>>> 4c: 40 de 00 4c bne- cr7,98 <.kt_2+0x98>
>>> 50: e8 1c 00 00 ld r0,0(r28)
>>> 54: 78 09 f7 e3 rldicl. r9,r0,62,63
>>> 58: 40 c2 00 54 bne- ac <.kt_2+0xac>
>>> 5c: 48 00 00 01 bl 5c <.kt_2+0x5c>
>>> 60: 60 00 00 00 nop
>>> 64: 3b ff 00 01 addi r31,r31,1
>>> 68: 2f a3 00 00 cmpdi cr7,r3,0
>>> 6c: 7f ff 07 b4 extsw r31,r31
>>> 70: 41 9e ff d0 beq+ cr7,40 <.kt_2+0x40>
>>> 74: 38 21 00 90 addi r1,r1,144
>>> 78: 38 60 00 00 li r3,0
>>> 7c: e8 01 00 10 ld r0,16(r1)
>>> 80: eb 81 ff e0 ld r28,-32(r1)
>>> 84: eb a1 ff e8 ld r29,-24(r1)
>>> 88: eb c1 ff f0 ld r30,-16(r1)
>>> 8c: eb e1 ff f8 ld r31,-8(r1)
>>> 90: 7c 08 03 a6 mtlr r0
>>> 94: 4e 80 00 20 blr
>>> 98: e8 7e 80 28 ld r3,-32728(r30)
>>> 9c: 7f e5 fb 78 mr r5,r31
>>> a0: 48 00 00 01 bl a0 <.kt_2+0xa0>
>>> a4: 60 00 00 00 nop
>>> a8: 4b ff ff a8 b 50 <.kt_2+0x50>
>>> ac: 48 00 00 01 bl ac <.kt_2+0xac>
>>> b0: 60 00 00 00 nop
>>> b4: 4b ff ff a8 b 5c <.kt_2+0x5c>
>>> b8: 60 00 00 00 nop
>>> bc: 60 00 00 00 nop
>>>
>>> 00000000000000c0 <.kt_1>:
>>> c0: 7c 08 02 a6 mflr r0
>>> c4: fb 81 ff e0 std r28,-32(r1)
>>> c8: fb a1 ff e8 std r29,-24(r1)
>>> cc: fb c1 ff f0 std r30,-16(r1)
>>> d0: fb e1 ff f8 std r31,-8(r1)
>>> d4: eb c2 00 00 ld r30,0(r2)
>>> d8: f8 01 00 10 std r0,16(r1)
>>> dc: f8 21 ff 71 stdu r1,-144(r1)
>>> e0: 7c 7d 1b 78 mr r29,r3
>>> e4: 3b e0 00 00 li r31,0
>>> e8: 78 3c 04 64 rldicr r28,r1,0,49
>>> ec: 3b 9c 00 80 addi r28,r28,128
>>> f0: 48 00 00 38 b 128 <.kt_1+0x68>
>>> f4: 60 00 00 00 nop
>>> f8: 60 00 00 00 nop
>>> fc: 60 00 00 00 nop
>>> 100: e8 1d 00 00 ld r0,0(r29)
>>> 104: 79 20 e8 0e rldimi r0,r9,61,0
>>> 108: f8 1d 00 00 std r0,0(r29)
>>> 10c: 80 1d 00 00 lwz r0,0(r29)
>>> 110: 54 00 1f 7e rlwinm r0,r0,3,29,31
>>> 114: 7f 80 f8 00 cmpw cr7,r0,r31
>>> 118: 40 de 00 6c bne- cr7,184 <.kt_1+0xc4>
>>> 11c: e8 1c 00 00 ld r0,0(r28)
>>> 120: 78 09 f7 e3 rldicl. r9,r0,62,63
>>> 124: 40 c2 00 70 bne- 194 <.kt_1+0xd4>
>>> 128: 48 00 00 01 bl 128 <.kt_1+0x68>
>>> 12c: 60 00 00 00 nop
>>> 130: 3b ff 00 01 addi r31,r31,1
>>> 134: 2f a3 00 00 cmpdi cr7,r3,0
>>> 138: 7f ff 07 b4 extsw r31,r31
>>> 13c: 2f 1f 00 07 cmpwi cr6,r31,7
>>> 140: 7b e9 07 60 clrldi r9,r31,61
>>> 144: 40 9e 00 1c bne- cr7,160 <.kt_1+0xa0>
>>> 148: 40 9a ff b8 bne+ cr6,100 <.kt_1+0x40>
>>> 14c: 39 20 00 00 li r9,0
>>> 150: 3b e0 00 00 li r31,0
>>> 154: 4b ff ff ac b 100 <.kt_1+0x40>
>>> 158: 60 00 00 00 nop
>>> 15c: 60 00 00 00 nop
>>> 160: 38 21 00 90 addi r1,r1,144
>>> 164: 38 60 00 00 li r3,0
>>> 168: e8 01 00 10 ld r0,16(r1)
>>> 16c: eb 81 ff e0 ld r28,-32(r1)
>>> 170: eb a1 ff e8 ld r29,-24(r1)
>>> 174: eb c1 ff f0 ld r30,-16(r1)
>>> 178: eb e1 ff f8 ld r31,-8(r1)
>>> 17c: 7c 08 03 a6 mtlr r0
>>> 180: 4e 80 00 20 blr
>>> 184: e8 7e 80 30 ld r3,-32720(r30)
>>> 188: 48 00 00 01 bl 188 <.kt_1+0xc8>
>>> 18c: 60 00 00 00 nop
>>> 190: 4b ff ff 8c b 11c <.kt_1+0x5c>
>>> 194: 48 00 00 01 bl 194 <.kt_1+0xd4>
>>> 198: 60 00 00 00 nop
>>> 19c: 4b ff ff 8c b 128 <.kt_1+0x68>
>>>
>>> Unfortunately it tells me nothing, I do not know ppc.
>>>
>>> Oleg.
>>>
>>> --------------------------------------------------------------------------------
>>> #include <linux/module.h>
>>> #include <linux/kernel.h>
>>> #include <linux/kthread.h>
>>>
>>> struct utrace {
>>> unsigned int resume:3;
>>> int freeze_stop;
>>> };
>>>
>>> static int kt_1(void *arg)
>>> {
>>> struct utrace *u = arg;
>>> int r = 0;
>>>
>>> while (!kthread_should_stop()) {
>>> if (++r == 7)
>>> r = 0;
>>>
>>> u->resume = r;
>>> barrier();
>>> if (u->resume != r)
>>> printk(KERN_CRIT "BUG! bitfield\n");
>>>
>>> if (need_resched())
>>> schedule();
>>> }
>>>
>>> return 0;
>>> }
>>>
>>> static int kt_2(void *arg)
>>> {
>>> struct utrace *u = arg;
>>> int f = 0;
>>>
>>> while (!kthread_should_stop()) {
>>> u->freeze_stop = ++f;
>>> barrier();
>>> if (u->freeze_stop != f)
>>> printk(KERN_CRIT "BUG! freeze_stop %d != %d\n", u->freeze_stop, f);
>>>
>>> if (need_resched())
>>> schedule();
>>> }
>>>
>>> return 0;
>>> }
>>>
>>> static struct task_struct *t_1, *t_2;
>>>
>>> static struct utrace utrace;
>>>
>>> static int __init mod_init(void)
>>> {
>>> WARN_ON(IS_ERR(t_1 = kthread_run(kt_1, &utrace, "kt_1")));
>>> WARN_ON(IS_ERR(t_2 = kthread_run(kt_2, &utrace, "kt_2")));
>>>
>>> return 0;
>>> }
>>>
>>> static void __exit mod_exit(void)
>>> {
>>> kthread_stop(t_1);
>>> kthread_stop(t_2);
>>> }
>>>
>>> MODULE_LICENSE("GPL");
>>> module_init(mod_init);
>>> module_exit(mod_exit);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* [PATCH v3] arm64, ia64, ppc, s390, sh, tile, um, x86, mm: Remove default gate area
From: Andy Lutomirski @ 2014-07-13 20:01 UTC (permalink / raw)
Cc: linux-ia64, linux-sh, Catalin Marinas, Heiko Carstens, linux-mm,
Paul Mackerras, H. Peter Anvin, linux-arch, linux-s390,
Richard Weinberger, x86, Ingo Molnar, Fenghua Yu,
user-mode-linux-devel, Will Deacon, Jeff Dike, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Tony Luck, Nathan Lynch,
linux-kernel, Andy Lutomirski, Martin Schwidefsky, linux390,
linuxppc-dev
The core mm code will provide a default gate area based on
FIXADDR_USER_START and FIXADDR_USER_END if
!defined(__HAVE_ARCH_GATE_AREA) && defined(AT_SYSINFO_EHDR).
This default is only useful for ia64. arm64, ppc, s390, sh, tile,
64-bit UML, and x86_32 have their own code just to disable it. arm,
32-bit UML, and x86_64 have gate areas, but they have their own
implementations.
This gets rid of the default and moves the code into ia64.
This should save some code on architectures without a gate area: it's
now possible to inline the gate_area functions in the default case.
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Nathan Lynch <Nathan_Lynch@mentor.com>
Cc: x86@kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: linux-mm@kvack.org
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
It would be nice to get this into some tree that's in -next and that
people can base on.
Changes from v1 and v2: Nothing except Will Deacon's ack and splitting
this out from the larger series.
arch/arm64/include/asm/page.h | 3 ---
arch/arm64/kernel/vdso.c | 19 -------------------
arch/ia64/include/asm/page.h | 2 ++
arch/ia64/mm/init.c | 26 ++++++++++++++++++++++++++
arch/powerpc/include/asm/page.h | 3 ---
arch/powerpc/kernel/vdso.c | 16 ----------------
arch/s390/include/asm/page.h | 2 --
arch/s390/kernel/vdso.c | 15 ---------------
arch/sh/include/asm/page.h | 5 -----
arch/sh/kernel/vsyscall/vsyscall.c | 15 ---------------
arch/tile/include/asm/page.h | 6 ------
arch/tile/kernel/vdso.c | 15 ---------------
arch/um/include/asm/page.h | 5 +++++
arch/x86/include/asm/page.h | 1 -
arch/x86/include/asm/page_64.h | 2 ++
arch/x86/um/asm/elf.h | 1 -
arch/x86/um/mem_64.c | 15 ---------------
arch/x86/vdso/vdso32-setup.c | 19 +------------------
include/linux/mm.h | 17 ++++++++++++-----
mm/memory.c | 38 --------------------------------------
mm/nommu.c | 5 -----
21 files changed, 48 insertions(+), 182 deletions(-)
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 46bf666..992710f 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -28,9 +28,6 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
-#define __HAVE_ARCH_GATE_AREA 1
-
#ifndef __ASSEMBLY__
#ifdef CONFIG_ARM64_64K_PAGES
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 50384fe..f630626 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -187,25 +187,6 @@ const char *arch_vma_name(struct vm_area_struct *vma)
}
/*
- * We define AT_SYSINFO_EHDR, so we need these function stubs to keep
- * Linux happy.
- */
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return 0;
-}
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
-/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
void update_vsyscall(struct timekeeper *tk)
diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h
index f1e1b2e..1f1bf14 100644
--- a/arch/ia64/include/asm/page.h
+++ b/arch/ia64/include/asm/page.h
@@ -231,4 +231,6 @@ get_order (unsigned long size)
#define PERCPU_ADDR (-PERCPU_PAGE_SIZE)
#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE)
+#define __HAVE_ARCH_GATE_AREA 1
+
#endif /* _ASM_IA64_PAGE_H */
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 25c3502..35efaa3 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -278,6 +278,32 @@ setup_gate (void)
ia64_patch_gate();
}
+static struct vm_area_struct gate_vma;
+
+static int __init gate_vma_init(void)
+{
+ gate_vma.vm_mm = NULL;
+ gate_vma.vm_start = FIXADDR_USER_START;
+ gate_vma.vm_end = FIXADDR_USER_END;
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
+ gate_vma.vm_page_prot = __P101;
+
+ return 0;
+}
+__initcall(gate_vma_init);
+
+struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+ return &gate_vma;
+}
+
+int in_gate_area_no_mm(unsigned long addr)
+{
+ if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END))
+ return 1;
+ return 0;
+}
+
void ia64_mmu_init(void *my_cpu_data)
{
unsigned long pta, impl_va_bits;
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 32e4e21..26fe1ae 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -48,9 +48,6 @@ extern unsigned int HPAGE_SHIFT;
#define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1)
#endif
-/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
-#define __HAVE_ARCH_GATE_AREA 1
-
/*
* Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So if we
* assign PAGE_MASK to a larger type it gets extended the way we want
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ce74c33..f174351 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -840,19 +840,3 @@ static int __init vdso_init(void)
return 0;
}
arch_initcall(vdso_init);
-
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return 0;
-}
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 114258e..7b2ac6e 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -162,6 +162,4 @@ static inline int devmem_is_allowed(unsigned long pfn)
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
-#define __HAVE_ARCH_GATE_AREA 1
-
#endif /* _S390_PAGE_H */
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 6136490..0bbb7e0 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -316,18 +316,3 @@ static int __init vdso_init(void)
return 0;
}
early_initcall(vdso_init);
-
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return 0;
-}
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 15d9703..fe20d14 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -186,11 +186,6 @@ typedef struct page *pgtable_t;
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
-/* vDSO support */
-#ifdef CONFIG_VSYSCALL
-#define __HAVE_ARCH_GATE_AREA
-#endif
-
/*
* Some drivers need to perform DMA into kmalloc'ed buffers
* and so we have to increase the kmalloc minalign for this.
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
index 5ca5797..ea2aa13 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.c
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -92,18 +92,3 @@ const char *arch_vma_name(struct vm_area_struct *vma)
return NULL;
}
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long address)
-{
- return 0;
-}
-
-int in_gate_area_no_mm(unsigned long address)
-{
- return 0;
-}
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index 6727680..a213a8d 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -39,12 +39,6 @@
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
/*
- * We do define AT_SYSINFO_EHDR to support vDSO,
- * but don't use the gate mechanism.
- */
-#define __HAVE_ARCH_GATE_AREA 1
-
-/*
* If the Kconfig doesn't specify, set a maximum zone order that
* is enough so that we can create huge pages from small pages given
* the respective sizes of the two page types. See <linux/mmzone.h>.
diff --git a/arch/tile/kernel/vdso.c b/arch/tile/kernel/vdso.c
index 1533af2..5bc51d7 100644
--- a/arch/tile/kernel/vdso.c
+++ b/arch/tile/kernel/vdso.c
@@ -121,21 +121,6 @@ const char *arch_vma_name(struct vm_area_struct *vma)
return NULL;
}
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long address)
-{
- return 0;
-}
-
-int in_gate_area_no_mm(unsigned long address)
-{
- return 0;
-}
-
int setup_vdso_pages(void)
{
struct page **pagelist;
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
index 5ff53d9..71c5d13 100644
--- a/arch/um/include/asm/page.h
+++ b/arch/um/include/asm/page.h
@@ -119,4 +119,9 @@ extern unsigned long uml_physmem;
#include <asm-generic/getorder.h>
#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_X86_32
+#define __HAVE_ARCH_GATE_AREA 1
+#endif
+
#endif /* __UM_PAGE_H */
diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h
index 775873d..802dde3 100644
--- a/arch/x86/include/asm/page.h
+++ b/arch/x86/include/asm/page.h
@@ -70,7 +70,6 @@ extern bool __virt_addr_valid(unsigned long kaddr);
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
-#define __HAVE_ARCH_GATE_AREA 1
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#endif /* __KERNEL__ */
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index 0f1ddee..f408caf 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -39,4 +39,6 @@ void copy_page(void *to, void *from);
#endif /* !__ASSEMBLY__ */
+#define __HAVE_ARCH_GATE_AREA 1
+
#endif /* _ASM_X86_PAGE_64_H */
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h
index 0feee2f..25a1022 100644
--- a/arch/x86/um/asm/elf.h
+++ b/arch/x86/um/asm/elf.h
@@ -216,6 +216,5 @@ extern long elf_aux_hwcap;
#define ELF_HWCAP (elf_aux_hwcap)
#define SET_PERSONALITY(ex) do ; while(0)
-#define __HAVE_ARCH_GATE_AREA 1
#endif
diff --git a/arch/x86/um/mem_64.c b/arch/x86/um/mem_64.c
index c6492e7..f8fecad 100644
--- a/arch/x86/um/mem_64.c
+++ b/arch/x86/um/mem_64.c
@@ -9,18 +9,3 @@ const char *arch_vma_name(struct vm_area_struct *vma)
return NULL;
}
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return 0;
-}
-
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index e4f7781..e904c27 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -115,23 +115,6 @@ static __init int ia32_binfmt_init(void)
return 0;
}
__initcall(ia32_binfmt_init);
-#endif
-
-#else /* CONFIG_X86_32 */
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
- return NULL;
-}
-
-int in_gate_area(struct mm_struct *mm, unsigned long addr)
-{
- return 0;
-}
-
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
+#endif /* CONFIG_SYSCTL */
#endif /* CONFIG_X86_64 */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e03dd29..8981cc8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2014,13 +2014,20 @@ static inline bool kernel_page_present(struct page *page) { return true; }
#endif /* CONFIG_HIBERNATION */
#endif
+#ifdef __HAVE_ARCH_GATE_AREA
extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm);
-#ifdef __HAVE_ARCH_GATE_AREA
-int in_gate_area_no_mm(unsigned long addr);
-int in_gate_area(struct mm_struct *mm, unsigned long addr);
+extern int in_gate_area_no_mm(unsigned long addr);
+extern int in_gate_area(struct mm_struct *mm, unsigned long addr);
#else
-int in_gate_area_no_mm(unsigned long addr);
-#define in_gate_area(mm, addr) ({(void)mm; in_gate_area_no_mm(addr);})
+static inline struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+ return NULL;
+}
+static inline int in_gate_area_no_mm(unsigned long addr) { return 0; }
+static inline int in_gate_area(struct mm_struct *mm, unsigned long addr)
+{
+ return 0;
+}
#endif /* __HAVE_ARCH_GATE_AREA */
#ifdef CONFIG_SYSCTL
diff --git a/mm/memory.c b/mm/memory.c
index d67fd9f..099d234 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3399,44 +3399,6 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
}
#endif /* __PAGETABLE_PMD_FOLDED */
-#if !defined(__HAVE_ARCH_GATE_AREA)
-
-#if defined(AT_SYSINFO_EHDR)
-static struct vm_area_struct gate_vma;
-
-static int __init gate_vma_init(void)
-{
- gate_vma.vm_mm = NULL;
- gate_vma.vm_start = FIXADDR_USER_START;
- gate_vma.vm_end = FIXADDR_USER_END;
- gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
- gate_vma.vm_page_prot = __P101;
-
- return 0;
-}
-__initcall(gate_vma_init);
-#endif
-
-struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-{
-#ifdef AT_SYSINFO_EHDR
- return &gate_vma;
-#else
- return NULL;
-#endif
-}
-
-int in_gate_area_no_mm(unsigned long addr)
-{
-#ifdef AT_SYSINFO_EHDR
- if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END))
- return 1;
-#endif
- return 0;
-}
-
-#endif /* __HAVE_ARCH_GATE_AREA */
-
static int __follow_pte(struct mm_struct *mm, unsigned long address,
pte_t **ptepp, spinlock_t **ptlp)
{
diff --git a/mm/nommu.c b/mm/nommu.c
index 4a852f6..a881d96 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1981,11 +1981,6 @@ error:
return -ENOMEM;
}
-int in_gate_area_no_mm(unsigned long addr)
-{
- return 0;
-}
-
int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
BUG();
--
1.9.3
^ permalink raw reply related
* Re: bit fields && data tearing
From: Benjamin Herrenschmidt @ 2014-07-13 22:25 UTC (permalink / raw)
To: Peter Hurley
Cc: Jakub Jelinek, Oleg Nesterov, linux-kernel, Paul Mackerras, Dan,
Paul E. McKenney, linuxppc-dev, Miroslav Franc, Richard Henderson
In-Reply-To: <53C2865B.5040200@hurleysoftware.com>
On Sun, 2014-07-13 at 09:15 -0400, Peter Hurley wrote:
>
> I'm not sure I understand your point here, Ben.
>
> Suppose that two different spinlocks are used independently to
> protect r-m-w access to adjacent data. In Oleg's example,
> suppose spinlock 1 is used for access to the bitfield and
> spinlock 2 is used for access to freeze_stop.
>
> What would prevent an accidental write to freeze_stop from the
> kt_1 thread?
My point was to be weary of bitfields in general because access
to them is always R-M-W, never atomic and that seem to escape
people regularily :-) (Among other problems such as endian etc...)
As for Oleg's example, it *should* have worked because the bitfield and
the adjacent freeze_stop should have been accessed using load/stores
that don't actually overlap, but the compiler bug causes the bitfield
access to not properly use the basic type of the bitfield, but escalate
to a full 64-bit R-M-W instead, thus incorrectly R-M-W'ing the field
next door.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 2/2] PCI/MSI: Remove arch_msi_check_device()
From: Yijing Wang @ 2014-07-14 2:11 UTC (permalink / raw)
To: Alexander Gordeev, linux-kernel; +Cc: linux-pci, linuxppc-dev
In-Reply-To: <1005232855c3af2c0c669818ee63be445389b6ad.1405160163.git.agordeev@redhat.com>
> /**
> - * pci_msi_check_device - check whether MSI may be enabled on a device
> + * msi_check_device - check whether MSI may be enabled on a device
> * @dev: pointer to the pci_dev data structure of MSI device function
> * @nvec: how many MSIs have been requested ?
> - * @type: are we checking for MSI or MSI-X ?
> *
> * Look at global flags, the device itself, and its parent buses
> * to determine if MSI/-X are supported for the device. If MSI/-X is
> * supported return 0, else return an error code.
> **/
> -static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> +static int msi_check_device(struct pci_dev *dev, int nvec)
> {
> struct pci_bus *bus;
> - int ret;
>
> /* MSI must be globally enabled and supported by the device */
> - if (!pci_msi_enable || !dev || dev->no_msi)
> + if (!pci_msi_enable)
> + return -EINVAL;
> +
> + if (!dev || dev->no_msi || dev->current_state != PCI_D0)
> return -EINVAL;
>
> /*
> @@ -846,10 +837,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
> return -EINVAL;
>
> - ret = arch_msi_check_device(dev, nvec, type);
> - if (ret)
> - return ret;
> -
Move the arch_msi_check_device() into arch_msi_setup_irq(), make we can not detect whether the device in this platform
supports MSI or MSI-X aeap. If we delay this, maybe we will do a lot unnecessary working for MSI/MSI-X setup.
Thanks!
Yijing.
> return 0;
> }
>
> @@ -954,13 +941,13 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
> int status, nr_entries;
> int i, j;
>
> - if (!entries || !dev->msix_cap || dev->current_state != PCI_D0)
> - return -EINVAL;
> -
> - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX);
> + status = msi_check_device(dev, nvec);
> if (status)
> return status;
>
> + if (!entries)
> + return -EINVAL;
> +
> nr_entries = pci_msix_vec_count(dev);
> if (nr_entries < 0)
> return nr_entries;
> @@ -1085,8 +1072,9 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> int nvec;
> int rc;
>
> - if (dev->current_state != PCI_D0)
> - return -EINVAL;
> + rc = msi_check_device(dev, minvec);
> + if (rc)
> + return rc;
>
> WARN_ON(!!dev->msi_enabled);
>
> @@ -1109,17 +1097,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> nvec = maxvec;
>
> do {
> - rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
> - if (rc < 0) {
> - return rc;
> - } else if (rc > 0) {
> - if (rc < minvec)
> - return -ENOSPC;
> - nvec = rc;
> - }
> - } while (rc);
> -
> - do {
> rc = msi_capability_init(dev, nvec);
> if (rc < 0) {
> return rc;
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 92a2f99..3b873bc 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -59,7 +59,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
> void arch_teardown_msi_irq(unsigned int irq);
> int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
> void arch_teardown_msi_irqs(struct pci_dev *dev);
> -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
> void arch_restore_msi_irqs(struct pci_dev *dev);
>
> void default_teardown_msi_irqs(struct pci_dev *dev);
> @@ -76,8 +75,6 @@ struct msi_chip {
> int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
> struct msi_desc *desc);
> void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
> - int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
> - int nvec, int type);
> };
>
> #endif /* LINUX_MSI_H */
>
--
Thanks!
Yijing
^ 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