Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5072234imu; Tue, 25 Dec 2018 17:09:32 -0800 (PST) X-Google-Smtp-Source: ALg8bN6yTyTIQwC06TBs3rpEd4PiiRe3H6kAXRJDM324AImkoLo//cEwWZ75qnZns3Lby1rb0vPX X-Received: by 2002:a17:902:780c:: with SMTP id p12mr17534806pll.197.1545786572268; Tue, 25 Dec 2018 17:09:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545786572; cv=none; d=google.com; s=arc-20160816; b=0Li1Co6FjxHuAcclmKu8XmNugwXfiqiYz8FW8N4zWeFOzUazsOOsBRbHLCIpWVI8a5 2JwgVw+9m2BGa66xyJpPpILiHiQuI9oaKF4mCEiQvTQxgDMURi+ljrIKn4rFPGWcAzaK SKuo9tiRmK9/gIBzNP2LoVCjBIHu349XyzhIp/cE3MGKa35wWpCfhd1ySl1SJOtfDkBH 6QnCDMtv9xtlaY4+e5/WSiMaOKtzIZFmVGeoNyPkiUPCZgZP27XFbai0gA3RTDri3D8E RT4GUDLfdpavXpFEzgdlivSGJ0VsvlleOaOMUcD356pL/sRJMKU2Ek8833j7hliLywQ0 joQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:subject:from:references:in-reply-to :message-id:cc:to; bh=EdHi3a87cSyA9l3LdoLzI/0jFqE2wjDLTBUBPc17gLc=; b=zvqT2HJSJ/N7GAtwuKnnnjHCeRiVQVnnHxyt35zpcPctXNYV0EPfP5BEpPraBPCQkd 35B4D85/1dyk+OAvR4djik3rI0Dm2BjtRXsP4ZIqWcz5Z/c6/LfDTUEYZtfMTJcXr4F6 i89x9LXefTpqoH36In1YwivHr6INMHJ1Z1MwBEVP5cTsZShx4r8aS0+jCCLdiIJajMFE 1QGLCqTrvCMKcPDeZGWf0BZKo0TTm56Nlu7cz4KOTfOlesXZ7K8hvV0hCB3b7+zWtpXj z5GDjJ/6dCGSyr7F5w8cPoVRG+fRsjLPPQToz2pGdSPzfLfc+e8yrk8OdrldA1UqnoOQ qHUQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j29si30615374pgm.554.2018.12.25.17.09.16; Tue, 25 Dec 2018 17:09:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726902AbeLZAob (ORCPT + 99 others); Tue, 25 Dec 2018 19:44:31 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:57384 "EHLO kvm5.telegraphics.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726865AbeLZAoC (ORCPT ); Tue, 25 Dec 2018 19:44:02 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 2115F2952E; Tue, 25 Dec 2018 19:43:57 -0500 (EST) To: Arnd Bergmann , Greg Kroah-Hartman , Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman Cc: linux-kernel@vger.kernel.org, linux-m68k@lists.linux-m68k.org, linuxppc-dev@lists.ozlabs.org Message-Id: <2fe2b8e6395aeacfafcbde590a50922d4e632189.1545784679.git.fthain@telegraphics.com.au> In-Reply-To: References: From: Finn Thain Subject: [PATCH v8 24/25] powerpc: Adopt nvram module for PPC64 Date: Wed, 26 Dec 2018 11:37:59 +1100 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adopt nvram module to reduce code duplication. This means CONFIG_NVRAM becomes available to CONFIG_PPC64 builds (until now it was only PPC32). The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the offset returned by pmac_get_partition(). Add this test to the nvram module. Note that the old PPC32 generic_nvram module lacked this test. So when CONFIG_PPC32 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl would have returned 0 (always). But when CONFIG_PPC64 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl would have returned -1 (which is -EPERM) when the requested partition was not found. With this patch, the result is now -EINVAL on both PPC32 and PPC64 when the requested PowerMac NVRAM partition is not found. This is a userspace- visible change, in the non-existent partition case, which would be in an error path for an IOC_NVRAM_GET_OFFSET ioctl syscall. Signed-off-by: Finn Thain Tested-by: Laurent Vivier Tested-by: Stan Johnson --- BTW, the IOC_NVRAM_SYNC ioctl call returns -EINVAL on PPC64. This patch retains this behaviour though it might be better to actually perform a sync. Both PPC64 and PPC32 kernels implement ppc_md.nvram_sync() for Core99, but on PPC64 the ioctl is unimplemented (unlike PPC32). Changed since v7: - Drop pointless comment edit. --- arch/powerpc/Kconfig | 3 +- arch/powerpc/kernel/nvram_64.c | 185 +++++------------------ arch/powerpc/platforms/powermac/Makefile | 2 - arch/powerpc/platforms/powermac/setup.c | 2 +- arch/powerpc/platforms/powermac/time.c | 2 +- arch/powerpc/platforms/pseries/nvram.c | 2 - drivers/char/nvram.c | 2 + 7 files changed, 40 insertions(+), 158 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b859b7f6599..940de2d62fb5 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -271,10 +271,9 @@ config SYSVIPC_COMPAT depends on COMPAT && SYSVIPC default y -# All PPC32s use generic nvram driver through ppc_md config HAVE_ARCH_NVRAM_OPS bool - default y if PPC32 + default y config SCHED_OMIT_FRAME_POINTER bool diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 22e9d281324d..6d0461c02e0f 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -7,12 +7,6 @@ * 2 of the License, or (at your option) any later version. * * /dev/nvram driver for PPC64 - * - * This perhaps should live in drivers/char - * - * TODO: Split the /dev/nvram part (that one can use - * drivers/char/generic_nvram.c) from the arch & partition - * parsing code. */ #include @@ -716,136 +710,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, spin_unlock_irqrestore(&lock, flags); } -static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) -{ - if (ppc_md.nvram_size == NULL) - return -ENODEV; - return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE, - ppc_md.nvram_size()); -} - - -static ssize_t dev_nvram_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - ssize_t ret; - char *tmp = NULL; - ssize_t size; - - if (!ppc_md.nvram_size) { - ret = -ENODEV; - goto out; - } - - size = ppc_md.nvram_size(); - if (size < 0) { - ret = size; - goto out; - } - - if (*ppos >= size) { - ret = 0; - goto out; - } - - count = min_t(size_t, count, size - *ppos); - count = min(count, PAGE_SIZE); - - tmp = kmalloc(count, GFP_KERNEL); - if (!tmp) { - ret = -ENOMEM; - goto out; - } - - ret = ppc_md.nvram_read(tmp, count, ppos); - if (ret <= 0) - goto out; - - if (copy_to_user(buf, tmp, ret)) - ret = -EFAULT; - -out: - kfree(tmp); - return ret; - -} - -static ssize_t dev_nvram_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - ssize_t ret; - char *tmp = NULL; - ssize_t size; - - ret = -ENODEV; - if (!ppc_md.nvram_size) - goto out; - - ret = 0; - size = ppc_md.nvram_size(); - if (*ppos >= size || size < 0) - goto out; - - count = min_t(size_t, count, size - *ppos); - count = min(count, PAGE_SIZE); - - tmp = memdup_user(buf, count); - if (IS_ERR(tmp)) { - ret = PTR_ERR(tmp); - goto out; - } - - ret = ppc_md.nvram_write(tmp, count, ppos); - - kfree(tmp); -out: - return ret; -} - -static long dev_nvram_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - switch(cmd) { -#ifdef CONFIG_PPC_PMAC - case OBSOLETE_PMAC_NVRAM_GET_OFFSET: - printk(KERN_WARNING "nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n"); - case IOC_NVRAM_GET_OFFSET: { - int part, offset; - - if (!machine_is(powermac)) - return -EINVAL; - if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) - return -EFAULT; - if (part < pmac_nvram_OF || part > pmac_nvram_NR) - return -EINVAL; - offset = pmac_get_partition(part); - if (offset < 0) - return offset; - if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0) - return -EFAULT; - return 0; - } -#endif /* CONFIG_PPC_PMAC */ - default: - return -EINVAL; - } -} - -static const struct file_operations nvram_fops = { - .owner = THIS_MODULE, - .llseek = dev_nvram_llseek, - .read = dev_nvram_read, - .write = dev_nvram_write, - .unlocked_ioctl = dev_nvram_ioctl, -}; - -static struct miscdevice nvram_dev = { - NVRAM_MINOR, - "nvram", - &nvram_fops -}; - - #ifdef DEBUG_NVRAM static void __init nvram_print_partitions(char * label) { @@ -993,6 +857,8 @@ loff_t __init nvram_create_partition(const char *name, int sig, long size = 0; int rc; + BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); + /* Convert sizes from bytes to blocks */ req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; @@ -1194,21 +1060,40 @@ int __init nvram_scan_partitions(void) return err; } -static int __init nvram_init(void) +#if IS_ENABLED(CONFIG_NVRAM) + +static ssize_t ppc_nvram_read(char *buf, size_t count, loff_t *index) { - int rc; - - BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); + if (ppc_md.nvram_read) + return ppc_md.nvram_read(buf, count, index); + return -EINVAL; +} - if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) - return -ENODEV; +static ssize_t ppc_nvram_write(char *buf, size_t count, loff_t *index) +{ + if (ppc_md.nvram_write) + return ppc_md.nvram_write(buf, count, index); + return -EINVAL; +} - rc = misc_register(&nvram_dev); - if (rc != 0) { - printk(KERN_ERR "nvram_init: failed to register device\n"); - return rc; - } - - return rc; +static ssize_t ppc_nvram_get_size(void) +{ + if (ppc_md.nvram_size) + return ppc_md.nvram_size(); + return -ENODEV; +} + +static long ppc_nvram_sync(void) +{ + return -EINVAL; } -device_initcall(nvram_init); + +const struct nvram_ops arch_nvram_ops = { + .read = ppc_nvram_read, + .write = ppc_nvram_write, + .get_size = ppc_nvram_get_size, + .sync = ppc_nvram_sync, +}; +EXPORT_SYMBOL(arch_nvram_ops); + +#endif /* CONFIG_NVRAM */ diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 923bfb340433..20ebf35d7913 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -15,7 +15,5 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o # need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really # CONFIG_NVRAM=y obj-$(CONFIG_NVRAM:m=y) += nvram.o -# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff -obj-$(CONFIG_PPC64) += nvram.o obj-$(CONFIG_PPC32) += bootx_init.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index ce340ae4ee38..dc56ae23118a 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -316,7 +316,7 @@ static void __init pmac_setup_arch(void) find_via_pmu(); smu_init(); -#if IS_ENABLED(CONFIG_NVRAM) || defined(CONFIG_PPC64) +#if IS_ENABLED(CONFIG_NVRAM) pmac_nvram_init(); #endif #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index f157e3d071f2..b36ddee17c87 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -68,7 +68,7 @@ long __init pmac_time_init(void) { s32 delta = 0; -#ifdef CONFIG_NVRAM +#if defined(CONFIG_NVRAM) && defined(CONFIG_PPC32) int dst; delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 69cedc1b3b8a..1136a38ff039 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -7,8 +7,6 @@ * 2 of the License, or (at your option) any later version. * * /dev/nvram driver for PPC64 - * - * This perhaps should live in drivers/char */ diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 8339885e8e9b..8cbfed86ec8d 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -334,6 +334,8 @@ static long nvram_misc_ioctl(struct file *file, unsigned int cmd, if (part < pmac_nvram_OF || part > pmac_nvram_NR) return -EINVAL; offset = pmac_get_partition(part); + if (offset < 0) + return -EINVAL; if (copy_to_user((void __user *)arg, &offset, sizeof(offset)) != 0) return -EFAULT; -- 2.19.2