powerpc: Adopt nvram module for PPC64
Adopt nvram module to reduce code duplication. This means CONFIG_NVRAM becomes available to PPC64 builds. Previously it was only available to PPC32 builds because it depended on CONFIG_GENERIC_NVRAM. The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the offset returned by pmac_get_partition(). Do the same in 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. Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
537f3286ad
Коммит
20e07af71f
|
@ -178,7 +178,7 @@ config PPC
|
|||
select HAVE_ARCH_KGDB
|
||||
select HAVE_ARCH_MMAP_RND_BITS
|
||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
|
||||
select HAVE_ARCH_NVRAM_OPS if PPC32
|
||||
select HAVE_ARCH_NVRAM_OPS
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_CBPF_JIT if !PPC64
|
||||
|
|
|
@ -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 <linux/types.h>
|
||||
|
@ -714,137 +708,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");
|
||||
/* fall through */
|
||||
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)
|
||||
{
|
||||
|
@ -992,6 +855,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;
|
||||
|
@ -1192,22 +1057,3 @@ int __init nvram_scan_partitions(void)
|
|||
kfree(header);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __init nvram_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
|
||||
|
||||
if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
rc = misc_register(&nvram_dev);
|
||||
if (rc != 0) {
|
||||
printk(KERN_ERR "nvram_init: failed to register device\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
device_initcall(nvram_init);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -302,6 +302,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;
|
||||
|
@ -309,6 +311,7 @@ static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
break;
|
||||
#ifdef CONFIG_PPC32
|
||||
case IOC_NVRAM_SYNC:
|
||||
if (ppc_md.nvram_sync != NULL) {
|
||||
mutex_lock(&nvram_mutex);
|
||||
|
@ -317,6 +320,7 @@ static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
|
|||
}
|
||||
ret = 0;
|
||||
break;
|
||||
#endif
|
||||
#elif defined(CONFIG_X86) || defined(CONFIG_M68K)
|
||||
case NVRAM_INIT:
|
||||
/* initialize NVRAM contents and checksum */
|
||||
|
|
Загрузка…
Ссылка в новой задаче