diff options
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 46 | 
1 files changed, 21 insertions, 25 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 68fd3d29279..cafb41000f6 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -479,6 +479,13 @@ static int acpi_processor_get_psd(struct acpi_processor	*pr)  		goto end;  	} +	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && +	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && +	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { +		printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n"); +		result = -EFAULT; +		goto end; +	}  end:  	kfree(buffer.pointer);  	return result; @@ -501,9 +508,10 @@ int acpi_processor_preregister_performance(  	mutex_lock(&performance_mutex); -	retval = 0; - -	/* Call _PSD for all CPUs */ +	/* +	 * Check if another driver has already registered, and abort before +	 * changing pr->performance if it has. Check input data as well. +	 */  	for_each_possible_cpu(i) {  		pr = per_cpu(processors, i);  		if (!pr) { @@ -513,13 +521,20 @@ int acpi_processor_preregister_performance(  		if (pr->performance) {  			retval = -EBUSY; -			continue; +			goto err_out;  		}  		if (!performance || !per_cpu_ptr(performance, i)) {  			retval = -EINVAL; -			continue; +			goto err_out;  		} +	} + +	/* Call _PSD for all CPUs */ +	for_each_possible_cpu(i) { +		pr = per_cpu(processors, i); +		if (!pr) +			continue;  		pr->performance = per_cpu_ptr(performance, i);  		cpumask_set_cpu(i, pr->performance->shared_cpu_map); @@ -535,26 +550,6 @@ int acpi_processor_preregister_performance(  	 * Now that we have _PSD data from all CPUs, lets setup P-state   	 * domain info.  	 */ -	for_each_possible_cpu(i) { -		pr = per_cpu(processors, i); -		if (!pr) -			continue; - -		/* Basic validity check for domain info */ -		pdomain = &(pr->performance->domain_info); -		if ((pdomain->revision != ACPI_PSD_REV0_REVISION) || -		    (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) { -			retval = -EINVAL; -			goto err_ret; -		} -		if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && -		    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && -		    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { -			retval = -EINVAL; -			goto err_ret; -		} -	} -  	cpumask_clear(covered_cpus);  	for_each_possible_cpu(i) {  		pr = per_cpu(processors, i); @@ -643,6 +638,7 @@ err_ret:  		pr->performance = NULL; /* Will be set for real in register */  	} +err_out:  	mutex_unlock(&performance_mutex);  	free_cpumask_var(covered_cpus);  	return retval;  |