diff options
Diffstat (limited to 'arch/sparc/kernel')
55 files changed, 353 insertions, 332 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 58ea4ef9b622..497b5714fa8f 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -4,12 +4,10 @@ # Makefile for the linux kernel. # -asflags-y := -ansi - # Undefine sparc when processing vmlinux.lds - it is used # And teach CPP we are doing $(BITS) builds (for this case) CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) -extra-y += vmlinux.lds +always-$(KBUILD_BUILTIN) += vmlinux.lds ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities @@ -35,6 +33,7 @@ obj-y += process.o obj-y += signal_$(BITS).o obj-y += sigutil_$(BITS).o obj-$(CONFIG_SPARC32) += ioport.o +obj-y += setup.o obj-y += setup_$(BITS).o obj-y += idprom.o obj-y += sys_sparc_$(BITS).o @@ -42,7 +41,6 @@ obj-$(CONFIG_SPARC32) += systbls_32.o obj-y += time_$(BITS).o obj-$(CONFIG_SPARC32) += windows.o obj-y += cpu.o -obj-$(CONFIG_SPARC64) += vdso.o obj-$(CONFIG_SPARC32) += devices.o obj-y += ptrace_$(BITS).o obj-y += unaligned_$(BITS).o diff --git a/arch/sparc/kernel/adi_64.c b/arch/sparc/kernel/adi_64.c index e0e4fc527b24..18036a43cf56 100644 --- a/arch/sparc/kernel/adi_64.c +++ b/arch/sparc/kernel/adi_64.c @@ -202,7 +202,7 @@ static tag_storage_desc_t *alloc_tag_store(struct mm_struct *mm, } else { size = sizeof(tag_storage_desc_t)*max_desc; - mm->context.tag_store = kzalloc(size, GFP_NOWAIT|__GFP_NOWARN); + mm->context.tag_store = kzalloc(size, GFP_NOWAIT); if (mm->context.tag_store == NULL) { tag_desc = NULL; goto out; @@ -281,7 +281,7 @@ static tag_storage_desc_t *alloc_tag_store(struct mm_struct *mm, size = (size + (PAGE_SIZE-adi_blksize()))/PAGE_SIZE; size = size * PAGE_SIZE; } - tags = kzalloc(size, GFP_NOWAIT|__GFP_NOWARN); + tags = kzalloc(size, GFP_NOWAIT); if (tags == NULL) { tag_desc->tag_users = 0; tag_desc = NULL; diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index d44725d37e30..849db20e7165 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -28,7 +28,6 @@ * #define APC_DEBUG_LED */ -#define APC_MINOR MISC_DYNAMIC_MINOR #define APC_OBPNAME "power-management" #define APC_DEVNAME "apc" @@ -138,7 +137,7 @@ static const struct file_operations apc_fops = { .llseek = noop_llseek, }; -static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; +static struct miscdevice apc_miscdev = { MISC_DYNAMIC_MINOR, APC_DEVNAME, &apc_fops }; static int apc_probe(struct platform_device *op) { diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c index 3d9b9855dce9..6e660bde48dd 100644 --- a/arch/sparc/kernel/asm-offsets.c +++ b/arch/sparc/kernel/asm-offsets.c @@ -10,6 +10,7 @@ * * On sparc, thread_info data is static and TI_XXX offsets are computed by hand. */ +#define COMPILE_OFFSETS #include <linux/sched.h> #include <linux/mm_types.h> diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index a1a6485c9183..16b45d172fb0 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -63,7 +63,7 @@ static int clock_board_calc_nslots(struct clock_board *p) static int clock_board_probe(struct platform_device *op) { - struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct clock_board *p = kzalloc_obj(*p); int err = -ENOMEM; if (!p) { @@ -159,7 +159,7 @@ static struct platform_driver clock_board_driver = { static int fhc_probe(struct platform_device *op) { - struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct fhc *p = kzalloc_obj(*p); int err = -ENOMEM; u32 reg; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index e02074062001..d935177b6953 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -417,7 +417,7 @@ static int jbusmc_probe(struct platform_device *op) num_mem_regs = len / sizeof(*mem_regs); err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { printk(KERN_ERR PFX "Cannot allocate struct jbusmc.\n"); goto out; @@ -718,7 +718,7 @@ static int chmc_probe(struct platform_device *op) } err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { printk(KERN_ERR PFX "Could not allocate struct chmc.\n"); goto out; @@ -814,7 +814,7 @@ static struct platform_driver us3mc_driver = { .of_match_table = us3mc_match, }, .probe = us3mc_probe, - .remove_new = us3mc_remove, + .remove = us3mc_remove, }; static inline bool us3mc_platform(void) diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 8fcf2d8c6bd2..d51ff010176c 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -194,7 +194,7 @@ static struct cpuinfo_tree *build_cpuinfo_tree(void) n = enumerate_cpuinfo_nodes(tmp_level); - new_tree = kzalloc(struct_size(new_tree, nodes, n), GFP_ATOMIC); + new_tree = kzalloc_flex(*new_tree, nodes, n, GFP_ATOMIC); if (!new_tree) return NULL; diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index ffdc15588ac2..b34db8125bba 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -781,14 +781,17 @@ void ldom_set_var(const char *var, const char *value) } pkt; char *base, *p; int msg_len, loops; + size_t var_len, value_len; - if (strlen(var) + strlen(value) + 2 > - sizeof(pkt) - sizeof(pkt.header)) { - printk(KERN_ERR PFX - "contents length: %zu, which more than max: %lu," - "so could not set (%s) variable to (%s).\n", - strlen(var) + strlen(value) + 2, - sizeof(pkt) - sizeof(pkt.header), var, value); + var_len = strlen(var) + 1; + value_len = strlen(value) + 1; + + if (var_len + value_len > sizeof(pkt) - sizeof(pkt.header)) { + pr_err(PFX + "contents length: %zu, which more than max: %lu," + "so could not set (%s) variable to (%s).\n", + var_len + value_len, + sizeof(pkt) - sizeof(pkt.header), var, value); return; } @@ -797,10 +800,10 @@ void ldom_set_var(const char *var, const char *value) pkt.header.data.handle = cp->handle; pkt.header.msg.hdr.type = DS_VAR_SET_REQ; base = p = &pkt.header.msg.name_and_value[0]; - strcpy(p, var); - p += strlen(var) + 1; - strcpy(p, value); - p += strlen(value) + 1; + strscpy(p, var, var_len); + p += var_len; + strscpy(p, value, value_len); + p += value_len; msg_len = (sizeof(struct ds_data) + sizeof(struct ds_var_set_msg) + @@ -910,7 +913,7 @@ static int register_services(struct ds_info *dp) pbuf.req.handle = cp->handle; pbuf.req.major = 1; pbuf.req.minor = 0; - strcpy(pbuf.id_buf, cp->service_id); + strscpy(pbuf.id_buf, cp->service_id); err = __ds_send(lp, &pbuf, msg_len); if (err > 0) @@ -1172,7 +1175,7 @@ static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id) if (ds_version_printed++ == 0) printk(KERN_INFO "%s", version); - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); err = -ENOMEM; if (!dp) goto out_err; diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index a3fdee4cd6fa..ea51ef52c952 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -907,6 +907,21 @@ flush_patch_four: jmpl %l1 + %lo(sparc_vfork), %g0 add %sp, STACKFRAME_SZ, %o0 + .globl __sys_clone3, flush_patch_five +__sys_clone3: + mov %o7, %l5 +flush_patch_five: + FLUSH_ALL_KERNEL_WINDOWS; + ld [%curptr + TI_TASK], %o4 + rd %psr, %g4 + WRITE_PAUSE + rd %wim, %g5 + WRITE_PAUSE + std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] + add %sp, STACKFRAME_SZ, %o0 + call sparc_clone3 + mov %l5, %o7 + .align 4 linux_sparc_ni_syscall: sethi %hi(sys_ni_syscall), %l7 diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 38345460d542..8c320fa25a67 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S @@ -57,13 +57,6 @@ sun4e_notsup: .align PAGE_SIZE -/* This was the only reasonable way I could think of to properly align - * these page-table data structures. - */ - .globl empty_zero_page -empty_zero_page: .skip PAGE_SIZE -EXPORT_SYMBOL(empty_zero_page) - .global root_flags .global ram_flags .global root_dev diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index da0363692528..7613ab0ffb89 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -260,26 +260,35 @@ static void dma_4u_free_coherent(struct device *dev, size_t size, free_pages((unsigned long)cpu, order); } -static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t sz, - enum dma_data_direction direction, +static dma_addr_t dma_4u_map_phys(struct device *dev, phys_addr_t phys, + size_t sz, enum dma_data_direction direction, unsigned long attrs) { struct iommu *iommu; struct strbuf *strbuf; iopte_t *base; unsigned long flags, npages, oaddr; - unsigned long i, base_paddr, ctx; + unsigned long i, ctx; u32 bus_addr, ret; unsigned long iopte_protection; + if (unlikely(attrs & DMA_ATTR_MMIO)) + /* + * This check is included because older versions of the code + * lacked MMIO path support, and my ability to test this path + * is limited. However, from a software technical standpoint, + * there is no restriction, as the following code operates + * solely on physical addresses. + */ + goto bad_no_ctx; + iommu = dev->archdata.iommu; strbuf = dev->archdata.stc; if (unlikely(direction == DMA_NONE)) goto bad_no_ctx; - oaddr = (unsigned long)(page_address(page) + offset); + oaddr = (unsigned long)(phys_to_virt(phys)); npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -296,7 +305,6 @@ static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, bus_addr = (iommu->tbl.table_map_base + ((base - iommu->page_table) << IO_PAGE_SHIFT)); ret = bus_addr | (oaddr & ~IO_PAGE_MASK); - base_paddr = __pa(oaddr & IO_PAGE_MASK); if (strbuf->strbuf_enabled) iopte_protection = IOPTE_STREAMING(ctx); else @@ -304,8 +312,10 @@ static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, if (direction != DMA_TO_DEVICE) iopte_protection |= IOPTE_WRITE; - for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) - iopte_val(*base) = iopte_protection | base_paddr; + phys &= IO_PAGE_MASK; + + for (i = 0; i < npages; i++, base++, phys += IO_PAGE_SIZE) + iopte_val(*base) = iopte_protection | phys; return ret; @@ -383,7 +393,7 @@ do_flush_sync: vaddr, ctx, npages); } -static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, +static void dma_4u_unmap_phys(struct device *dev, dma_addr_t bus_addr, size_t sz, enum dma_data_direction direction, unsigned long attrs) { @@ -753,8 +763,8 @@ static int dma_4u_supported(struct device *dev, u64 device_mask) static const struct dma_map_ops sun4u_dma_ops = { .alloc = dma_4u_alloc_coherent, .free = dma_4u_free_coherent, - .map_page = dma_4u_map_page, - .unmap_page = dma_4u_unmap_page, + .map_phys = dma_4u_map_phys, + .unmap_phys = dma_4u_unmap_phys, .map_sg = dma_4u_map_sg, .unmap_sg = dma_4u_unmap_sg, .sync_single_for_cpu = dma_4u_sync_single_for_cpu, diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 5ebca5c7af1e..cbc0680a4642 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -238,7 +238,7 @@ unsigned long sparc_dma_alloc_resource(struct device *dev, size_t len) { struct resource *res; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return 0; res->name = dev->of_node->full_name; diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 8605dd710f3c..5210991429d5 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -199,18 +199,18 @@ int arch_show_interrupts(struct seq_file *p, int prec) int j; #ifdef CONFIG_SMP - seq_printf(p, "RES: "); + seq_printf(p, "RES:"); for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).irq_resched_count); + seq_put_decimal_ull_width(p, " ", cpu_data(j).irq_resched_count, 10); seq_printf(p, " IPI rescheduling interrupts\n"); - seq_printf(p, "CAL: "); + seq_printf(p, "CAL:"); for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).irq_call_count); + seq_put_decimal_ull_width(p, " ", cpu_data(j).irq_call_count, 10); seq_printf(p, " IPI function call interrupts\n"); #endif - seq_printf(p, "NMI: "); + seq_printf(p, "NMI:"); for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).counter); + seq_put_decimal_ull_width(p, " ", cpu_data(j).counter, 10); seq_printf(p, " Non-maskable interrupts\n"); return 0; } diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 01ee800efde3..c5466a9fd560 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -22,6 +22,7 @@ #include <linux/seq_file.h> #include <linux/ftrace.h> #include <linux/irq.h> +#include <linux/string_choices.h> #include <asm/ptrace.h> #include <asm/processor.h> @@ -145,9 +146,7 @@ static int hv_irq_version; */ static bool sun4v_cookie_only_virqs(void) { - if (hv_irq_version >= 3) - return true; - return false; + return hv_irq_version >= 3; } static void __init irq_init_hv(void) @@ -170,7 +169,7 @@ static void __init irq_init_hv(void) pr_info("SUN4V: Using IRQ API major %d, cookie only virqs %s\n", hv_irq_version, - sun4v_cookie_only_virqs() ? "enabled" : "disabled"); + str_enabled_disabled(sun4v_cookie_only_virqs())); } /* This function is for the timer interrupt.*/ @@ -304,9 +303,9 @@ int arch_show_interrupts(struct seq_file *p, int prec) { int j; - seq_printf(p, "NMI: "); + seq_printf(p, "NMI:"); for_each_online_cpu(j) - seq_printf(p, "%10u ", cpu_data(j).__nmi_count); + seq_put_decimal_ull_width(p, " ", cpu_data(j).__nmi_count, 10); seq_printf(p, " Non-maskable interrupts\n"); return 0; } @@ -629,7 +628,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) if (unlikely(handler_data)) goto out; - handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct irq_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); @@ -655,7 +654,7 @@ static unsigned int sun4v_build_common(u32 devhandle, unsigned int devino, if (!irq) goto out; - data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + data = kzalloc_obj(struct irq_handler_data, GFP_ATOMIC); if (unlikely(!data)) { pr_err("IRQ handler data allocation failed.\n"); irq_free(irq); diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 8328a3b78a44..4ee85051521a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -18,6 +18,7 @@ extern int ncpus_probed; asmlinkage long sparc_clone(struct pt_regs *regs); asmlinkage long sparc_fork(struct pt_regs *regs); asmlinkage long sparc_vfork(struct pt_regs *regs); +asmlinkage long sparc_clone3(struct pt_regs *regs); #ifdef CONFIG_SPARC64 /* setup_64.c */ diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 7f3cdb6f644d..826fe8ed0289 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1171,7 +1171,7 @@ struct ldc_channel *ldc_alloc(unsigned long id, mssbuf = NULL; - lp = kzalloc(sizeof(*lp), GFP_KERNEL); + lp = kzalloc_obj(*lp); err = -ENOMEM; if (!lp) goto out_err; diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index ab657b359789..f4fb82b019bb 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -84,7 +84,7 @@ static ssize_t led_proc_write(struct file *file, const char __user *buffer, /* before we change anything we want to stop any running timers, * otherwise calls such as on will have no persistent effect */ - del_timer_sync(&led_blink_timer); + timer_delete_sync(&led_blink_timer); if (!strcmp(buf, "on")) { auxio_set_led(AUXIO_LED_ON); @@ -134,7 +134,7 @@ static int __init led_init(void) static void __exit led_exit(void) { remove_proc_entry("led", NULL); - del_timer_sync(&led_blink_timer); + timer_delete_sync(&led_blink_timer); } module_init(led_init); diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 8de6646e9ce8..10934dfa987a 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -60,30 +60,3 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) pci_assign_unassigned_resources(); pci_bus_add_devices(root_bus); } - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - struct resource *res; - u16 cmd, oldcmd; - int i; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - oldcmd = cmd; - - pci_dev_for_each_resource(dev, res, i) { - /* Only set up the requested stuff */ - if (!(mask & (1<<i))) - continue; - - if (res->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (res->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != oldcmd) { - pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 9f662340b5b2..c1cbdf88146c 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -721,7 +721,7 @@ static int grpci2_of_probe(struct platform_device *ofdev) goto err1; } - priv = grpci2priv = kzalloc(sizeof(struct grpci2_priv), GFP_KERNEL); + priv = grpci2priv = kzalloc_obj(struct grpci2_priv); if (grpci2priv == NULL) { err = -ENOMEM; goto err1; diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index b8c51cc23d96..2a8770369beb 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -29,7 +29,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, { unsigned int symidx; Elf_Sym *sym; - char *strtab; int i; for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) { @@ -39,7 +38,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, } } sym = (Elf_Sym *)sechdrs[symidx].sh_addr; - strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr; for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { if (sym[i].st_shndx == SHN_UNDEF) { @@ -87,6 +85,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; #ifdef CONFIG_SPARC64 case R_SPARC_64: + case R_SPARC_UA64: location[0] = v >> 56; location[1] = v >> 48; location[2] = v >> 40; @@ -141,7 +140,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; default: - printk(KERN_ERR "module %s: Unknown relocation: %x\n", + printk(KERN_ERR "module %s: Unknown relocation: 0x%x\n", me->name, (int) (ELF_R_TYPE(rel[i].r_info) & 0xff)); return -ENOEXEC; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 06012e68bdca..b62b1d0291a4 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -340,7 +340,7 @@ static void __init build_device_resources(struct platform_device *op, static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc_obj(*op); const struct linux_prom_irqs *intr; struct dev_archdata *sd; int len, i; @@ -387,6 +387,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, if (of_device_register(op)) { printk("%pOF: Could not register of device.\n", dp); + put_device(&op->dev); kfree(op); op = NULL; } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index f98c2901f335..0b87eb629a62 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -633,7 +633,7 @@ out: static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc_obj(*op); const unsigned int *irq; struct dev_archdata *sd; int len, i; @@ -677,6 +677,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, if (of_device_register(op)) { printk("%pOF: Could not register of device.\n", dp); + put_device(&op->dev); kfree(op); op = NULL; } diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 50a0927a84a6..1603d50fdcad 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -181,6 +181,28 @@ static int __init ofpci_debug(char *str) __setup("ofpci_debug=", ofpci_debug); +static void of_fixup_pci_pref(struct pci_dev *dev, int index, + struct resource *res) +{ + struct pci_bus_region region; + + if (!(res->flags & IORESOURCE_MEM_64)) + return; + + if (!resource_size(res)) + return; + + pcibios_resource_to_bus(dev->bus, ®ion, res); + if (region.end <= ~((u32)0)) + return; + + if (!(res->flags & IORESOURCE_PREFETCH)) { + res->flags |= IORESOURCE_PREFETCH; + pci_info(dev, "reg 0x%x: fixup: pref added to 64-bit resource\n", + index); + } +} + static unsigned long pci_parse_of_flags(u32 addr0) { unsigned long flags = 0; @@ -244,6 +266,7 @@ static void pci_parse_of_addrs(struct platform_device *op, res->end = op_res->end; res->flags = flags; res->name = pci_name(dev); + of_fixup_pci_pref(dev, i, res); pci_info(dev, "reg 0x%x: %pR\n", i, res); } @@ -332,6 +355,13 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->error_state = pci_channel_io_normal; dev->dma_mask = 0xffffffff; + /* + * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit + * if MSI (rather than MSI-X) capability does not have + * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver. + */ + dev->msi_addr_mask = DMA_BIT_MASK(64); + if (of_node_name_eq(node, "pci")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; @@ -627,7 +657,7 @@ static void pci_claim_legacy_resources(struct pci_dev *dev) if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) return; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return; @@ -722,33 +752,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, return bus; } -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - struct resource *res; - u16 cmd, oldcmd; - int i; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - oldcmd = cmd; - - pci_dev_for_each_resource(dev, res, i) { - /* Only set up the requested stuff */ - if (!(mask & (1<<i))) - continue; - - if (res->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (res->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != oldcmd) { - pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - /* Platform support for /proc/bus/pci/X/Y mmap()s. */ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma) { @@ -932,7 +935,7 @@ static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus) { const struct pci_slot_names { u32 slot_mask; - char names[0]; + char names[]; } *prop; const char *sp; int len, i; diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 5eeec9ad6845..0eafcb2d88ce 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -336,7 +336,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) NULL); if (vdma) { - struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); + struct resource *rp = kzalloc_obj(*rp); if (!rp) { pr_info("%s: Cannot allocate IOMMU resource.\n", @@ -361,7 +361,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) int i, saw_mem, saw_io; int num_pbm_ranges; - /* Corresponding generic code in of_pci_get_host_bridge_resources() */ + /* Corresponds to generic devm_of_pci_get_host_bridge_resources() */ saw_mem = saw_io = 0; pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i); diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 0b91bde80fdc..c35a8e3c1eae 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -468,13 +468,13 @@ static int fire_probe(struct platform_device *op) portid = of_getintprop_default(dp, "portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbminfo.\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 1efc98305ec7..199ab73f84af 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -519,7 +519,7 @@ static int psycho_probe(struct platform_device *op) upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; @@ -529,7 +529,7 @@ static int psycho_probe(struct platform_device *op) if (pbm->sibling) { iommu = pbm->sibling->iommu; } else { - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index a84598568300..1109d5b344eb 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -482,13 +482,13 @@ static int sabre_probe(struct platform_device *op) } err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; } - iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + iommu = kzalloc_obj(*iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 93cd9e5a8099..4348ca2c4a3f 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1426,7 +1426,7 @@ static int __schizo_init(struct platform_device *op, unsigned long chip_type) portid = of_getintprop_default(dp, "portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; @@ -1434,7 +1434,7 @@ static int __schizo_init(struct platform_device *op, unsigned long chip_type) pbm->sibling = schizo_find_sibling(portid, chip_type); - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); goto out_free_pbm; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index b720b21ccfbd..61f14b4c8f90 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -352,9 +352,8 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, free_pages((unsigned long)cpu, order); } -static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t sz, - enum dma_data_direction direction, +static dma_addr_t dma_4v_map_phys(struct device *dev, phys_addr_t phys, + size_t sz, enum dma_data_direction direction, unsigned long attrs) { struct iommu *iommu; @@ -362,18 +361,27 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, struct iommu_map_table *tbl; u64 mask; unsigned long flags, npages, oaddr; - unsigned long i, base_paddr; - unsigned long prot; + unsigned long i, prot; dma_addr_t bus_addr, ret; long entry; + if (unlikely(attrs & DMA_ATTR_MMIO)) + /* + * This check is included because older versions of the code + * lacked MMIO path support, and my ability to test this path + * is limited. However, from a software technical standpoint, + * there is no restriction, as the following code operates + * solely on physical addresses. + */ + goto bad; + iommu = dev->archdata.iommu; atu = iommu->atu; if (unlikely(direction == DMA_NONE)) goto bad; - oaddr = (unsigned long)(page_address(page) + offset); + oaddr = (unsigned long)(phys_to_virt(phys)); npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); npages >>= IO_PAGE_SHIFT; @@ -391,7 +399,6 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, bus_addr = (tbl->table_map_base + (entry << IO_PAGE_SHIFT)); ret = bus_addr | (oaddr & ~IO_PAGE_MASK); - base_paddr = __pa(oaddr & IO_PAGE_MASK); prot = HV_PCI_MAP_ATTR_READ; if (direction != DMA_TO_DEVICE) prot |= HV_PCI_MAP_ATTR_WRITE; @@ -403,8 +410,10 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, iommu_batch_start(dev, prot, entry); - for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE) { - long err = iommu_batch_add(base_paddr, mask); + phys &= IO_PAGE_MASK; + + for (i = 0; i < npages; i++, phys += IO_PAGE_SIZE) { + long err = iommu_batch_add(phys, mask); if (unlikely(err < 0L)) goto iommu_map_fail; } @@ -426,7 +435,7 @@ iommu_map_fail: return DMA_MAPPING_ERROR; } -static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, +static void dma_4v_unmap_phys(struct device *dev, dma_addr_t bus_addr, size_t sz, enum dma_data_direction direction, unsigned long attrs) { @@ -686,8 +695,8 @@ static int dma_4v_supported(struct device *dev, u64 device_mask) static const struct dma_map_ops sun4v_dma_ops = { .alloc = dma_4v_alloc_coherent, .free = dma_4v_free_coherent, - .map_page = dma_4v_map_page, - .unmap_page = dma_4v_unmap_page, + .map_phys = dma_4v_map_phys, + .unmap_phys = dma_4v_unmap_phys, .map_sg = dma_4v_map_sg, .unmap_sg = dma_4v_unmap_sg, .dma_supported = dma_4v_supported, @@ -747,7 +756,7 @@ static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm) unsigned long order; unsigned long err; - iotsb = kzalloc(sizeof(*iotsb), GFP_KERNEL); + iotsb = kzalloc_obj(*iotsb); if (!iotsb) { err = -ENOMEM; goto out_err; @@ -1285,13 +1294,13 @@ static int pci_sun4v_probe(struct platform_device *op) iommu_batch_initialized = 1; } - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Could not allocate pci_pbm_info\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Could not allocate pbm iommu\n"); goto out_free_controller; @@ -1300,7 +1309,7 @@ static int pci_sun4v_probe(struct platform_device *op) pbm->iommu = iommu; iommu->atu = NULL; if (hv_atu) { - atu = kzalloc(sizeof(*atu), GFP_KERNEL); + atu = kzalloc_obj(*atu); if (!atu) pr_err(PFX "Could not allocate atu\n"); else diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 25fe0a061732..4cd32ccc5191 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/jiffies.h> #include <asm/swift.h> /* for cache flushing. */ @@ -352,7 +353,7 @@ int __init pcic_probe(void) pbm = &pcic->pbm; pbm->prom_node = node; prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0; - strcpy(pbm->prom_name, namebuf); + strscpy(pbm->prom_name, namebuf); { extern int pcic_nmi_trap_patch[4]; @@ -465,7 +466,7 @@ static int pdev_to_pnode(struct linux_pbm_info *pbm, struct pci_dev *pdev) static inline struct pcidev_cookie *pci_devcookie_alloc(void) { - return kmalloc(sizeof(struct pcidev_cookie), GFP_ATOMIC); + return kmalloc_obj(struct pcidev_cookie, GFP_ATOMIC); } static void pcic_map_pci_device(struct linux_pcic *pcic, @@ -477,7 +478,7 @@ static void pcic_map_pci_device(struct linux_pcic *pcic, int j; if (node == 0 || node == -1) { - strcpy(namebuf, "???"); + strscpy(namebuf, "???"); } else { prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0; } @@ -536,7 +537,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node) char namebuf[64]; if (node == 0 || node == -1) { - strcpy(namebuf, "???"); + strscpy(namebuf, "???"); } else { prom_getstring(node, "name", namebuf, sizeof(namebuf)); } @@ -641,33 +642,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) } } -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - struct resource *res; - u16 cmd, oldcmd; - int i; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - oldcmd = cmd; - - pci_dev_for_each_resource(dev, res, i) { - /* Only set up the requested stuff */ - if (!(mask & (1<<i))) - continue; - - if (res->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (res->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != oldcmd) { - pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - /* Makes compiler happy */ static volatile int pcic_timer_dummy; diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index f02a283a8e8f..0ce4ae343531 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -6,7 +6,7 @@ * This code is based almost entirely upon the x86 perf event * code, which is: * - * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de> + * Copyright (C) 2008 Linutronix GmbH, Thomas Gleixner <tglx@kernel.org> * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar * Copyright (C) 2009 Jaswinder Singh Rajput * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter @@ -1668,8 +1668,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, if (!sparc_perf_event_set_period(event, hwc, idx)) continue; - if (perf_event_overflow(event, &data, regs)) - sparc_pmu_stop(event, 0); + perf_event_overflow(event, &data, regs); } finish_clock = sched_clock(); diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 0442ab00518d..d72fa0665943 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -12,19 +12,24 @@ #include <linux/sched/task.h> #include <linux/sched/task_stack.h> #include <linux/signal.h> +#include <linux/syscalls.h> #include "kernel.h" asmlinkage long sparc_fork(struct pt_regs *regs) { - unsigned long orig_i1 = regs->u_regs[UREG_I1]; + unsigned long orig_i1; long ret; struct kernel_clone_args args = { .exit_signal = SIGCHLD, - /* Reuse the parent's stack for the child. */ - .stack = regs->u_regs[UREG_FP], }; + synchronize_user_stack(); + + orig_i1 = regs->u_regs[UREG_I1]; + /* Reuse the parent's stack for the child. */ + args.stack = regs->u_regs[UREG_FP]; + ret = kernel_clone(&args); /* If we get an error and potentially restart the system @@ -40,16 +45,19 @@ asmlinkage long sparc_fork(struct pt_regs *regs) asmlinkage long sparc_vfork(struct pt_regs *regs) { - unsigned long orig_i1 = regs->u_regs[UREG_I1]; + unsigned long orig_i1; long ret; - struct kernel_clone_args args = { .flags = CLONE_VFORK | CLONE_VM, .exit_signal = SIGCHLD, - /* Reuse the parent's stack for the child. */ - .stack = regs->u_regs[UREG_FP], }; + synchronize_user_stack(); + + orig_i1 = regs->u_regs[UREG_I1]; + /* Reuse the parent's stack for the child. */ + args.stack = regs->u_regs[UREG_FP]; + ret = kernel_clone(&args); /* If we get an error and potentially restart the system @@ -65,15 +73,18 @@ asmlinkage long sparc_vfork(struct pt_regs *regs) asmlinkage long sparc_clone(struct pt_regs *regs) { - unsigned long orig_i1 = regs->u_regs[UREG_I1]; - unsigned int flags = lower_32_bits(regs->u_regs[UREG_I0]); + unsigned long orig_i1; + unsigned int flags; long ret; + struct kernel_clone_args args = {0}; - struct kernel_clone_args args = { - .flags = (flags & ~CSIGNAL), - .exit_signal = (flags & CSIGNAL), - .tls = regs->u_regs[UREG_I3], - }; + synchronize_user_stack(); + + orig_i1 = regs->u_regs[UREG_I1]; + flags = lower_32_bits(regs->u_regs[UREG_I0]); + args.flags = (flags & ~CSIGNAL); + args.exit_signal = (flags & CSIGNAL); + args.tls = regs->u_regs[UREG_I3]; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { @@ -108,3 +119,16 @@ asmlinkage long sparc_clone(struct pt_regs *regs) return ret; } + +asmlinkage long sparc_clone3(struct pt_regs *regs) +{ + unsigned long sz; + struct clone_args __user *cl_args; + + synchronize_user_stack(); + + cl_args = (struct clone_args __user *)regs->u_regs[UREG_I0]; + sz = regs->u_regs[UREG_I1]; + + return sys_clone3(cl_args, sz); +} diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 9c7c662cb565..dd8c6c02b0f1 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -247,6 +247,8 @@ clone_stackframe(struct sparc_stackf __user *dst, * Parent --> %o0 == childs pid, %o1 == 0 * Child --> %o0 == parents pid, %o1 == 1 * + * clone3() - Uses regular kernel return value conventions + * * NOTE: We have a separate fork kpsr/kwim because * the parent could change these values between * sys_fork invocation and when we reach here @@ -260,12 +262,12 @@ extern void ret_from_kernel_thread(void); int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) { - unsigned long clone_flags = args->flags; - unsigned long sp = args->stack; + u64 clone_flags = args->flags; unsigned long tls = args->tls; struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs, *regs = current_pt_regs(); char *new_stack; + unsigned long sp = args->stack ? args->stack : regs->u_regs[UREG_FP]; #ifndef CONFIG_SMP if(last_task_used_math == current) { @@ -350,13 +352,22 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) childregs->psr &= ~PSR_EF; clear_tsk_thread_flag(p, TIF_USEDFPU); #endif + /* Handle return value conventions */ + if (regs->u_regs[UREG_G1] == __NR_clone3) { + /* clone3() - use regular kernel return value convention */ + + /* Set the return value for the child. */ + childregs->u_regs[UREG_I0] = 0; + } else { + /* clone()/fork() - use SunOS return value convention */ - /* Set the return value for the child. */ - childregs->u_regs[UREG_I0] = current->pid; - childregs->u_regs[UREG_I1] = 1; + /* Set the return value for the child. */ + childregs->u_regs[UREG_I0] = current->pid; + childregs->u_regs[UREG_I1] = 1; - /* Set the return value for the parent. */ - regs->u_regs[UREG_I1] = 0; + /* Set the return value for the parent. */ + regs->u_regs[UREG_I1] = 0; + } if (clone_flags & CLONE_SETTLS) childregs->u_regs[UREG_G7] = tls; diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 529adfecd58c..e889da8e4835 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -564,17 +564,19 @@ barf: * under SunOS are nothing short of bletcherous: * Parent --> %o0 == childs pid, %o1 == 0 * Child --> %o0 == parents pid, %o1 == 1 + * + * clone3() - Uses regular kernel return value conventions */ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) { - unsigned long clone_flags = args->flags; - unsigned long sp = args->stack; + u64 clone_flags = args->flags; unsigned long tls = args->tls; struct thread_info *t = task_thread_info(p); struct pt_regs *regs = current_pt_regs(); struct sparc_stackf *parent_sf; unsigned long child_stack_sz; char *child_trap_frame; + unsigned long sp = args->stack ? args->stack : regs->u_regs[UREG_FP]; /* Calculate offset to stack_frame & pt_regs */ child_stack_sz = (STACKFRAME_SZ + TRACEREG_SZ); @@ -616,12 +618,25 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) if (t->utraps) t->utraps[0]++; - /* Set the return value for the child. */ - t->kregs->u_regs[UREG_I0] = current->pid; - t->kregs->u_regs[UREG_I1] = 1; + /* Handle return value conventions */ + if (regs->u_regs[UREG_G1] == __NR_clone3) { + /* clone3() - use regular kernel return value convention */ + + /* Set the return value for the child. */ + t->kregs->u_regs[UREG_I0] = 0; + + /* Clear g1 to indicate user thread */ + t->kregs->u_regs[UREG_G1] = 0; + } else { + /* clone()/fork() - use SunOS return value convention */ + + /* Set the return value for the child. */ + t->kregs->u_regs[UREG_I0] = current->pid; + t->kregs->u_regs[UREG_I1] = 1; - /* Set the second return value for the parent. */ - regs->u_regs[UREG_I1] = 0; + /* Set the second return value for the parent. */ + regs->u_regs[UREG_I1] = 0; + } if (clone_flags & CLONE_SETTLS) t->kregs->u_regs[UREG_G7] = tls; diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c index 3df960c137f7..cd94f1e8d644 100644 --- a/arch/sparc/kernel/prom_32.c +++ b/arch/sparc/kernel/prom_32.c @@ -28,9 +28,7 @@ void * __init prom_early_alloc(unsigned long size) { void *ret; - ret = memblock_alloc(size, SMP_CACHE_BYTES); - if (!ret) - panic("%s: Failed to allocate %lu bytes\n", __func__, size); + ret = memblock_alloc_or_panic(size, SMP_CACHE_BYTES); prom_early_allocated += size; @@ -189,14 +187,16 @@ char * __init build_path_component(struct device_node *dp) { const char *name = of_get_property(dp, "name", NULL); char tmp_buf[64], *n; + size_t n_sz; tmp_buf[0] = '\0'; __build_path_component(dp, tmp_buf); if (tmp_buf[0] == '\0') - strcpy(tmp_buf, name); + strscpy(tmp_buf, name); - n = prom_early_alloc(strlen(tmp_buf) + 1); - strcpy(n, tmp_buf); + n_sz = strlen(tmp_buf) + 1; + n = prom_early_alloc(n_sz); + strscpy(n, tmp_buf, n_sz); return n; } @@ -206,13 +206,14 @@ extern void restore_current(void); void __init of_console_init(void) { char *msg = "OF stdout device is: %s\n"; + const size_t of_console_path_sz = 256; struct device_node *dp; unsigned long flags; const char *type; phandle node; int skip, tmp, fd; - of_console_path = prom_early_alloc(256); + of_console_path = prom_early_alloc(of_console_path_sz); switch (prom_vers) { case PROM_V0: @@ -299,7 +300,7 @@ void __init of_console_init(void) prom_printf("No stdout-path in root node.\n"); prom_halt(); } - strcpy(of_console_path, path); + strscpy(of_console_path, path, of_console_path_sz); } break; } diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index ba82884cb92a..aa4799cbb9c1 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -361,14 +361,16 @@ char * __init build_path_component(struct device_node *dp) { const char *name = of_get_property(dp, "name", NULL); char tmp_buf[64], *n; + size_t n_sz; tmp_buf[0] = '\0'; __build_path_component(dp, tmp_buf); if (tmp_buf[0] == '\0') - strcpy(tmp_buf, name); + strscpy(tmp_buf, name); - n = prom_early_alloc(strlen(tmp_buf) + 1); - strcpy(n, tmp_buf); + n_sz = strlen(tmp_buf) + 1; + n = prom_early_alloc(n_sz); + strscpy(n, tmp_buf, n_sz); return n; } diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index c9ec70888a39..d258fd10db01 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -120,11 +120,14 @@ EXPORT_SYMBOL(of_find_in_proplist); */ static int __init handle_nextprop_quirks(char *buf, const char *name) { - if (!name || strlen(name) == 0) + size_t name_len; + + name_len = name ? strlen(name) : 0; + if (name_len == 0) return -1; #ifdef CONFIG_SPARC32 - strcpy(buf, name); + strscpy(buf, name, name_len + 1); #endif return 0; } diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index c273ccebea46..c56333975fb1 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c @@ -218,7 +218,7 @@ static const struct user_regset sparc32_regsets[] = { * PSR, PC, nPC, Y, WIM, TBR */ [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = 38, .size = sizeof(u32), .align = sizeof(u32), .regset_get = genregs32_get, .set = genregs32_set @@ -234,7 +234,7 @@ static const struct user_regset sparc32_regsets[] = { * FPU QUEUE (64 32-bit ints) */ [REGSET_FP] = { - .core_note_type = NT_PRFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = 99, .size = sizeof(u32), .align = sizeof(u32), .regset_get = fpregs32_get, .set = fpregs32_set diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 4deba5b6eddb..9fc67fa9336f 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -420,7 +420,7 @@ static const struct user_regset sparc64_regsets[] = { * TSTATE, TPC, TNPC, Y */ [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = 36, .size = sizeof(u64), .align = sizeof(u64), .regset_get = genregs64_get, .set = genregs64_set @@ -432,7 +432,7 @@ static const struct user_regset sparc64_regsets[] = { * FPRS */ [REGSET_FP] = { - .core_note_type = NT_PRFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = 35, .size = sizeof(u64), .align = sizeof(u64), .regset_get = fpregs64_get, .set = fpregs64_set @@ -750,7 +750,7 @@ static const struct user_regset sparc32_regsets[] = { * PSR, PC, nPC, Y, WIM, TBR */ [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = 38, .size = sizeof(u32), .align = sizeof(u32), .regset_get = genregs32_get, .set = genregs32_set @@ -766,7 +766,7 @@ static const struct user_regset sparc32_regsets[] = { * FPU QUEUE (64 32-bit ints) */ [REGSET_FP] = { - .core_note_type = NT_PRFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = 99, .size = sizeof(u32), .align = sizeof(u32), .regset_get = fpregs32_get, .set = fpregs32_set diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 0bababf6f2bc..bb2794ce7aad 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -556,8 +556,8 @@ static void __init sbus_iommu_init(struct platform_device *op) } regs = pr->phys_addr; - iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); - strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC); + iommu = kzalloc_obj(*iommu, GFP_ATOMIC); + strbuf = kzalloc_obj(*strbuf, GFP_ATOMIC); if (!iommu || !strbuf) goto fatal_memory_error; diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c new file mode 100644 index 000000000000..4975867d9001 --- /dev/null +++ b/arch/sparc/kernel/setup.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <asm/setup.h> +#include <linux/sysctl.h> + +static const struct ctl_table sparc_sysctl_table[] = { + { + .procname = "reboot-cmd", + .data = reboot_command, + .maxlen = 256, + .mode = 0644, + .proc_handler = proc_dostring, + }, + { + .procname = "stop-a", + .data = &stop_a_enabled, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "scons-poweroff", + .data = &scons_pwroff, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#ifdef CONFIG_SPARC64 + { + .procname = "tsb-ratio", + .data = &sysctl_tsb_ratio, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif +}; + + +static int __init init_sparc_sysctls(void) +{ + register_sysctl_init("kernel", sparc_sysctl_table); + return 0; +} + +arch_initcall(init_sparc_sysctls); diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 704375c061e7..1b0db16cd37b 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -388,7 +388,7 @@ static int __init topology_init(void) err = 0; for_each_online_cpu(i) { - struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct cpu *p = kzalloc_obj(*p); if (!p) err = -ENOMEM; else diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 5cbd6ed5ef6f..371460e34484 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -297,8 +297,7 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, unsigned long hv_err; int i; - hdesc = kzalloc(struct_size(hdesc, maps, num_kernel_image_mappings), - GFP_KERNEL); + hdesc = kzalloc_flex(*hdesc, maps, num_kernel_image_mappings); if (!hdesc) { printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate " "hvtramp_descr.\n"); diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c index b8cd57d9182b..d8ee9a69ae31 100644 --- a/arch/sparc/kernel/starfire.c +++ b/arch/sparc/kernel/starfire.c @@ -50,7 +50,7 @@ void starfire_hookup(int upaid) struct starfire_irqinfo *p; unsigned long treg_base, hwmid, i; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) { prom_printf("starfire_hookup: No memory, this is insane.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 9a137c70e8d1..95683ecdc590 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -304,7 +304,7 @@ static unsigned int _sun4d_build_device_irq(unsigned int real_irq, if (unlikely(handler_data)) goto err_out; - handler_data = kzalloc(sizeof(struct sun4d_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct sun4d_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(sun4d_handler_data) failed.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 1079638986b5..fe8cfb1cdd3a 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -268,7 +268,7 @@ static unsigned int sun4m_build_device_irq(struct platform_device *op, if (unlikely(handler_data)) goto out; - handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct sun4m_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index f84a02ab6bf9..04432b82b9e3 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -58,7 +58,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, path, u32, high, u32, lo COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, u32, high, u32, low) { - return ksys_ftruncate(fd, ((u64)high << 32) | low); + return ksys_ftruncate(fd, ((u64)high << 32) | low, FTRUNCATE_LFS); } static int cp_compat_stat64(struct kstat *stat, diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index c5a284df7b41..ecefcffcf7b1 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -241,7 +241,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u if (flags & MAP_FIXED) { /* Ok, don't mess with it. */ - return mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags); + return mm_get_unmapped_area(NULL, orig_addr, len, pgoff, flags); } flags &= ~MAP_SHARED; @@ -254,7 +254,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u align_goal = (64UL * 1024); do { - addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, + addr = mm_get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); if (!(addr & ~PAGE_MASK)) { addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); @@ -273,7 +273,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u * be obtained. */ if (addr & ~PAGE_MASK) - addr = mm_get_unmapped_area(current->mm, NULL, orig_addr, len, pgoff, flags); + addr = mm_get_unmapped_area(NULL, orig_addr, len, pgoff, flags); return addr; } @@ -294,7 +294,7 @@ static unsigned long mmap_rnd(void) return rnd << PAGE_SHIFT; } -void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) +void arch_pick_mmap_layout(struct mm_struct *mm, const struct rlimit *rlim_stack) { unsigned long random_factor = mmap_rnd(); unsigned long gap; @@ -309,7 +309,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) gap == RLIM_INFINITY || sysctl_legacy_va_layout) { mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; - clear_bit(MMF_TOPDOWN, &mm->flags); + mm_flags_clear(MMF_TOPDOWN, mm); } else { /* We know it's 32-bit */ unsigned long task_size = STACK_TOP32; @@ -320,7 +320,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) gap = (task_size / 6 * 5); mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor); - set_bit(MMF_TOPDOWN, &mm->flags); + mm_flags_set(MMF_TOPDOWN, mm); } } @@ -647,8 +647,7 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, } if (!current_thread_info()->utraps) { current_thread_info()->utraps = - kcalloc(UT_TRAP_INSTRUCTION_31 + 1, sizeof(long), - GFP_KERNEL); + kzalloc_objs(long, UT_TRAP_INSTRUCTION_31 + 1); if (!current_thread_info()->utraps) return -ENOMEM; current_thread_info()->utraps[0] = 1; @@ -658,9 +657,7 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, unsigned long *p = current_thread_info()->utraps; current_thread_info()->utraps = - kmalloc_array(UT_TRAP_INSTRUCTION_31 + 1, - sizeof(long), - GFP_KERNEL); + kmalloc_objs(long, UT_TRAP_INSTRUCTION_31 + 1); if (!current_thread_info()->utraps) { current_thread_info()->utraps = p; return -ENOMEM; diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 0e8ab0602c36..96fe8763d70c 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -103,6 +103,12 @@ sys_clone: ba,pt %xcc, sparc_clone add %sp, PTREGS_OFF, %o0 + .align 32 +__sys_clone3: + flushw + ba,pt %xcc, sparc_clone3 + add %sp, PTREGS_OFF, %o0 + .globl ret_from_fork ret_from_fork: /* Clear current_thread_info()->new_child. */ @@ -113,6 +119,8 @@ ret_from_fork: brnz,pt %o0, ret_sys_call ldx [%g6 + TI_FLAGS], %l0 ldx [%sp + PTREGS_OFF + PT_V9_G1], %l1 + brz,pt %l1, ret_sys_call + nop call %l1 ldx [%sp + PTREGS_OFF + PT_V9_G2], %o0 ba,pt %xcc, ret_sys_call diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index 727f99d333b3..7e71bf7fcd14 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -480,7 +480,7 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open -# 435 reserved for clone3 +435 common clone3 __sys_clone3 436 common close_range sys_close_range 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd @@ -512,3 +512,8 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr +468 common file_getattr sys_file_getattr +469 common file_setattr sys_file_setattr +470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index b32f27f929d1..87b267043ccd 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -838,14 +838,14 @@ void __init time_init_early(void) if (tlb_type == spitfire) { if (is_hummingbird()) { init_tick_ops(&hbtick_operations); - clocksource_tick.archdata.vclock_mode = VCLOCK_NONE; + clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_NONE; } else { init_tick_ops(&tick_operations); - clocksource_tick.archdata.vclock_mode = VCLOCK_TICK; + clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_TICK; } } else { init_tick_ops(&stick_operations); - clocksource_tick.archdata.vclock_mode = VCLOCK_STICK; + clocksource_tick.vdso_clock_mode = VDSO_CLOCKMODE_STICK; } } diff --git a/arch/sparc/kernel/vdso.c b/arch/sparc/kernel/vdso.c deleted file mode 100644 index 0e27437eb97b..000000000000 --- a/arch/sparc/kernel/vdso.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE - * Copyright 2003 Andi Kleen, SuSE Labs. - * - * Thanks to hpa@transmeta.com for some useful hint. - * Special thanks to Ingo Molnar for his early experience with - * a different vsyscall implementation for Linux/IA32 and for the name. - */ - -#include <linux/time.h> -#include <linux/timekeeper_internal.h> - -#include <asm/vvar.h> - -void update_vsyscall_tz(void) -{ - if (unlikely(vvar_data == NULL)) - return; - - vvar_data->tz_minuteswest = sys_tz.tz_minuteswest; - vvar_data->tz_dsttime = sys_tz.tz_dsttime; -} - -void update_vsyscall(struct timekeeper *tk) -{ - struct vvar_data *vdata = vvar_data; - - if (unlikely(vdata == NULL)) - return; - - vvar_write_begin(vdata); - vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; - vdata->clock.cycle_last = tk->tkr_mono.cycle_last; - vdata->clock.mask = tk->tkr_mono.mask; - vdata->clock.mult = tk->tkr_mono.mult; - vdata->clock.shift = tk->tkr_mono.shift; - - vdata->wall_time_sec = tk->xtime_sec; - vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; - - vdata->monotonic_time_sec = tk->xtime_sec + - tk->wall_to_monotonic.tv_sec; - vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + - (tk->wall_to_monotonic.tv_nsec << - tk->tkr_mono.shift); - - while (vdata->monotonic_time_snsec >= - (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) { - vdata->monotonic_time_snsec -= - ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift; - vdata->monotonic_time_sec++; - } - - vdata->wall_time_coarse_sec = tk->xtime_sec; - vdata->wall_time_coarse_nsec = - (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); - - vdata->monotonic_time_coarse_sec = - vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec; - vdata->monotonic_time_coarse_nsec = - vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec; - - while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) { - vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC; - vdata->monotonic_time_coarse_sec++; - } - - vvar_write_end(vdata); -} diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 07933d75ac81..8b4f55047716 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/irq.h> #include <linux/export.h> #include <linux/init.h> @@ -324,7 +325,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, return NULL; } - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) { printk(KERN_ERR "VIO: Could not allocate vio_dev\n"); return NULL; @@ -378,8 +379,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, * the parent doesn't require the MD node info. */ if (node_name != NULL) { - (void) snprintf(vdev->node_name, VIO_MAX_NAME_LEN, "%s", - node_name); + strscpy(vdev->node_name, node_name); err = mdesc_get_node_info(hp, mp, node_name, &vdev->md_node_info); @@ -419,13 +419,13 @@ struct vio_remove_node_data { u64 node; }; -static int vio_md_node_match(struct device *dev, void *arg) +static int vio_md_node_match(struct device *dev, const void *arg) { struct vio_dev *vdev = to_vio_dev(dev); - struct vio_remove_node_data *node_data; + const struct vio_remove_node_data *node_data; u64 node; - node_data = (struct vio_remove_node_data *)arg; + node_data = (const struct vio_remove_node_data *)arg; node = vio_vdev_node(node_data->hp, vdev); diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index e27afd233bf5..8fb2e7ca5015 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c @@ -804,7 +804,7 @@ EXPORT_SYMBOL(vio_port_up); static void vio_port_timer(struct timer_list *t) { - struct vio_driver_state *vio = from_timer(vio, t, timer); + struct vio_driver_state *vio = timer_container_of(vio, t, timer); vio_port_up(vio); } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index f1b86eb30340..7ea510d9b42f 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -191,6 +191,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS |
