From 32927393dc1ccd60fb2bdc05b9e8e88753761469 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 24 Apr 2020 08:43:38 +0200 Subject: sysctl: pass kernel pointers to ->proc_handler Instead of having all the sysctl handlers deal with user pointers, which is rather hairy in terms of the BPF interaction, copy the input to and from userspace in common code. This also means that the strings are always NUL-terminated by the common code, making the API a little bit safer. As most handler just pass through the data to one of the common handlers a lot of the changes are mechnical. Signed-off-by: Christoph Hellwig Acked-by: Andrey Ignatov Signed-off-by: Al Viro --- arch/s390/appldata/appldata_base.c | 11 +++++------ arch/s390/kernel/debug.c | 2 +- arch/s390/kernel/topology.c | 2 +- arch/s390/mm/cmm.c | 12 +++++------- 4 files changed, 12 insertions(+), 15 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index aa738cad1338..d74a4c7d5df6 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -51,10 +51,9 @@ static struct platform_device *appldata_pdev; */ static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; static int appldata_timer_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); + void *buffer, size_t *lenp, loff_t *ppos); static int appldata_interval_handler(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos); + void *buffer, size_t *lenp, loff_t *ppos); static struct ctl_table_header *appldata_sysctl_header; static struct ctl_table appldata_table[] = { @@ -217,7 +216,7 @@ static void __appldata_vtimer_setup(int cmd) */ static int appldata_timer_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { int timer_active = appldata_timer_active; int rc; @@ -250,7 +249,7 @@ appldata_timer_handler(struct ctl_table *ctl, int write, */ static int appldata_interval_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { int interval = appldata_interval; int rc; @@ -280,7 +279,7 @@ appldata_interval_handler(struct ctl_table *ctl, int write, */ static int appldata_generic_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { struct appldata_ops *ops = NULL, *tmp_ops; struct list_head *lh; diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6d321f5f101d..636446003a06 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -867,7 +867,7 @@ static int debug_active = 1; * if debug_active is already off */ static int s390dbf_procactive(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { if (!write || debug_stoppable || !debug_active) return proc_dointvec(table, write, buffer, lenp, ppos); diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 5f70cefc13e4..332b542548cd 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -594,7 +594,7 @@ static int __init topology_setup(char *str) early_param("topology", topology_setup); static int topology_ctl_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { int enabled = topology_is_enabled(); int new_mode; diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index ae989b740376..36bce727897b 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -245,7 +245,7 @@ static int cmm_skip_blanks(char *cp, char **endp) } static int cmm_pages_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { long nr = cmm_get_pages(); struct ctl_table ctl_entry = { @@ -264,7 +264,7 @@ static int cmm_pages_handler(struct ctl_table *ctl, int write, } static int cmm_timed_pages_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, + void *buffer, size_t *lenp, loff_t *ppos) { long nr = cmm_get_timed_pages(); @@ -284,7 +284,7 @@ static int cmm_timed_pages_handler(struct ctl_table *ctl, int write, } static int cmm_timeout_handler(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { char buf[64], *p; long nr, seconds; @@ -297,8 +297,7 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write, if (write) { len = min(*lenp, sizeof(buf)); - if (copy_from_user(buf, buffer, len)) - return -EFAULT; + memcpy(buf, buffer, len); buf[len - 1] = '\0'; cmm_skip_blanks(buf, &p); nr = simple_strtoul(p, &p, 0); @@ -311,8 +310,7 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write, cmm_timeout_pages, cmm_timeout_seconds); if (len > *lenp) len = *lenp; - if (copy_to_user(buffer, buf, len)) - return -EFAULT; + memcpy(buffer, buf, len); *lenp = len; *ppos += len; } -- cgit v1.2.3 From fc4a4515acac072a69465d01ba45969323a9c50d Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 19 May 2020 21:09:03 +0200 Subject: s390/net: remove pm ops from ccwgroup drivers commit 5e1fb45ec8e2 ("s390/ccwgroup: remove pm support") removed power management support from the ccwgroup bus driver. So remove the associated callbacks from all ccwgroup drivers. CC: Vineeth Vijayan Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- arch/s390/include/asm/ccwgroup.h | 10 ------- drivers/s390/net/ctcm_main.c | 40 -------------------------- drivers/s390/net/lcs.c | 59 --------------------------------------- drivers/s390/net/qeth_core_main.c | 31 -------------------- 4 files changed, 140 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index 7293c139dd79..ad3acb1e882b 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -36,11 +36,6 @@ struct ccwgroup_device { * @set_online: function called when device is set online * @set_offline: function called when device is set offline * @shutdown: function called when device is shut down - * @prepare: prepare for pm state transition - * @complete: undo work done in @prepare - * @freeze: callback for freezing during hibernation snapshotting - * @thaw: undo work done in @freeze - * @restore: callback for restoring after hibernation * @driver: embedded driver structure * @ccw_driver: supported ccw_driver (optional) */ @@ -50,11 +45,6 @@ struct ccwgroup_driver { int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); void (*shutdown)(struct ccwgroup_device *); - int (*prepare) (struct ccwgroup_device *); - void (*complete) (struct ccwgroup_device *); - int (*freeze)(struct ccwgroup_device *); - int (*thaw) (struct ccwgroup_device *); - int (*restore)(struct ccwgroup_device *); struct device_driver driver; struct ccw_driver *ccw_driver; diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 437a6d822105..d06809eac16d 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1698,43 +1698,6 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev) put_device(&cgdev->dev); } -static int ctcm_pm_suspend(struct ccwgroup_device *gdev) -{ - struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev); - - if (gdev->state == CCWGROUP_OFFLINE) - return 0; - netif_device_detach(priv->channel[CTCM_READ]->netdev); - ctcm_close(priv->channel[CTCM_READ]->netdev); - if (!wait_event_timeout(priv->fsm->wait_q, - fsm_getstate(priv->fsm) == DEV_STATE_STOPPED, CTCM_TIME_5_SEC)) { - netif_device_attach(priv->channel[CTCM_READ]->netdev); - return -EBUSY; - } - ccw_device_set_offline(gdev->cdev[1]); - ccw_device_set_offline(gdev->cdev[0]); - return 0; -} - -static int ctcm_pm_resume(struct ccwgroup_device *gdev) -{ - struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev); - int rc; - - if (gdev->state == CCWGROUP_OFFLINE) - return 0; - rc = ccw_device_set_online(gdev->cdev[1]); - if (rc) - goto err_out; - rc = ccw_device_set_online(gdev->cdev[0]); - if (rc) - goto err_out; - ctcm_open(priv->channel[CTCM_READ]->netdev); -err_out: - netif_device_attach(priv->channel[CTCM_READ]->netdev); - return rc; -} - static struct ccw_device_id ctcm_ids[] = { {CCW_DEVICE(0x3088, 0x08), .driver_info = ctcm_channel_type_parallel}, {CCW_DEVICE(0x3088, 0x1e), .driver_info = ctcm_channel_type_ficon}, @@ -1764,9 +1727,6 @@ static struct ccwgroup_driver ctcm_group_driver = { .remove = ctcm_remove_device, .set_online = ctcm_new_device, .set_offline = ctcm_shutdown_device, - .freeze = ctcm_pm_suspend, - .thaw = ctcm_pm_resume, - .restore = ctcm_pm_resume, }; static ssize_t group_store(struct device_driver *ddrv, const char *buf, diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 8f08b0a2917c..440219bcaa2b 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -2296,60 +2296,6 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev) put_device(&ccwgdev->dev); } -static int lcs_pm_suspend(struct lcs_card *card) -{ - if (card->dev) - netif_device_detach(card->dev); - lcs_set_allowed_threads(card, 0); - lcs_wait_for_threads(card, 0xffffffff); - if (card->state != DEV_STATE_DOWN) - __lcs_shutdown_device(card->gdev, 1); - return 0; -} - -static int lcs_pm_resume(struct lcs_card *card) -{ - int rc = 0; - - if (card->state == DEV_STATE_RECOVER) - rc = lcs_new_device(card->gdev); - if (card->dev) - netif_device_attach(card->dev); - if (rc) { - dev_warn(&card->gdev->dev, "The lcs device driver " - "failed to recover the device\n"); - } - return rc; -} - -static int lcs_prepare(struct ccwgroup_device *gdev) -{ - return 0; -} - -static void lcs_complete(struct ccwgroup_device *gdev) -{ - return; -} - -static int lcs_freeze(struct ccwgroup_device *gdev) -{ - struct lcs_card *card = dev_get_drvdata(&gdev->dev); - return lcs_pm_suspend(card); -} - -static int lcs_thaw(struct ccwgroup_device *gdev) -{ - struct lcs_card *card = dev_get_drvdata(&gdev->dev); - return lcs_pm_resume(card); -} - -static int lcs_restore(struct ccwgroup_device *gdev) -{ - struct lcs_card *card = dev_get_drvdata(&gdev->dev); - return lcs_pm_resume(card); -} - static struct ccw_device_id lcs_ids[] = { {CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel}, {CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216}, @@ -2382,11 +2328,6 @@ static struct ccwgroup_driver lcs_group_driver = { .remove = lcs_remove_device, .set_online = lcs_new_device, .set_offline = lcs_shutdown_device, - .prepare = lcs_prepare, - .complete = lcs_complete, - .freeze = lcs_freeze, - .thaw = lcs_thaw, - .restore = lcs_restore, }; static ssize_t group_store(struct device_driver *ddrv, const char *buf, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index db8e069be3a0..18a0fb75a710 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6434,32 +6434,6 @@ static void qeth_core_shutdown(struct ccwgroup_device *gdev) qdio_free(CARD_DDEV(card)); } -static int qeth_suspend(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - - qeth_set_allowed_threads(card, 0, 1); - wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); - if (gdev->state == CCWGROUP_OFFLINE) - return 0; - - qeth_set_offline(card, false); - return 0; -} - -static int qeth_resume(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - int rc; - - rc = qeth_set_online(card); - - qeth_set_allowed_threads(card, 0xffffffff, 0); - if (rc) - dev_warn(&card->gdev->dev, "The qeth device driver failed to recover an error on the device\n"); - return rc; -} - static ssize_t group_store(struct device_driver *ddrv, const char *buf, size_t count) { @@ -6496,11 +6470,6 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { .set_online = qeth_core_set_online, .set_offline = qeth_core_set_offline, .shutdown = qeth_core_shutdown, - .prepare = NULL, - .complete = NULL, - .freeze = qeth_suspend, - .thaw = qeth_resume, - .restore = qeth_resume, }; struct qeth_card *qeth_get_card_by_busid(char *bus_id) -- cgit v1.2.3 From effe5be17706167ee968fa28afe40dec9c6f71db Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 2 Jun 2020 19:43:39 +0200 Subject: s390/bpf: Maintain 8-byte stack alignment Certain kernel functions (e.g. get_vtimer/set_vtimer) cause kernel panic when the stack is not 8-byte aligned. Currently JITed BPF programs may trigger this by allocating stack frames with non-rounded sizes and then being interrupted. Fix by using rounded fp->aux->stack_depth. Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20200602174339.2501066-1-iii@linux.ibm.com --- arch/s390/net/bpf_jit_comp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 8d2134136290..0f37a1b635f8 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -594,7 +594,7 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth) * stack space for the large switch statement. */ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, - int i, bool extra_pass) + int i, bool extra_pass, u32 stack_depth) { struct bpf_insn *insn = &fp->insnsi[i]; u32 dst_reg = insn->dst_reg; @@ -1207,7 +1207,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, */ if (jit->seen & SEEN_STACK) - off = STK_OFF_TCCNT + STK_OFF + fp->aux->stack_depth; + off = STK_OFF_TCCNT + STK_OFF + stack_depth; else off = STK_OFF_TCCNT; /* lhi %w0,1 */ @@ -1249,7 +1249,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, /* * Restore registers before calling function */ - save_restore_regs(jit, REGS_RESTORE, fp->aux->stack_depth); + save_restore_regs(jit, REGS_RESTORE, stack_depth); /* * goto *(prog->bpf_func + tail_call_start); @@ -1519,7 +1519,7 @@ static int bpf_set_addr(struct bpf_jit *jit, int i) * Compile eBPF program into s390x code */ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp, - bool extra_pass) + bool extra_pass, u32 stack_depth) { int i, insn_count, lit32_size, lit64_size; @@ -1527,18 +1527,18 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp, jit->lit64 = jit->lit64_start; jit->prg = 0; - bpf_jit_prologue(jit, fp->aux->stack_depth); + bpf_jit_prologue(jit, stack_depth); if (bpf_set_addr(jit, 0) < 0) return -1; for (i = 0; i < fp->len; i += insn_count) { - insn_count = bpf_jit_insn(jit, fp, i, extra_pass); + insn_count = bpf_jit_insn(jit, fp, i, extra_pass, stack_depth); if (insn_count < 0) return -1; /* Next instruction address */ if (bpf_set_addr(jit, i + insn_count) < 0) return -1; } - bpf_jit_epilogue(jit, fp->aux->stack_depth); + bpf_jit_epilogue(jit, stack_depth); lit32_size = jit->lit32 - jit->lit32_start; lit64_size = jit->lit64 - jit->lit64_start; @@ -1569,6 +1569,7 @@ struct s390_jit_data { */ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) { + u32 stack_depth = round_up(fp->aux->stack_depth, 8); struct bpf_prog *tmp, *orig_fp = fp; struct bpf_binary_header *header; struct s390_jit_data *jit_data; @@ -1621,7 +1622,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) * - 3: Calculate program size and addrs arrray */ for (pass = 1; pass <= 3; pass++) { - if (bpf_jit_prog(&jit, fp, extra_pass)) { + if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) { fp = orig_fp; goto free_addrs; } @@ -1635,7 +1636,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) goto free_addrs; } skip_init_ctx: - if (bpf_jit_prog(&jit, fp, extra_pass)) { + if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) { bpf_jit_binary_free(header); fp = orig_fp; goto free_addrs; -- cgit v1.2.3 From 33d21f18204cb33b43ca6c78c8180949f6dc7227 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 2 Jun 2020 19:45:55 +0200 Subject: s390/bpf: Use bcr 0,%0 as tail call nop filler Currently used 0x0000 filler confuses bfd disassembler, making bpftool prog dump xlated output nearly useless. Fix by using a real instruction. Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20200602174555.2501389-1-iii@linux.ibm.com --- arch/s390/net/bpf_jit_comp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/s390') diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 0f37a1b635f8..f4242b894cf2 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -503,7 +503,8 @@ static void bpf_jit_prologue(struct bpf_jit *jit, u32 stack_depth) } else { /* j tail_call_start: NOP if no tail calls are used */ EMIT4_PCREL(0xa7f40000, 6); - _EMIT2(0); + /* bcr 0,%0 */ + EMIT2(0x0700, 0, REG_0); } /* Tail calls have to skip above initialization */ jit->tail_call_start = jit->prg; -- cgit v1.2.3