Christoph Hellwig <h...@lst.de> writes: > powerpc mantainers, There's only one of me.
> are you going to pick this up for the next -rc1? I'm waiting for it to > hit upstream before resending the coredump series. I thought you were going to take it in your series. Otherwise you'll be waiting 4 or more weeks before this hits rc1. I can put it in a topic branch if you're worried about merge conflicts. There's also the fcheck() RCU fix I need to repost as a proper patch, it seems to work. cheers > On Wed, Apr 29, 2020 at 03:03:02PM +0800, Jeremy Kerr wrote: >> Currently, we may perform a copy_to_user (through >> simple_read_from_buffer()) while holding a context's register_lock, >> while accessing the context save area. >> >> This change uses a temporary buffer for the context save area data, >> which we then pass to simple_read_from_buffer. >> >> Includes changes from Christoph Hellwig <h...@lst.de>. >> >> Fixes: bf1ab978be23 ("[POWERPC] coredump: Add SPU elf notes to coredump.") >> Signed-off-by: Jeremy Kerr <j...@ozlabs.org> >> Reviewed-by: Arnd Bergmann <a...@arndb.de> >> Reviewed-by: Christoph Hellwig <h...@lst.de> >> --- >> arch/powerpc/platforms/cell/spufs/file.c | 113 +++++++++++++++-------- >> 1 file changed, 75 insertions(+), 38 deletions(-) >> >> diff --git a/arch/powerpc/platforms/cell/spufs/file.c >> b/arch/powerpc/platforms/cell/spufs/file.c >> index c0f950a3f4e1..b4e1ef650b40 100644 >> --- a/arch/powerpc/platforms/cell/spufs/file.c >> +++ b/arch/powerpc/platforms/cell/spufs/file.c >> @@ -1978,8 +1978,9 @@ static ssize_t __spufs_mbox_info_read(struct >> spu_context *ctx, >> static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, >> size_t len, loff_t *pos) >> { >> - int ret; >> struct spu_context *ctx = file->private_data; >> + u32 stat, data; >> + int ret; >> >> if (!access_ok(buf, len)) >> return -EFAULT; >> @@ -1988,11 +1989,16 @@ static ssize_t spufs_mbox_info_read(struct file >> *file, char __user *buf, >> if (ret) >> return ret; >> spin_lock(&ctx->csa.register_lock); >> - ret = __spufs_mbox_info_read(ctx, buf, len, pos); >> + stat = ctx->csa.prob.mb_stat_R; >> + data = ctx->csa.prob.pu_mb_R; >> spin_unlock(&ctx->csa.register_lock); >> spu_release_saved(ctx); >> >> - return ret; >> + /* EOF if there's no entry in the mbox */ >> + if (!(stat & 0x0000ff)) >> + return 0; >> + >> + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); >> } >> >> static const struct file_operations spufs_mbox_info_fops = { >> @@ -2019,6 +2025,7 @@ static ssize_t spufs_ibox_info_read(struct file *file, >> char __user *buf, >> size_t len, loff_t *pos) >> { >> struct spu_context *ctx = file->private_data; >> + u32 stat, data; >> int ret; >> >> if (!access_ok(buf, len)) >> @@ -2028,11 +2035,16 @@ static ssize_t spufs_ibox_info_read(struct file >> *file, char __user *buf, >> if (ret) >> return ret; >> spin_lock(&ctx->csa.register_lock); >> - ret = __spufs_ibox_info_read(ctx, buf, len, pos); >> + stat = ctx->csa.prob.mb_stat_R; >> + data = ctx->csa.priv2.puint_mb_R; >> spin_unlock(&ctx->csa.register_lock); >> spu_release_saved(ctx); >> >> - return ret; >> + /* EOF if there's no entry in the ibox */ >> + if (!(stat & 0xff0000)) >> + return 0; >> + >> + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); >> } >> >> static const struct file_operations spufs_ibox_info_fops = { >> @@ -2041,6 +2053,11 @@ static const struct file_operations >> spufs_ibox_info_fops = { >> .llseek = generic_file_llseek, >> }; >> >> +static size_t spufs_wbox_info_cnt(struct spu_context *ctx) >> +{ >> + return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32); >> +} >> + >> static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, >> char __user *buf, size_t len, loff_t *pos) >> { >> @@ -2049,7 +2066,7 @@ static ssize_t __spufs_wbox_info_read(struct >> spu_context *ctx, >> u32 wbox_stat; >> >> wbox_stat = ctx->csa.prob.mb_stat_R; >> - cnt = 4 - ((wbox_stat & 0x00ff00) >> 8); >> + cnt = spufs_wbox_info_cnt(ctx); >> for (i = 0; i < cnt; i++) { >> data[i] = ctx->csa.spu_mailbox_data[i]; >> } >> @@ -2062,7 +2079,8 @@ static ssize_t spufs_wbox_info_read(struct file *file, >> char __user *buf, >> size_t len, loff_t *pos) >> { >> struct spu_context *ctx = file->private_data; >> - int ret; >> + u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)]; >> + int ret, count; >> >> if (!access_ok(buf, len)) >> return -EFAULT; >> @@ -2071,11 +2089,13 @@ static ssize_t spufs_wbox_info_read(struct file >> *file, char __user *buf, >> if (ret) >> return ret; >> spin_lock(&ctx->csa.register_lock); >> - ret = __spufs_wbox_info_read(ctx, buf, len, pos); >> + count = spufs_wbox_info_cnt(ctx); >> + memcpy(&data, &ctx->csa.spu_mailbox_data, sizeof(data)); >> spin_unlock(&ctx->csa.register_lock); >> spu_release_saved(ctx); >> >> - return ret; >> + return simple_read_from_buffer(buf, len, pos, &data, >> + count * sizeof(u32)); >> } >> >> static const struct file_operations spufs_wbox_info_fops = { >> @@ -2084,27 +2104,33 @@ static const struct file_operations >> spufs_wbox_info_fops = { >> .llseek = generic_file_llseek, >> }; >> >> -static ssize_t __spufs_dma_info_read(struct spu_context *ctx, >> - char __user *buf, size_t len, loff_t *pos) >> +static void ___spufs_dma_info_read(struct spu_context *ctx, >> + struct spu_dma_info *info) >> { >> - struct spu_dma_info info; >> - struct mfc_cq_sr *qp, *spuqp; >> int i; >> >> - info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; >> - info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; >> - info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; >> - info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; >> - info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; >> + info->dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; >> + info->dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; >> + info->dma_info_status = ctx->csa.spu_chnldata_RW[24]; >> + info->dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; >> + info->dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; >> for (i = 0; i < 16; i++) { >> - qp = &info.dma_info_command_data[i]; >> - spuqp = &ctx->csa.priv2.spuq[i]; >> + struct mfc_cq_sr *qp = &info->dma_info_command_data[i]; >> + struct mfc_cq_sr *spuqp = &ctx->csa.priv2.spuq[i]; >> >> qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; >> qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; >> qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; >> qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; >> } >> +} >> + >> +static ssize_t __spufs_dma_info_read(struct spu_context *ctx, >> + char __user *buf, size_t len, loff_t *pos) >> +{ >> + struct spu_dma_info info; >> + >> + ___spufs_dma_info_read(ctx, &info); >> >> return simple_read_from_buffer(buf, len, pos, &info, >> sizeof info); >> @@ -2114,6 +2140,7 @@ static ssize_t spufs_dma_info_read(struct file *file, >> char __user *buf, >> size_t len, loff_t *pos) >> { >> struct spu_context *ctx = file->private_data; >> + struct spu_dma_info info; >> int ret; >> >> if (!access_ok(buf, len)) >> @@ -2123,11 +2150,12 @@ static ssize_t spufs_dma_info_read(struct file >> *file, char __user *buf, >> if (ret) >> return ret; >> spin_lock(&ctx->csa.register_lock); >> - ret = __spufs_dma_info_read(ctx, buf, len, pos); >> + ___spufs_dma_info_read(ctx, &info); >> spin_unlock(&ctx->csa.register_lock); >> spu_release_saved(ctx); >> >> - return ret; >> + return simple_read_from_buffer(buf, len, pos, &info, >> + sizeof(info)); >> } >> >> static const struct file_operations spufs_dma_info_fops = { >> @@ -2136,13 +2164,31 @@ static const struct file_operations >> spufs_dma_info_fops = { >> .llseek = no_llseek, >> }; >> >> +static void ___spufs_proxydma_info_read(struct spu_context *ctx, >> + struct spu_proxydma_info *info) >> +{ >> + int i; >> + >> + info->proxydma_info_type = ctx->csa.prob.dma_querytype_RW; >> + info->proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; >> + info->proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; >> + >> + for (i = 0; i < 8; i++) { >> + struct mfc_cq_sr *qp = &info->proxydma_info_command_data[i]; >> + struct mfc_cq_sr *puqp = &ctx->csa.priv2.puq[i]; >> + >> + qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; >> + qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; >> + qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; >> + qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; >> + } >> +} >> + >> static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, >> char __user *buf, size_t len, loff_t *pos) >> { >> struct spu_proxydma_info info; >> - struct mfc_cq_sr *qp, *puqp; >> int ret = sizeof info; >> - int i; >> >> if (len < ret) >> return -EINVAL; >> @@ -2150,18 +2196,7 @@ static ssize_t __spufs_proxydma_info_read(struct >> spu_context *ctx, >> if (!access_ok(buf, len)) >> return -EFAULT; >> >> - info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; >> - info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; >> - info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; >> - for (i = 0; i < 8; i++) { >> - qp = &info.proxydma_info_command_data[i]; >> - puqp = &ctx->csa.priv2.puq[i]; >> - >> - qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; >> - qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; >> - qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; >> - qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; >> - } >> + ___spufs_proxydma_info_read(ctx, &info); >> >> return simple_read_from_buffer(buf, len, pos, &info, >> sizeof info); >> @@ -2171,17 +2206,19 @@ static ssize_t spufs_proxydma_info_read(struct file >> *file, char __user *buf, >> size_t len, loff_t *pos) >> { >> struct spu_context *ctx = file->private_data; >> + struct spu_proxydma_info info; >> int ret; >> >> ret = spu_acquire_saved(ctx); >> if (ret) >> return ret; >> spin_lock(&ctx->csa.register_lock); >> - ret = __spufs_proxydma_info_read(ctx, buf, len, pos); >> + ___spufs_proxydma_info_read(ctx, &info); >> spin_unlock(&ctx->csa.register_lock); >> spu_release_saved(ctx); >> >> - return ret; >> + return simple_read_from_buffer(buf, len, pos, &info, >> + sizeof(info)); >> } >> >> static const struct file_operations spufs_proxydma_info_fops = { >> -- >> 2.17.1 > ---end quoted text---