diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/sun4/os/mp_startup.c | 28 | ||||
-rw-r--r-- | usr/src/uts/sun4/os/startup.c | 7 | ||||
-rw-r--r-- | usr/src/uts/sun4u/os/mach_mp_startup.c | 15 | ||||
-rw-r--r-- | usr/src/uts/sun4u/os/mach_startup.c | 5 | ||||
-rw-r--r-- | usr/src/uts/sun4v/os/intrq.c | 139 | ||||
-rw-r--r-- | usr/src/uts/sun4v/os/mach_mp_startup.c | 11 |
6 files changed, 126 insertions, 79 deletions
diff --git a/usr/src/uts/sun4/os/mp_startup.c b/usr/src/uts/sun4/os/mp_startup.c index cb793f3563..8436db7273 100644 --- a/usr/src/uts/sun4/os/mp_startup.c +++ b/usr/src/uts/sun4/os/mp_startup.c @@ -46,7 +46,7 @@ #endif /* TRAPTRACE */ #include <sys/cpu_sgnblk_defs.h> -extern void cpu_intrq_setup(struct cpu *); +extern int cpu_intrq_setup(struct cpu *); extern void cpu_intrq_cleanup(struct cpu *); extern void cpu_intrq_register(struct cpu *); @@ -280,7 +280,7 @@ int trap_trace_inuse[NCPU]; /* * Routine to set up a CPU to prepare for starting it up. */ -void +int setup_cpu_common(int cpuid) { struct cpu *cp = NULL; @@ -292,6 +292,7 @@ setup_cpu_common(int cpuid) #endif /* TRAPTRACE */ extern void idle(); + int rval; ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(cpu[cpuid] == NULL); @@ -419,13 +420,16 @@ setup_cpu_common(int cpuid) if (nosteal_nsec == -1) cmp_set_nosteal_interval(); - cpu_intrq_setup(cp); + if ((rval = cpu_intrq_setup(cp)) != 0) { + return (rval); + } /* * Initialize MMU context domain information. */ sfmmu_cpu_init(cp); + return (0); } /* @@ -450,8 +454,10 @@ cleanup_cpu_common(int cpuid) cpu_uninit_private(cp); /* Free cpu ID string and brand string. */ - kmem_free(cp->cpu_idstr, strlen(cp->cpu_idstr) + 1); - kmem_free(cp->cpu_brandstr, strlen(cp->cpu_brandstr) + 1); + if (cp->cpu_idstr) + kmem_free(cp->cpu_idstr, strlen(cp->cpu_idstr) + 1); + if (cp->cpu_brandstr) + kmem_free(cp->cpu_brandstr, strlen(cp->cpu_brandstr) + 1); cpu_vm_data_destroy(cp); @@ -512,7 +518,8 @@ cleanup_cpu_common(int cpuid) */ disp_cpu_fini(cp); cpu_pa[cpuid] = 0; - sfmmu_cpu_cleanup(cp); + if (CPU_MMU_CTXP(cp)) + sfmmu_cpu_cleanup(cp); bzero(cp, sizeof (*cp)); /* @@ -651,11 +658,6 @@ slave_startup(void) extern struct cpu *cpu[NCPU]; /* pointers to all CPUs */ -extern void setup_cpu_common(int); -extern void common_startup_init(cpu_t *, int); -extern void start_cpu(int, void(*func)(int)); -extern void cold_flag_set(int cpuid); - /* * cpu_bringup_set is a tunable (via /etc/system, debugger, etc.) that * can be used during debugging to control which processors are brought @@ -752,7 +754,9 @@ start_other_cpus(int flag) ASSERT(cpu[cpuid] == NULL); - setup_cpu_common(cpuid); + if (setup_cpu_common(cpuid)) { + cmn_err(CE_PANIC, "cpu%d: setup failed", cpuid); + } common_startup_init(cpu[cpuid], cpuid); diff --git a/usr/src/uts/sun4/os/startup.c b/usr/src/uts/sun4/os/startup.c index ffa5783f4a..36c62b2343 100644 --- a/usr/src/uts/sun4/os/startup.c +++ b/usr/src/uts/sun4/os/startup.c @@ -67,7 +67,7 @@ #include <sys/mmu.h> extern void setup_trap_table(void); -extern void cpu_intrq_setup(struct cpu *); +extern int cpu_intrq_setup(struct cpu *); extern void cpu_intrq_register(struct cpu *); extern void contig_mem_init(void); extern void mach_dump_buffer_init(void); @@ -2320,7 +2320,10 @@ startup_end(void) */ contig_mem_init(); mach_descrip_init(); - cpu_intrq_setup(CPU); + + if (cpu_intrq_setup(CPU)) { + cmn_err(CE_PANIC, "cpu%d: setup failed", CPU->cpu_id); + } cpu_intrq_register(CPU); mach_htraptrace_setup(CPU->cpu_id); mach_htraptrace_configure(CPU->cpu_id); diff --git a/usr/src/uts/sun4u/os/mach_mp_startup.c b/usr/src/uts/sun4u/os/mach_mp_startup.c index ad0b76e1c6..243e56a3ac 100644 --- a/usr/src/uts/sun4u/os/mach_mp_startup.c +++ b/usr/src/uts/sun4u/os/mach_mp_startup.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -154,7 +153,7 @@ int mp_cpu_configure(int cpuid) { extern void fill_cpu_ddi(dev_info_t *); - extern void setup_cpu_common(int); + extern int setup_cpu_common(int); struct mp_find_cpu_arg target; ASSERT(MUTEX_HELD(&cpu_lock)); @@ -172,7 +171,11 @@ mp_cpu_configure(int cpuid) */ fill_cpu_ddi(target.dip); - setup_cpu_common(cpuid); + /* + * sun4v cpu setup may fail. sun4u assumes cpu setup to + * be always successful, so the return value is ignored. + */ + (void) setup_cpu_common(cpuid); return (0); } diff --git a/usr/src/uts/sun4u/os/mach_startup.c b/usr/src/uts/sun4u/os/mach_startup.c index daa681b744..d2605b75c5 100644 --- a/usr/src/uts/sun4u/os/mach_startup.c +++ b/usr/src/uts/sun4u/os/mach_startup.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -394,10 +394,11 @@ mach_cpu_halt_idle() } /*ARGSUSED*/ -void +int cpu_intrq_setup(struct cpu *cp) { /* Interrupt mondo queues not applicable to sun4u */ + return (0); } /*ARGSUSED*/ diff --git a/usr/src/uts/sun4v/os/intrq.c b/usr/src/uts/sun4v/os/intrq.c index ae905ed312..e2158a703b 100644 --- a/usr/src/uts/sun4v/os/intrq.c +++ b/usr/src/uts/sun4v/os/intrq.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,40 +58,32 @@ cpu_intrq_register(struct cpu *cpu) ret = hv_cpu_qconf(CPU_NRQ, mcpup->cpu_nrq_base_pa, cpu_nrq_entries); if (ret != H_EOK) cmn_err(CE_PANIC, "cpu%d: non-resumable error queue " - "configuration failed, error %lu", cpu->cpu_id, ret); + "configuration failed, error %lu", cpu->cpu_id, ret); } -void +int cpu_intrq_setup(struct cpu *cpu) { struct machcpu *mcpup = &cpu->cpu_m; - int cpu_list_size; - uint64_t cpu_q_size; - uint64_t dev_q_size; - uint64_t cpu_rq_size; - uint64_t cpu_nrq_size; + size_t size; /* - * Allocate mondo data for xcalls. + * This routine will return with an error return if any + * contig_mem_alloc() fails. It is expected that the caller will + * call cpu_intrq_cleanup() (or cleanup_cpu_common() which will). + * That will cleanly free only those blocks that were alloc'd. */ - mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE); - if (mcpup->mondo_data == NULL) - cmn_err(CE_PANIC, "cpu%d: cpu mondo_data allocation failed", - cpu->cpu_id); /* - * Allocate a percpu list of NCPU for xcalls + * Allocate mondo data for xcalls. */ - cpu_list_size = NCPU * sizeof (uint16_t); - if (cpu_list_size < INTR_REPORT_SIZE) - cpu_list_size = INTR_REPORT_SIZE; - - mcpup->cpu_list = contig_mem_alloc(cpu_list_size); - if (mcpup->cpu_list == NULL) - cmn_err(CE_PANIC, "cpu%d: cpu cpu_list allocation failed", - cpu->cpu_id); - mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list); + mcpup->mondo_data = contig_mem_alloc(INTR_REPORT_SIZE); + if (mcpup->mondo_data == NULL) { + cmn_err(CE_NOTE, "cpu%d: cpu mondo_data allocation failed", + cpu->cpu_id); + return (ENOMEM); + } /* * va_to_pa() is too expensive to call for every crosscall * so we do it here at init time and save it in machcpu. @@ -99,45 +91,86 @@ cpu_intrq_setup(struct cpu *cpu) mcpup->mondo_data_ra = va_to_pa(mcpup->mondo_data); /* + * Allocate a percpu list of NCPU for xcalls + */ + size = NCPU * sizeof (uint16_t); + if (size < INTR_REPORT_SIZE) + size = INTR_REPORT_SIZE; + + mcpup->cpu_list = contig_mem_alloc(size); + + if (mcpup->cpu_list == NULL) { + cmn_err(CE_NOTE, "cpu%d: cpu cpu_list allocation failed", + cpu->cpu_id); + return (ENOMEM); + } + mcpup->cpu_list_ra = va_to_pa(mcpup->cpu_list); + + /* * Allocate sun4v interrupt and error queues. */ - cpu_q_size = cpu_q_entries * INTR_REPORT_SIZE; - mcpup->cpu_q_va = contig_mem_alloc(cpu_q_size); - if (mcpup->cpu_q_va == NULL) - cmn_err(CE_PANIC, "cpu%d: cpu intrq allocation failed", - cpu->cpu_id); + size = cpu_q_entries * INTR_REPORT_SIZE; + + mcpup->cpu_q_va = contig_mem_alloc(size); + + if (mcpup->cpu_q_va == NULL) { + cmn_err(CE_NOTE, "cpu%d: cpu intrq allocation failed", + cpu->cpu_id); + return (ENOMEM); + } mcpup->cpu_q_base_pa = va_to_pa(mcpup->cpu_q_va); - mcpup->cpu_q_size = cpu_q_size; + mcpup->cpu_q_size = size; + + /* + * Allocate device queues + */ + size = dev_q_entries * INTR_REPORT_SIZE; + + mcpup->dev_q_va = contig_mem_alloc(size); - dev_q_size = dev_q_entries * INTR_REPORT_SIZE; - mcpup->dev_q_va = contig_mem_alloc(dev_q_size); - if (mcpup->dev_q_va == NULL) - cmn_err(CE_PANIC, "cpu%d: dev intrq allocation failed", - cpu->cpu_id); + if (mcpup->dev_q_va == NULL) { + cmn_err(CE_NOTE, "cpu%d: dev intrq allocation failed", + cpu->cpu_id); + return (ENOMEM); + } mcpup->dev_q_base_pa = va_to_pa(mcpup->dev_q_va); - mcpup->dev_q_size = dev_q_size; - - /* Allocate resumable queue and its kernel buffer */ - cpu_rq_size = cpu_rq_entries * Q_ENTRY_SIZE; - mcpup->cpu_rq_va = contig_mem_alloc(2 * cpu_rq_size); - if (mcpup->cpu_rq_va == NULL) - cmn_err(CE_PANIC, "cpu%d: resumable queue allocation failed", - cpu->cpu_id); + mcpup->dev_q_size = size; + + /* + * Allocate resumable queue and its kernel buffer + */ + size = cpu_rq_entries * Q_ENTRY_SIZE; + + mcpup->cpu_rq_va = contig_mem_alloc(2 * size); + + if (mcpup->cpu_rq_va == NULL) { + cmn_err(CE_NOTE, "cpu%d: resumable queue allocation failed", + cpu->cpu_id); + return (ENOMEM); + } mcpup->cpu_rq_base_pa = va_to_pa(mcpup->cpu_rq_va); - mcpup->cpu_rq_size = cpu_rq_size; + mcpup->cpu_rq_size = size; /* zero out the memory */ - bzero(mcpup->cpu_rq_va, 2 * cpu_rq_size); - - /* Allocate nonresumable queue here */ - cpu_nrq_size = cpu_nrq_entries * Q_ENTRY_SIZE; - mcpup->cpu_nrq_va = contig_mem_alloc(2 * cpu_nrq_size); - if (mcpup->cpu_nrq_va == NULL) - cmn_err(CE_PANIC, "cpu%d: nonresumable queue " - "allocation failed", cpu->cpu_id); + bzero(mcpup->cpu_rq_va, 2 * size); + + /* + * Allocate non-resumable queues + */ + size = cpu_nrq_entries * Q_ENTRY_SIZE; + + mcpup->cpu_nrq_va = contig_mem_alloc(2 * size); + + if (mcpup->cpu_nrq_va == NULL) { + cmn_err(CE_NOTE, "cpu%d: nonresumable queue allocation failed", + cpu->cpu_id); + return (ENOMEM); + } mcpup->cpu_nrq_base_pa = va_to_pa(mcpup->cpu_nrq_va); - mcpup->cpu_nrq_size = cpu_nrq_size; + mcpup->cpu_nrq_size = size; /* zero out the memory */ - bzero(mcpup->cpu_nrq_va, 2 * cpu_nrq_size); + bzero(mcpup->cpu_nrq_va, 2 * size); + + return (0); } void diff --git a/usr/src/uts/sun4v/os/mach_mp_startup.c b/usr/src/uts/sun4v/os/mach_mp_startup.c index 7d4df1fe7d..4c9ee0d057 100644 --- a/usr/src/uts/sun4v/os/mach_mp_startup.c +++ b/usr/src/uts/sun4v/os/mach_mp_startup.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -166,7 +166,8 @@ int mp_cpu_configure(int cpuid) { extern void fill_cpu(md_t *, mde_cookie_t); - extern void setup_cpu_common(int); + extern int setup_cpu_common(int); + extern int cleanup_cpu_common(int); extern void setup_exec_unit_mappings(md_t *); md_t *mdp; mde_cookie_t rootnode, cpunode = MDE_INVAL_ELEM_COOKIE; @@ -226,8 +227,10 @@ mp_cpu_configure(int cpuid) (void) md_fini_handle(mdp); - setup_cpu_common(cpuid); - + if ((i = setup_cpu_common(cpuid)) != 0) { + (void) cleanup_cpu_common(cpuid); + return (i); + } return (0); } |