diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-04-13 13:24:54 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-04-13 13:24:54 +0200 | 
| commit | 2b2f862ee6ef8ae8f913fee6af2112c5ffeedf94 (patch) | |
| tree | 06a89df37436f9902a37800e05541880ba3aa603 /arch/x86/kernel/amd_iommu_init.c | |
| parent | 0d0fb0f9c5fddef4a10242fe3337f00f528a3099 (diff) | |
| parent | 4b83873d3da0704987cb116833818ed96214ee29 (diff) | |
Merge branch 'iommu/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu into x86/urgent
Diffstat (limited to 'arch/x86/kernel/amd_iommu_init.c')
| -rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 48 | 
1 files changed, 33 insertions, 15 deletions
| diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 42f5350b908f..6360abf993d4 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -138,9 +138,9 @@ int amd_iommus_present;  bool amd_iommu_np_cache __read_mostly;  /* - * Set to true if ACPI table parsing and hardware intialization went properly + * The ACPI table parsing functions set this variable on an error   */ -static bool amd_iommu_initialized; +static int __initdata amd_iommu_init_err;  /*   * List of protection domains - used during resume @@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)  	 */  	for (i = 0; i < table->length; ++i)  		checksum += p[i]; -	if (checksum != 0) +	if (checksum != 0) {  		/* ACPI table corrupt */ -		return -ENODEV; +		amd_iommu_init_err = -ENODEV; +		return 0; +	}  	p += IVRS_HEADER_LENGTH; @@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)  	if (cmd_buf == NULL)  		return NULL; -	iommu->cmd_buf_size = CMD_BUFFER_SIZE; +	iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;  	return cmd_buf;  } @@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)  		    &entry, sizeof(entry));  	amd_iommu_reset_cmd_buffer(iommu); +	iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);  }  static void __init free_command_buffer(struct amd_iommu *iommu)  {  	free_pages((unsigned long)iommu->cmd_buf, -		   get_order(iommu->cmd_buf_size)); +		   get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));  }  /* allocates the memory where the IOMMU will log its events to */ @@ -920,11 +923,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)  				    h->mmio_phys);  			iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); -			if (iommu == NULL) -				return -ENOMEM; +			if (iommu == NULL) { +				amd_iommu_init_err = -ENOMEM; +				return 0; +			} +  			ret = init_iommu_one(iommu, h); -			if (ret) -				return ret; +			if (ret) { +				amd_iommu_init_err = ret; +				return 0; +			}  			break;  		default:  			break; @@ -934,8 +942,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)  	}  	WARN_ON(p != end); -	amd_iommu_initialized = true; -  	return 0;  } @@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void)  	if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)  		return -ENODEV; +	ret = amd_iommu_init_err; +	if (ret) +		goto out; +  	dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);  	alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);  	rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); @@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void)  	if (acpi_table_parse("IVRS", init_iommu_all) != 0)  		goto free; -	if (!amd_iommu_initialized) +	if (amd_iommu_init_err) { +		ret = amd_iommu_init_err;  		goto free; +	}  	if (acpi_table_parse("IVRS", init_memory_definitions) != 0)  		goto free; +	if (amd_iommu_init_err) { +		ret = amd_iommu_init_err; +		goto free; +	} +  	ret = sysdev_class_register(&amd_iommu_sysdev_class);  	if (ret)  		goto free; @@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void)  	if (ret)  		goto free; +	enable_iommus(); +  	if (iommu_pass_through)  		ret = amd_iommu_init_passthrough();  	else @@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void)  	amd_iommu_init_notifier(); -	enable_iommus(); -  	if (iommu_pass_through)  		goto out; @@ -1315,6 +1332,7 @@ out:  	return ret;  free: +	disable_iommus();  	amd_iommu_uninit_devices(); | 
