Index: trunk/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c =================================================================== --- trunk/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c (revision 10421) +++ trunk/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c (working copy) @@ -418,7 +418,7 @@ /* pointer to _cpuid4_info array (for each cache leaf) */ static struct _cpuid4_info *cpuid4_info[NR_CPUS]; -#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) +#define CPUID4_INFO_IDX(x,y) (cpuid4_info[x]?(&((cpuid4_info[x])[y])):NULL) #ifdef CONFIG_SMP static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) @@ -429,20 +429,23 @@ struct cpuinfo_x86 *c = cpu_data; this_leaf = CPUID4_INFO_IDX(cpu, index); - num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; + if (this_leaf) { + num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; - if (num_threads_sharing == 1) - cpu_set(cpu, this_leaf->shared_cpu_map); - else { - index_msb = get_count_order(num_threads_sharing); + if (num_threads_sharing == 1) + cpu_set(cpu, this_leaf->shared_cpu_map); + else { + index_msb = get_count_order(num_threads_sharing); - for_each_online_cpu(i) { - if (c[i].apicid >> index_msb == - c[cpu].apicid >> index_msb) { - cpu_set(i, this_leaf->shared_cpu_map); - if (i != cpu && cpuid4_info[i]) { - sibling_leaf = CPUID4_INFO_IDX(i, index); - cpu_set(cpu, sibling_leaf->shared_cpu_map); + for_each_online_cpu(i) { + if (c[i].apicid >> index_msb == + c[cpu].apicid >> index_msb) { + cpu_set(i, this_leaf->shared_cpu_map); + if (i != cpu && cpuid4_info[i]) { + sibling_leaf = CPUID4_INFO_IDX(i, index); + if (sibling_leaf) + cpu_set(cpu, sibling_leaf->shared_cpu_map); + } } } } @@ -454,9 +457,11 @@ int sibling; this_leaf = CPUID4_INFO_IDX(cpu, index); - for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) { - sibling_leaf = CPUID4_INFO_IDX(sibling, index); - cpu_clear(cpu, sibling_leaf->shared_cpu_map); + if (this_leaf) { + for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) { + sibling_leaf = CPUID4_INFO_IDX(sibling, index); + cpu_clear(cpu, sibling_leaf->shared_cpu_map); + } } } #else @@ -496,10 +501,12 @@ retval = 0; for (j = 0; j < num_cache_leaves; j++) { this_leaf = CPUID4_INFO_IDX(cpu, j); - retval = cpuid4_cache_lookup(j, this_leaf); - if (unlikely(retval < 0)) - break; - cache_shared_cpu_map_setup(cpu, j); + if (this_leaf) { + retval = cpuid4_cache_lookup(j, this_leaf); + if (unlikely(retval < 0)) + break; + cache_shared_cpu_map_setup(cpu, j); + } } set_cpus_allowed(current, oldmask); @@ -527,7 +534,7 @@ /* pointer to array of kobjects for cpuX/cache/indexY */ static struct _index_kobject *index_kobject[NR_CPUS]; -#define INDEX_KOBJECT_PTR(x,y) (&((index_kobject[x])[y])) +#define INDEX_KOBJECT_PTR(x,y) (index_kobject[x]?(&((index_kobject[x])[y])):NULL) #define show_one_plus(file_name, object, val) \ static ssize_t show_##file_name \ @@ -608,12 +615,14 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) { struct _cache_attr *fattr = to_attr(attr); - struct _index_kobject *this_leaf = to_object(kobj); + struct _index_kobject *this_leaf_obj = to_object(kobj); + struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(this_leaf_obj->cpu, + this_leaf_obj->index); + ssize_t ret; - ret = fattr->show ? - fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), - buf) : + ret = fattr->show && this_leaf? + fattr->show(this_leaf,buf) : 0; return ret; } @@ -696,6 +705,9 @@ for (i = 0; i < num_cache_leaves; i++) { this_object = INDEX_KOBJECT_PTR(cpu,i); + if (!this_object) + continue; + this_object->cpu = cpu; this_object->index = i; this_object->kobj.parent = cache_kobject[cpu]; @@ -704,8 +716,10 @@ retval = kobject_register(&(this_object->kobj)); if (unlikely(retval)) { for (j = 0; j < i; j++) { - kobject_unregister( - &(INDEX_KOBJECT_PTR(cpu,j)->kobj)); + struct _index_kobject *robj = + INDEX_KOBJECT_PTR(cpu,j); + if (robj) + kobject_unregister(&robj->kobj); } kobject_unregister(cache_kobject[cpu]); cpuid4_cache_sysfs_exit(cpu); @@ -719,12 +733,16 @@ { unsigned int cpu = sys_dev->id; unsigned long i; + struct _index_kobject *this_object; for (i = 0; i < num_cache_leaves; i++) { cache_remove_shared_cpu_map(cpu, i); - kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); + this_object = INDEX_KOBJECT_PTR(cpu,i); + if (this_object) + kobject_unregister(&this_object->kobj); } - kobject_unregister(cache_kobject[cpu]); + if (cache_kobject[cpu]) + kobject_unregister(cache_kobject[cpu]); cpuid4_cache_sysfs_exit(cpu); return; }