diff options
author | edp <none@none> | 2007-05-15 13:28:37 -0700 |
---|---|---|
committer | edp <none@none> | 2007-05-15 13:28:37 -0700 |
commit | 725deb8fd64fbf9c978c9fe35c9d5cc1e4a7b6c2 (patch) | |
tree | 9f7763f5dd370269d33f86e367b1a950c93da29d /usr/src | |
parent | 207c561d680c931abe394588f09474c69152b253 (diff) | |
download | illumos-gate-725deb8fd64fbf9c978c9fe35c9d5cc1e4a7b6c2.tar.gz |
6557021 snv_64: panic on booting an lx branded zone
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/os/brand.c | 76 | ||||
-rw-r--r-- | usr/src/uts/common/os/zone.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/sys/brand.h | 5 |
3 files changed, 25 insertions, 70 deletions
diff --git a/usr/src/uts/common/os/brand.c b/usr/src/uts/common/os/brand.c index 285828236c..39aeee38c1 100644 --- a/usr/src/uts/common/os/brand.c +++ b/usr/src/uts/common/os/brand.c @@ -38,6 +38,10 @@ #define SUPPORTED_BRAND_VERSION BRAND_VER_1 #if defined(__sparcv9) +/* sparcv9 uses system wide brand interposition hooks */ +static void brand_plat_interposition_enable(void); +static void brand_plat_interposition_disable(void); + struct brand_mach_ops native_mach_ops = { NULL, NULL }; @@ -67,12 +71,6 @@ struct brand_list { static struct brand_list *brand_list = NULL; /* - * Used to enable brand platform specific interposition code - */ -#pragma weak brand_plat_interposition_init -extern void brand_plat_interposition_init(void); - -/* * This lock protects the integrity of the brand list. */ static kmutex_t brand_list_lock; @@ -80,8 +78,6 @@ static kmutex_t brand_list_lock; void brand_init() { - if (brand_plat_interposition_init != NULL) - brand_plat_interposition_init(); mutex_init(&brand_list_lock, NULL, MUTEX_DEFAULT, NULL); p0.p_brand = &native_brand; } @@ -141,10 +137,17 @@ brand_register(brand_t *brand) } } +#if defined(__sparcv9) + /* sparcv9 uses system wide brand interposition hooks */ + if (brand_list == NULL) + brand_plat_interposition_enable(); +#endif /* __sparcv9 */ + list->bl_brand = brand; list->bl_refcnt = 0; list->bl_next = brand_list; brand_list = list; + mutex_exit(&brand_list_lock); return (0); @@ -193,6 +196,12 @@ brand_unregister(brand_t *brand) else brand_list = list->bl_next; +#if defined(__sparcv9) + /* sparcv9 uses system wide brand interposition hooks */ + if (brand_list == NULL) + brand_plat_interposition_disable(); +#endif /* __sparcv9 */ + mutex_exit(&brand_list_lock); kmem_free(list, sizeof (struct brand_list)); @@ -332,14 +341,12 @@ brand_setbrand(proc_t *p) #if defined(__sparcv9) /* - * Currently, only sparc has platform level brand syscall interposition. + * Currently, only sparc has system level brand syscall interposition. * On x86 we're able to enable syscall interposition on a per-cpu basis * when a branded thread is scheduled to run on a cpu. */ /* Local variables needed for dynamic syscall interposition support */ -static kmutex_t brand_interposition_lock; -static int brand_interposition_count; static uint32_t syscall_trap_patch_instr_orig; static uint32_t syscall_trap32_patch_instr_orig; @@ -356,34 +363,15 @@ extern void syscall_wrapper32(void); #define DISP22(from, to) \ ((((uintptr_t)(to) - (uintptr_t)(from)) >> 2) & 0x3fffff) -void -brand_plat_interposition_init(void) -{ - mutex_init(&brand_interposition_lock, NULL, MUTEX_DEFAULT, NULL); - brand_interposition_count = 0; -} - /*ARGSUSED*/ -void -brand_plat_interposition_enable(brand_t *bp) +static void +brand_plat_interposition_enable(void) { - ASSERT((bp != NULL) && (bp != &native_brand)); - - mutex_enter(&brand_interposition_lock); - ASSERT(brand_interposition_count >= 0); - - if (brand_interposition_count++ > 0) { - mutex_exit(&brand_interposition_lock); - return; - } + ASSERT(MUTEX_HELD(&brand_list_lock)); /* - * This is the first branded zone that is being enabled on - * this system. - * * Before we hot patch the kernel save the current instructions - * so that we can restore them if all branded zones on the - * system are shutdown. + * so that we can restore them later. */ syscall_trap_patch_instr_orig = *(uint32_t *)syscall_trap_patch_point; @@ -411,27 +399,15 @@ brand_plat_interposition_enable(brand_t *bp) hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point, BA_A_INSTR | DISP22(syscall_trap32_patch_point, syscall_wrapper32), 4); - - mutex_exit(&brand_interposition_lock); } /*ARGSUSED*/ -void -brand_plat_interposition_disable(brand_t *bp) +static void +brand_plat_interposition_disable(void) { - ASSERT((bp != NULL) && (bp != &native_brand)); - - mutex_enter(&brand_interposition_lock); - ASSERT(brand_interposition_count > 0); - - if (--brand_interposition_count > 0) { - mutex_exit(&brand_interposition_lock); - return; - } + ASSERT(MUTEX_HELD(&brand_list_lock)); /* - * The last branded zone on this system has been shutdown. - * * Restore the original instructions at the trap table syscall * patch points to disable the brand syscall interposition * mechanism. @@ -440,7 +416,5 @@ brand_plat_interposition_disable(brand_t *bp) syscall_trap_patch_instr_orig, 4); hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point, syscall_trap32_patch_instr_orig, 4); - - mutex_exit(&brand_interposition_lock); } #endif /* __sparcv9 */ diff --git a/usr/src/uts/common/os/zone.c b/usr/src/uts/common/os/zone.c index dbb1849208..2f2981b27a 100644 --- a/usr/src/uts/common/os/zone.c +++ b/usr/src/uts/common/os/zone.c @@ -2762,7 +2762,6 @@ zsched(void *arg) task_t *tk, *oldtk; rctl_entity_p_t e; kproject_t *pj; - boolean_t disable_plat_interposition = B_FALSE; nvlist_t *nvl = za->nvlist; nvpair_t *nvp = NULL; @@ -2988,13 +2987,6 @@ zsched(void *arg) if (zone_status_get(zone) == ZONE_IS_BOOTING) { id_t cid; - /* enable platform wide brand interposition mechanisms */ - if (ZONE_IS_BRANDED(zone) && - brand_plat_interposition_enable != NULL) { - disable_plat_interposition = B_TRUE; - brand_plat_interposition_enable(zone->zone_brand); - } - /* * Ok, this is a little complicated. We need to grab the * zone's pool's scheduling class ID; note that by now, we @@ -3037,12 +3029,6 @@ zsched(void *arg) */ zone_status_wait_cpr(zone, ZONE_IS_DYING, "zsched"); - /* disable platform wide brand interposition mechanisms */ - if (disable_plat_interposition && - brand_plat_interposition_disable != NULL) { - brand_plat_interposition_disable(zone->zone_brand); - } - if (ct) /* * At this point the process contract should be empty. diff --git a/usr/src/uts/common/sys/brand.h b/usr/src/uts/common/sys/brand.h index f9d5412e14..99314a95f0 100644 --- a/usr/src/uts/common/sys/brand.h +++ b/usr/src/uts/common/sys/brand.h @@ -117,9 +117,6 @@ extern brand_t native_brand; #define ZBROP(z) ((z)->zone_brand->b_ops) #define BRMOP(p) ((p)->p_brand->b_machops) -#pragma weak brand_plat_interposition_enable -#pragma weak brand_plat_interposition_disable - extern void brand_init(); extern int brand_register(brand_t *); extern int brand_unregister(brand_t *); @@ -128,8 +125,6 @@ extern brand_t *brand_find_name(char *); extern void brand_unregister_zone(brand_t *); extern int brand_zone_count(brand_t *); extern void brand_setbrand(proc_t *); -extern void brand_plat_interposition_enable(brand_t *); -extern void brand_plat_interposition_disable(brand_t *); #endif /* _KERNEL */ #ifdef __cplusplus |