Mailing List Archive

[PATCH 4/4] ACPI: eliminate duplicate IVRS definitions
Use their proper counterparts in include/acpi/actbl*.h instead.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -20,10 +20,38 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <asm/apicdef.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
+
+/* Some helper structures, particularly to deal with ranges. */
+
+struct acpi_ivhd_device_range {
+ struct acpi_ivrs_device4 start;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_alias_range {
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_extended_range {
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivrs_device4 end;
+};
+
+union acpi_ivhd_device {
+ struct acpi_ivrs_de_header header;
+ struct acpi_ivrs_device4 select;
+ struct acpi_ivhd_device_range range;
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivhd_device_alias_range alias_range;
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivhd_device_extended_range extended_range;
+ struct acpi_ivrs_device8c special;
+};

static unsigned short __initdata last_bdf;

@@ -242,12 +270,12 @@ static int __init register_exclusion_ran
}

static int __init parse_ivmd_device_select(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 bdf;

- bdf = ivmd_block->header.dev_id;
+ bdf = ivmd_block->header.device_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Dev_Id 0x%x\n", bdf);
@@ -258,13 +286,13 @@ static int __init parse_ivmd_device_sele
}

static int __init parse_ivmd_device_range(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 first_bdf, last_bdf, bdf;
int error;

- first_bdf = ivmd_block->header.dev_id;
+ first_bdf = ivmd_block->header.device_id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: "
@@ -272,7 +300,7 @@ static int __init parse_ivmd_device_rang
return -ENODEV;
}

- last_bdf = ivmd_block->last_dev_id;
+ last_bdf = ivmd_block->aux_data;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVMD Error: "
@@ -288,18 +316,18 @@ static int __init parse_ivmd_device_rang
}

static int __init parse_ivmd_device_iommu(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
struct amd_iommu *iommu;

/* find target IOMMU */
- iommu = find_iommu_from_bdf_cap(ivmd_block->header.dev_id,
- ivmd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivmd_block->header.device_id,
+ ivmd_block->aux_data);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVMD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivmd_block->header.dev_id, ivmd_block->cap_offset);
+ ivmd_block->header.device_id, ivmd_block->aux_data);
return -ENODEV;
}

@@ -307,20 +335,19 @@ static int __init parse_ivmd_device_iomm
iommu, base, limit, iw, ir);
}

-static int __init parse_ivmd_block(struct acpi_ivmd_block_header *ivmd_block)
+static int __init parse_ivmd_block(const struct acpi_ivrs_memory *ivmd_block)
{
unsigned long start_addr, mem_length, base, limit;
u8 iw, ir;

- if ( ivmd_block->header.length <
- sizeof(struct acpi_ivmd_block_header) )
+ if ( ivmd_block->header.length < sizeof(*ivmd_block) )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Block Length!\n");
return -ENODEV;
}

- start_addr = (unsigned long)ivmd_block->start_addr;
- mem_length = (unsigned long)ivmd_block->mem_length;
+ start_addr = (unsigned long)ivmd_block->start_address;
+ mem_length = (unsigned long)ivmd_block->memory_length;
base = start_addr & PAGE_MASK;
limit = (start_addr + mem_length - 1) & PAGE_MASK;

@@ -328,20 +355,14 @@ static int __init parse_ivmd_block(struc
AMD_IOMMU_DEBUG(" Start_Addr_Phys 0x%lx\n", start_addr);
AMD_IOMMU_DEBUG(" Mem_Length 0x%lx\n", mem_length);

- if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_MASK,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_SHIFT) )
+ if ( ivmd_block->header.flags & ACPI_IVMD_EXCLUSION_RANGE )
iw = ir = IOMMU_CONTROL_ENABLED;
- else if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_UNITY_MAPPING_MASK,
- AMD_IOMMU_ACPI_UNITY_MAPPING_SHIFT) )
- {
- iw = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IW_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IW_PERMISSION_SHIFT);
- ir = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IR_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IR_PERMISSION_SHIFT);
+ else if ( ivmd_block->header.flags & ACPI_IVMD_UNITY )
+ {
+ iw = ivmd_block->header.flags & ACPI_IVMD_READ ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
+ ir = ivmd_block->header.flags & ACPI_IVMD_WRITE ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
}
else
{
@@ -351,19 +372,19 @@ static int __init parse_ivmd_block(struc

switch( ivmd_block->header.type )
{
- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
return register_exclusion_range_for_all_devices(
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
return parse_ivmd_device_select(ivmd_block,
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
return parse_ivmd_device_range(ivmd_block,
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
return parse_ivmd_device_iommu(ivmd_block,
base, limit, iw, ir);

@@ -386,45 +407,44 @@ static u16 __init parse_ivhd_device_padd
}

static u16 __init parse_ivhd_device_select(
- union acpi_ivhd_device *ivhd_device, struct amd_iommu *iommu)
+ const struct acpi_ivrs_device4 *select, struct amd_iommu *iommu)
{
u16 bdf;

- bdf = ivhd_device->header.dev_id;
+ bdf = select->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, select->header.data_setting, iommu);

- return sizeof(struct acpi_ivhd_device_header);
+ return sizeof(*select);
}

static u16 __init parse_ivhd_device_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->start.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -432,7 +452,7 @@ static u16 __init parse_ivhd_device_rang
return 0;
}

- last_bdf = ivhd_device->range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -443,32 +463,33 @@ static u16 __init parse_ivhd_device_rang
AMD_IOMMU_DEBUG(" Dev_Id Range: 0x%x -> 0x%x\n", first_bdf, last_bdf);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->start.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_alias(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8a *alias,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, alias_id, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_alias);
+ dev_length = sizeof(*alias);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->header.dev_id;
+ bdf = alias->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- alias_id = ivhd_device->alias.dev_id;
+ alias_id = alias->used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
@@ -477,35 +498,34 @@ static u16 __init parse_ivhd_device_alia

AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);

- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, alias->header.data_setting, iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_alias_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_alias_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{

u16 dev_length, first_bdf, last_bdf, alias_id, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->alias_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->alias_range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->alias.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -513,7 +533,7 @@ static u16 __init parse_ivhd_device_alia
return 0;
}

- last_bdf = ivhd_device->alias_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( last_bdf >= ivrs_bdf_entries || last_bdf <= first_bdf )
{
AMD_IOMMU_DEBUG(
@@ -521,7 +541,7 @@ static u16 __init parse_ivhd_device_alia
return 0;
}

- alias_id = ivhd_device->alias_range.alias.dev_id;
+ alias_id = range->alias.used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
@@ -532,59 +552,59 @@ static u16 __init parse_ivhd_device_alia
AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, range->alias.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_extended(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8b *ext,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_extended);
+ dev_length = sizeof(*ext);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->header.dev_id;
+ bdf = ext->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, ext->header.data_setting, iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_extended_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_extended_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->extended_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->extended_range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->extended.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -592,7 +612,7 @@ static u16 __init parse_ivhd_device_exte
return 0;
}

- last_bdf = ivhd_device->extended_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -604,116 +624,116 @@ static u16 __init parse_ivhd_device_exte
first_bdf, last_bdf);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->extended.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_special(
- union acpi_ivhd_device *ivhd_device, u16 seg,
+ const struct acpi_ivrs_device8c *special, u16 seg,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_special);
+ dev_length = sizeof(*special);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->special.dev_id;
+ bdf = special->used_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
/* set device id of ioapic */
- ioapic_sbdf[ivhd_device->special.handle].bdf = bdf;
- ioapic_sbdf[ivhd_device->special.handle].seg = seg;
+ ioapic_sbdf[special->handle].bdf = bdf;
+ ioapic_sbdf[special->handle].seg = seg;
return dev_length;
}

-static int __init parse_ivhd_block(struct acpi_ivhd_block_header *ivhd_block)
+static int __init parse_ivhd_block(const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
struct amd_iommu *iommu;

- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}

- iommu = find_iommu_from_bdf_cap(ivhd_block->header.dev_id,
- ivhd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVHD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivhd_block->header.dev_id, ivhd_block->cap_offset);
+ ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
return -ENODEV;
}

/* parse Device Entries */
- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((const u8 *)ivhd_block + block_length);

AMD_IOMMU_DEBUG( "IVHD Device Entry:\n");
AMD_IOMMU_DEBUG( " Type 0x%x\n", ivhd_device->header.type);
- AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.dev_id);
- AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.flags);
+ AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.id);
+ AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.data_setting);

switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = parse_ivhd_device_padding(
sizeof(u32),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = parse_ivhd_device_padding(
sizeof(u64),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- dev_length = parse_ivhd_device_select(ivhd_device, iommu);
+ case ACPI_IVRS_TYPE_SELECT:
+ dev_length = parse_ivhd_device_select(&ivhd_device->select, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
+ case ACPI_IVRS_TYPE_START:
dev_length = parse_ivhd_device_range(
- ivhd_device,
+ &ivhd_device->range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
dev_length = parse_ivhd_device_alias(
- ivhd_device,
+ &ivhd_device->alias,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
+ case ACPI_IVRS_TYPE_ALIAS_START:
dev_length = parse_ivhd_device_alias_range(
- ivhd_device,
+ &ivhd_device->alias_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
+ case ACPI_IVRS_TYPE_EXT_SELECT:
dev_length = parse_ivhd_device_extended(
- ivhd_device,
+ &ivhd_device->extended,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
+ case ACPI_IVRS_TYPE_EXT_START:
dev_length = parse_ivhd_device_extended_range(
- ivhd_device,
+ &ivhd_device->extended_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
+ case ACPI_IVRS_TYPE_SPECIAL:
dev_length = parse_ivhd_device_special(
- ivhd_device, ivhd_block->pci_segment,
+ &ivhd_device->special, ivhd_block->pci_segment_group,
ivhd_block->header.length, block_length, iommu);
break;
default:
@@ -730,22 +750,24 @@ static int __init parse_ivhd_block(struc
return 0;
}

-static int __init parse_ivrs_block(struct acpi_ivrs_block_header *ivrs_block)
+static int __init parse_ivrs_block(const struct acpi_ivrs_header *ivrs_block)
{
- struct acpi_ivhd_block_header *ivhd_block;
- struct acpi_ivmd_block_header *ivmd_block;
+ const struct acpi_ivrs_hardware *ivhd_block;
+ const struct acpi_ivrs_memory *ivmd_block;

switch ( ivrs_block->type )
{
- case AMD_IOMMU_ACPI_IVHD_TYPE:
- ivhd_block = (struct acpi_ivhd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_HARDWARE:
+ ivhd_block = container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header);
return parse_ivhd_block(ivhd_block);

- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
- ivmd_block = (struct acpi_ivmd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
+ ivmd_block = container_of(ivrs_block, const struct acpi_ivrs_memory,
+ header);
return parse_ivmd_block(ivmd_block);

default:
@@ -792,12 +814,11 @@ static void __init dump_acpi_table_heade

}

-static int __init parse_ivrs_table(struct acpi_table_header *_table)
+static int __init parse_ivrs_table(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long length;
int error = 0;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;

BUG_ON(!table);

@@ -805,17 +826,16 @@ static int __init parse_ivrs_table(struc
dump_acpi_table_header(table);

/* parse IVRS blocks */
- length = sizeof(struct acpi_ivrs_table_header);
+ length = sizeof(struct acpi_table_ivrs);
while ( (error == 0) && (table->length > (length + sizeof(*ivrs_block))) )
{
- ivrs_block = (struct acpi_ivrs_block_header *)
- ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);

AMD_IOMMU_DEBUG("IVRS Block:\n");
AMD_IOMMU_DEBUG(" Type 0x%x\n", ivrs_block->type);
AMD_IOMMU_DEBUG(" Flags 0x%x\n", ivrs_block->flags);
AMD_IOMMU_DEBUG(" Length 0x%x\n", ivrs_block->length);
- AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->dev_id);
+ AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->device_id);

if ( table->length < (length + ivrs_block->length) )
{
@@ -833,12 +853,11 @@ static int __init parse_ivrs_table(struc
return error;
}

-static int __init detect_iommu_acpi(struct acpi_table_header *_table)
+static int __init detect_iommu_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long i;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ unsigned long length = sizeof(struct acpi_table_ivrs);
u8 checksum, *raw_table;

/* validate checksum: sum of entire table == 0 */
@@ -854,12 +873,14 @@ static int __init detect_iommu_acpi(stru

while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( amd_iommu_detect_one_acpi((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ amd_iommu_detect_one_acpi(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
@@ -870,63 +891,59 @@ static int __init detect_iommu_acpi(stru
last_bdf = (x); \
} while(0);

-static int __init get_last_bdf_ivhd(void *ivhd)
+static int __init get_last_bdf_ivhd(
+ const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
- struct acpi_ivhd_block_header *ivhd_block;
-
- ivhd_block = (struct acpi_ivhd_block_header *)ivhd;

- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}

- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((u8 *)ivhd_block + block_length);

switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = sizeof(u32);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = sizeof(u64);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_header);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_alias);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_extended);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
- UPDATE_LAST_BDF(ivhd_device->range.trailer.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
- UPDATE_LAST_BDF(ivhd_device->alias_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
- UPDATE_LAST_BDF(ivhd_device->extended_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
- UPDATE_LAST_BDF(ivhd_device->special.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_special);
+ case ACPI_IVRS_TYPE_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->select.header.id);
+ dev_length = sizeof(ivhd_device->header);
+ break;
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->alias.header.id);
+ dev_length = sizeof(ivhd_device->alias);
+ break;
+ case ACPI_IVRS_TYPE_EXT_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->extended.header.id);
+ dev_length = sizeof(ivhd_device->extended);
+ break;
+ case ACPI_IVRS_TYPE_START:
+ UPDATE_LAST_BDF(ivhd_device->range.end.header.id);
+ dev_length = sizeof(ivhd_device->range);
+ break;
+ case ACPI_IVRS_TYPE_ALIAS_START:
+ UPDATE_LAST_BDF(ivhd_device->alias_range.end.header.id)
+ dev_length = sizeof(ivhd_device->alias_range);
+ break;
+ case ACPI_IVRS_TYPE_EXT_START:
+ UPDATE_LAST_BDF(ivhd_device->extended_range.end.header.id)
+ dev_length = sizeof(ivhd_device->extended_range);
+ break;
+ case ACPI_IVRS_TYPE_SPECIAL:
+ UPDATE_LAST_BDF(ivhd_device->special.used_id)
+ dev_length = sizeof(ivhd_device->special);
break;
default:
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device Type!\n");
@@ -942,20 +959,21 @@ static int __init get_last_bdf_ivhd(void
return 0;
}

-static int __init get_last_bdf_acpi(struct acpi_table_header *_table)
+static int __init get_last_bdf_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ const struct acpi_ivrs_header *ivrs_block;
+ unsigned long length = sizeof(struct acpi_table_ivrs);

while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( get_last_bdf_ivhd((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ get_last_bdf_ivhd(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
@@ -963,16 +981,16 @@ static int __init get_last_bdf_acpi(stru

int __init amd_iommu_detect_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, detect_iommu_acpi);
+ return acpi_table_parse(ACPI_SIG_IVRS, detect_iommu_acpi);
}

int __init amd_iommu_get_ivrs_dev_entries(void)
{
- acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, get_last_bdf_acpi);
+ acpi_table_parse(ACPI_SIG_IVRS, get_last_bdf_acpi);
return last_bdf + 1;
}

int __init amd_iommu_update_ivrs_mapping_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table);
+ return acpi_table_parse(ACPI_SIG_IVRS, parse_ivrs_table);
}
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -20,12 +20,12 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <xen/iommu.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>

static int __init get_iommu_msi_capabilities(
u16 seg, u8 bus, u8 dev, u8 func, struct amd_iommu *iommu)
@@ -103,23 +103,21 @@ void __init get_iommu_features(struct am
}
}

-int __init amd_iommu_detect_one_acpi(void *ivhd)
+int __init amd_iommu_detect_one_acpi(
+ const struct acpi_ivrs_hardware *ivhd_block)
{
struct amd_iommu *iommu;
u8 bus, dev, func;
- struct acpi_ivhd_block_header *ivhd_block;
int rt = 0;

- ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
-
- if ( ivhd_block->header.length < sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("Invalid IVHD Block Length!\n");
return -ENODEV;
}

- if ( !ivhd_block->header.dev_id ||
- !ivhd_block->cap_offset || !ivhd_block->mmio_base)
+ if ( !ivhd_block->header.device_id ||
+ !ivhd_block->capability_offset || !ivhd_block->base_address)
{
AMD_IOMMU_DEBUG("Invalid IVHD Block!\n");
return -ENODEV;
@@ -134,10 +132,10 @@ int __init amd_iommu_detect_one_acpi(voi

spin_lock_init(&iommu->lock);

- iommu->seg = ivhd_block->pci_segment;
- iommu->bdf = ivhd_block->header.dev_id;
- iommu->cap_offset = ivhd_block->cap_offset;
- iommu->mmio_base_phys = ivhd_block->mmio_base;
+ iommu->seg = ivhd_block->pci_segment_group;
+ iommu->bdf = ivhd_block->header.device_id;
+ iommu->cap_offset = ivhd_block->capability_offset;
+ iommu->mmio_base_phys = ivhd_block->base_address;

/* override IOMMU HT flags */
iommu->ht_flags = ivhd_block->header.flags;
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -20,6 +20,7 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
#include <xen/irq.h>
@@ -28,7 +29,6 @@
#include <asm/hvm/svm/amd-iommu-proto.h>
#include <asm-x86/fixmap.h>
#include <mach_apic.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>

static int __initdata nr_amd_iommus;

@@ -37,9 +37,8 @@ static struct radix_tree_root ivrs_maps;
struct list_head amd_iommu_head;
struct table_struct device_table;

-static int iommu_has_ht_flag(struct amd_iommu *iommu, uint8_t bit)
+static int iommu_has_ht_flag(struct amd_iommu *iommu, u8 mask)
{
- u8 mask = 1U << bit;
return iommu->ht_flags & mask;
}

@@ -80,19 +79,19 @@ static void set_iommu_ht_flags(struct am

/* Setup HT flags */
if ( iommu_has_cap(iommu, PCI_CAP_HT_TUNNEL_SHIFT) )
- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_TT_ENABLE) ?
iommu_set_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT) :
iommu_clear_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_RES_PASS_PW) ?
iommu_set_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_ISOC_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_ISOC) ?
iommu_set_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_PASS_PW_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_PASS_PW) ?
iommu_set_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT);

--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -18,12 +18,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

+#include <xen/config.h>
+#include <xen/acpi.h>
#include <xen/sched.h>
#include <asm/p2m.h>
#include <xen/hvm/iommu.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
#include "../ats.h"
#include <xen/pci.h>

@@ -215,8 +216,7 @@ void __init iommu_dte_add_device_entry(u
dte[7] = dte[6] = dte[4] = dte[2] = dte[1] = dte[0] = 0;

flags = ivrs_dev->device_flags;
- sys_mgt = get_field_from_byte(flags, AMD_IOMMU_ACPI_SYS_MGT_MASK,
- AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
+ sys_mgt = get_field_from_byte(flags, ACPI_IVHD_SYSTEM_MGMT);
dev_ex = ivrs_dev->dte_allow_exclusion;

flags &= mask;
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-acpi.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- * Author: Leo Duran <leo.duran@amd.com>
- * Author: Wei Wang <wei.wang2@amd.com> - adapted to xen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _ASM_X86_64_AMD_IOMMU_ACPI_H
-#define _ASM_X86_64_AMD_IOMMU_ACPI_H
-
-#include <xen/acpi.h>
-
-/* I/O Virtualization Reporting Structure */
-#define AMD_IOMMU_ACPI_IVRS_SIG "IVRS"
-#define AMD_IOMMU_ACPI_IVHD_TYPE 0x10
-#define AMD_IOMMU_ACPI_IVMD_ALL_TYPE 0x20
-#define AMD_IOMMU_ACPI_IVMD_ONE_TYPE 0x21
-#define AMD_IOMMU_ACPI_IVMD_RANGE_TYPE 0x22
-#define AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE 0x23
-
-/* 4-byte Device Entries */
-#define AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD 0
-#define AMD_IOMMU_ACPI_IVHD_DEV_SELECT 2
-#define AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START 3
-#define AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END 4
-
-/* 8-byte Device Entries */
-#define AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD 64
-#define AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT 66
-#define AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE 67
-#define AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT 70
-#define AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE 71
-#define AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL 72
-
-/* IVHD IOMMU Flags */
-#define AMD_IOMMU_ACPI_COHERENT_MASK 0x20
-#define AMD_IOMMU_ACPI_COHERENT_SHIFT 5
-#define AMD_IOMMU_ACPI_IOTLB_SUP_MASK 0x10
-#define AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT 4
-#define AMD_IOMMU_ACPI_ISOC_MASK 0x08
-#define AMD_IOMMU_ACPI_ISOC_SHIFT 3
-#define AMD_IOMMU_ACPI_RES_PASS_PW_MASK 0x04
-#define AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT 2
-#define AMD_IOMMU_ACPI_PASS_PW_MASK 0x02
-#define AMD_IOMMU_ACPI_PASS_PW_SHIFT 1
-#define AMD_IOMMU_ACPI_HT_TUN_ENB_MASK 0x01
-#define AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT 0
-
-/* IVHD Device Flags */
-#define AMD_IOMMU_ACPI_LINT1_PASS_MASK 0x80
-#define AMD_IOMMU_ACPI_LINT1_PASS_SHIFT 7
-#define AMD_IOMMU_ACPI_LINT0_PASS_MASK 0x40
-#define AMD_IOMMU_ACPI_LINT0_PASS_SHIFT 6
-#define AMD_IOMMU_ACPI_SYS_MGT_MASK 0x30
-#define AMD_IOMMU_ACPI_SYS_MGT_SHIFT 4
-#define AMD_IOMMU_ACPI_NMI_PASS_MASK 0x04
-#define AMD_IOMMU_ACPI_NMI_PASS_SHIFT 2
-#define AMD_IOMMU_ACPI_EINT_PASS_MASK 0x02
-#define AMD_IOMMU_ACPI_EINT_PASS_SHIFT 1
-#define AMD_IOMMU_ACPI_INIT_PASS_MASK 0x01
-#define AMD_IOMMU_ACPI_INIT_PASS_SHIFT 0
-
-/* IVHD Device Extended Flags */
-#define AMD_IOMMU_ACPI_ATS_DISABLED_MASK 0x80000000
-#define AMD_IOMMU_ACPI_ATS_DISABLED_SHIFT 31
-
-/* IVMD Device Flags */
-#define AMD_IOMMU_ACPI_EXCLUSION_RANGE_MASK 0x08
-#define AMD_IOMMU_ACPI_EXCLUSION_RANGE_SHIFT 3
-#define AMD_IOMMU_ACPI_IW_PERMISSION_MASK 0x04
-#define AMD_IOMMU_ACPI_IW_PERMISSION_SHIFT 2
-#define AMD_IOMMU_ACPI_IR_PERMISSION_MASK 0x02
-#define AMD_IOMMU_ACPI_IR_PERMISSION_SHIFT 1
-#define AMD_IOMMU_ACPI_UNITY_MAPPING_MASK 0x01
-#define AMD_IOMMU_ACPI_UNITY_MAPPING_SHIFT 0
-
-#define ACPI_OEM_ID_SIZE 6
-#define ACPI_OEM_TABLE_ID_SIZE 8
-
-#pragma pack(1)
-struct acpi_ivrs_table_header {
- struct acpi_table_header acpi_header;
- u32 io_info;
- u8 reserved[8];
-};
-
-struct acpi_ivrs_block_header {
- u8 type;
- u8 flags;
- u16 length;
- u16 dev_id;
-};
-
-struct acpi_ivhd_block_header {
- struct acpi_ivrs_block_header header;
- u16 cap_offset;
- u64 mmio_base;
- u16 pci_segment;
- u16 iommu_info;
- u8 reserved[4];
-};
-
-struct acpi_ivhd_device_header {
- u8 type;
- u16 dev_id;
- u8 flags;
-};
-
-struct acpi_ivhd_device_trailer {
- u8 type;
- u16 dev_id;
- u8 reserved;
-};
-
-struct acpi_ivhd_device_range {
- struct acpi_ivhd_device_header header;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_alias {
- struct acpi_ivhd_device_header header;
- u8 reserved1;
- u16 dev_id;
- u8 reserved2;
-};
-
-struct acpi_ivhd_device_alias_range {
- struct acpi_ivhd_device_alias alias;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_extended {
- struct acpi_ivhd_device_header header;
- u32 ext_flags;
-};
-
-struct acpi_ivhd_device_extended_range {
- struct acpi_ivhd_device_extended extended;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_special {
- struct acpi_ivhd_device_header header;
- u8 handle;
- u16 dev_id;
- u8 variety;
-};
-
-union acpi_ivhd_device {
- struct acpi_ivhd_device_header header;
- struct acpi_ivhd_device_range range;
- struct acpi_ivhd_device_alias alias;
- struct acpi_ivhd_device_alias_range alias_range;
- struct acpi_ivhd_device_extended extended;
- struct acpi_ivhd_device_extended_range extended_range;
- struct acpi_ivhd_device_special special;
-};
-
-struct acpi_ivmd_block_header {
- struct acpi_ivrs_block_header header;
- union {
- u16 last_dev_id;
- u16 cap_offset;
- u16 reserved1;
- };
- u64 reserved2;
- u64 start_addr;
- u64 mem_length;
-};
-#pragma pack()
-
-#endif /* _ASM_X86_64_AMD_IOMMU_ACPI_H */
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -26,6 +26,8 @@
#include <asm/apicdef.h>
#include <xen/domain_page.h>

+struct acpi_ivrs_hardware;
+
#define for_each_amd_iommu(amd_iommu) \
list_for_each_entry(amd_iommu, \
&amd_iommu_head, list)
@@ -41,7 +43,7 @@

/* amd-iommu-detect functions */
int amd_iommu_get_ivrs_dev_entries(void);
-int amd_iommu_detect_one_acpi(void *ivhd);
+int amd_iommu_detect_one_acpi(const struct acpi_ivrs_hardware *);
int amd_iommu_detect_acpi(void);
void get_iommu_features(struct amd_iommu *iommu);

@@ -121,11 +123,9 @@ static inline u32 set_field_in_reg_u32(u
return reg_value;
}

-static inline u8 get_field_from_byte(u8 value, u8 mask, u8 shift)
+static inline u8 get_field_from_byte(u8 value, u8 mask)
{
- u8 field;
- field = (value & mask) >> shift;
- return field;
+ return (value & mask) / (mask & -mask);
}

static inline unsigned long region_to_pages(unsigned long addr, unsigned long size)
[PATCH 4/4] ACPI: eliminate duplicate IVRS definitions [ In reply to ]
Use their proper counterparts in include/acpi/actbl*.h instead.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -20,10 +20,38 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <asm/apicdef.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
+
+/* Some helper structures, particularly to deal with ranges. */
+
+struct acpi_ivhd_device_range {
+ struct acpi_ivrs_device4 start;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_alias_range {
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_extended_range {
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivrs_device4 end;
+};
+
+union acpi_ivhd_device {
+ struct acpi_ivrs_de_header header;
+ struct acpi_ivrs_device4 select;
+ struct acpi_ivhd_device_range range;
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivhd_device_alias_range alias_range;
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivhd_device_extended_range extended_range;
+ struct acpi_ivrs_device8c special;
+};

static unsigned short __initdata last_bdf;

@@ -242,12 +270,12 @@ static int __init register_exclusion_ran
}

static int __init parse_ivmd_device_select(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 bdf;

- bdf = ivmd_block->header.dev_id;
+ bdf = ivmd_block->header.device_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Dev_Id 0x%x\n", bdf);
@@ -258,13 +286,13 @@ static int __init parse_ivmd_device_sele
}

static int __init parse_ivmd_device_range(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 first_bdf, last_bdf, bdf;
int error;

- first_bdf = ivmd_block->header.dev_id;
+ first_bdf = ivmd_block->header.device_id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: "
@@ -272,7 +300,7 @@ static int __init parse_ivmd_device_rang
return -ENODEV;
}

- last_bdf = ivmd_block->last_dev_id;
+ last_bdf = ivmd_block->aux_data;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVMD Error: "
@@ -288,18 +316,18 @@ static int __init parse_ivmd_device_rang
}

static int __init parse_ivmd_device_iommu(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
struct amd_iommu *iommu;

/* find target IOMMU */
- iommu = find_iommu_from_bdf_cap(ivmd_block->header.dev_id,
- ivmd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivmd_block->header.device_id,
+ ivmd_block->aux_data);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVMD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivmd_block->header.dev_id, ivmd_block->cap_offset);
+ ivmd_block->header.device_id, ivmd_block->aux_data);
return -ENODEV;
}

@@ -307,20 +335,19 @@ static int __init parse_ivmd_device_iomm
iommu, base, limit, iw, ir);
}

-static int __init parse_ivmd_block(struct acpi_ivmd_block_header *ivmd_block)
+static int __init parse_ivmd_block(const struct acpi_ivrs_memory *ivmd_block)
{
unsigned long start_addr, mem_length, base, limit;
u8 iw, ir;

- if ( ivmd_block->header.length <
- sizeof(struct acpi_ivmd_block_header) )
+ if ( ivmd_block->header.length < sizeof(*ivmd_block) )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Block Length!\n");
return -ENODEV;
}

- start_addr = (unsigned long)ivmd_block->start_addr;
- mem_length = (unsigned long)ivmd_block->mem_length;
+ start_addr = (unsigned long)ivmd_block->start_address;
+ mem_length = (unsigned long)ivmd_block->memory_length;
base = start_addr & PAGE_MASK;
limit = (start_addr + mem_length - 1) & PAGE_MASK;

@@ -328,20 +355,14 @@ static int __init parse_ivmd_block(struc
AMD_IOMMU_DEBUG(" Start_Addr_Phys 0x%lx\n", start_addr);
AMD_IOMMU_DEBUG(" Mem_Length 0x%lx\n", mem_length);

- if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_MASK,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_SHIFT) )
+ if ( ivmd_block->header.flags & ACPI_IVMD_EXCLUSION_RANGE )
iw = ir = IOMMU_CONTROL_ENABLED;
- else if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_UNITY_MAPPING_MASK,
- AMD_IOMMU_ACPI_UNITY_MAPPING_SHIFT) )
- {
- iw = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IW_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IW_PERMISSION_SHIFT);
- ir = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IR_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IR_PERMISSION_SHIFT);
+ else if ( ivmd_block->header.flags & ACPI_IVMD_UNITY )
+ {
+ iw = ivmd_block->header.flags & ACPI_IVMD_READ ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
+ ir = ivmd_block->header.flags & ACPI_IVMD_WRITE ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
}
else
{
@@ -351,19 +372,19 @@ static int __init parse_ivmd_block(struc

switch( ivmd_block->header.type )
{
- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
return register_exclusion_range_for_all_devices(
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
return parse_ivmd_device_select(ivmd_block,
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
return parse_ivmd_device_range(ivmd_block,
base, limit, iw, ir);

- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
return parse_ivmd_device_iommu(ivmd_block,
base, limit, iw, ir);

@@ -386,45 +407,44 @@ static u16 __init parse_ivhd_device_padd
}

static u16 __init parse_ivhd_device_select(
- union acpi_ivhd_device *ivhd_device, struct amd_iommu *iommu)
+ const struct acpi_ivrs_device4 *select, struct amd_iommu *iommu)
{
u16 bdf;

- bdf = ivhd_device->header.dev_id;
+ bdf = select->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, select->header.data_setting, iommu);

- return sizeof(struct acpi_ivhd_device_header);
+ return sizeof(*select);
}

static u16 __init parse_ivhd_device_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->start.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -432,7 +452,7 @@ static u16 __init parse_ivhd_device_rang
return 0;
}

- last_bdf = ivhd_device->range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -443,32 +463,33 @@ static u16 __init parse_ivhd_device_rang
AMD_IOMMU_DEBUG(" Dev_Id Range: 0x%x -> 0x%x\n", first_bdf, last_bdf);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->start.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_alias(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8a *alias,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, alias_id, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_alias);
+ dev_length = sizeof(*alias);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->header.dev_id;
+ bdf = alias->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- alias_id = ivhd_device->alias.dev_id;
+ alias_id = alias->used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
@@ -477,35 +498,34 @@ static u16 __init parse_ivhd_device_alia

AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);

- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, alias->header.data_setting, iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_alias_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_alias_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{

u16 dev_length, first_bdf, last_bdf, alias_id, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->alias_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->alias_range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->alias.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -513,7 +533,7 @@ static u16 __init parse_ivhd_device_alia
return 0;
}

- last_bdf = ivhd_device->alias_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( last_bdf >= ivrs_bdf_entries || last_bdf <= first_bdf )
{
AMD_IOMMU_DEBUG(
@@ -521,7 +541,7 @@ static u16 __init parse_ivhd_device_alia
return 0;
}

- alias_id = ivhd_device->alias_range.alias.dev_id;
+ alias_id = range->alias.used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
@@ -532,59 +552,59 @@ static u16 __init parse_ivhd_device_alia
AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, range->alias.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_extended(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8b *ext,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_extended);
+ dev_length = sizeof(*ext);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->header.dev_id;
+ bdf = ext->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, ext->header.data_setting, iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_extended_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_extended_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- if ( ivhd_device->extended_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->extended_range.trailer.type);
+ range->end.header.type);
return 0;
}

- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->extended.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -592,7 +612,7 @@ static u16 __init parse_ivhd_device_exte
return 0;
}

- last_bdf = ivhd_device->extended_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
@@ -604,116 +624,116 @@ static u16 __init parse_ivhd_device_exte
first_bdf, last_bdf);

for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->extended.header.data_setting,
+ iommu);

return dev_length;
}

static u16 __init parse_ivhd_device_special(
- union acpi_ivhd_device *ivhd_device, u16 seg,
+ const struct acpi_ivrs_device8c *special, u16 seg,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;

- dev_length = sizeof(struct acpi_ivhd_device_special);
+ dev_length = sizeof(*special);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}

- bdf = ivhd_device->special.dev_id;
+ bdf = special->used_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}

- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
/* set device id of ioapic */
- ioapic_sbdf[ivhd_device->special.handle].bdf = bdf;
- ioapic_sbdf[ivhd_device->special.handle].seg = seg;
+ ioapic_sbdf[special->handle].bdf = bdf;
+ ioapic_sbdf[special->handle].seg = seg;
return dev_length;
}

-static int __init parse_ivhd_block(struct acpi_ivhd_block_header *ivhd_block)
+static int __init parse_ivhd_block(const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
struct amd_iommu *iommu;

- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}

- iommu = find_iommu_from_bdf_cap(ivhd_block->header.dev_id,
- ivhd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVHD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivhd_block->header.dev_id, ivhd_block->cap_offset);
+ ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
return -ENODEV;
}

/* parse Device Entries */
- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((const u8 *)ivhd_block + block_length);

AMD_IOMMU_DEBUG( "IVHD Device Entry:\n");
AMD_IOMMU_DEBUG( " Type 0x%x\n", ivhd_device->header.type);
- AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.dev_id);
- AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.flags);
+ AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.id);
+ AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.data_setting);

switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = parse_ivhd_device_padding(
sizeof(u32),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = parse_ivhd_device_padding(
sizeof(u64),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- dev_length = parse_ivhd_device_select(ivhd_device, iommu);
+ case ACPI_IVRS_TYPE_SELECT:
+ dev_length = parse_ivhd_device_select(&ivhd_device->select, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
+ case ACPI_IVRS_TYPE_START:
dev_length = parse_ivhd_device_range(
- ivhd_device,
+ &ivhd_device->range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
dev_length = parse_ivhd_device_alias(
- ivhd_device,
+ &ivhd_device->alias,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
+ case ACPI_IVRS_TYPE_ALIAS_START:
dev_length = parse_ivhd_device_alias_range(
- ivhd_device,
+ &ivhd_device->alias_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
+ case ACPI_IVRS_TYPE_EXT_SELECT:
dev_length = parse_ivhd_device_extended(
- ivhd_device,
+ &ivhd_device->extended,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
+ case ACPI_IVRS_TYPE_EXT_START:
dev_length = parse_ivhd_device_extended_range(
- ivhd_device,
+ &ivhd_device->extended_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
+ case ACPI_IVRS_TYPE_SPECIAL:
dev_length = parse_ivhd_device_special(
- ivhd_device, ivhd_block->pci_segment,
+ &ivhd_device->special, ivhd_block->pci_segment_group,
ivhd_block->header.length, block_length, iommu);
break;
default:
@@ -730,22 +750,24 @@ static int __init parse_ivhd_block(struc
return 0;
}

-static int __init parse_ivrs_block(struct acpi_ivrs_block_header *ivrs_block)
+static int __init parse_ivrs_block(const struct acpi_ivrs_header *ivrs_block)
{
- struct acpi_ivhd_block_header *ivhd_block;
- struct acpi_ivmd_block_header *ivmd_block;
+ const struct acpi_ivrs_hardware *ivhd_block;
+ const struct acpi_ivrs_memory *ivmd_block;

switch ( ivrs_block->type )
{
- case AMD_IOMMU_ACPI_IVHD_TYPE:
- ivhd_block = (struct acpi_ivhd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_HARDWARE:
+ ivhd_block = container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header);
return parse_ivhd_block(ivhd_block);

- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
- ivmd_block = (struct acpi_ivmd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
+ ivmd_block = container_of(ivrs_block, const struct acpi_ivrs_memory,
+ header);
return parse_ivmd_block(ivmd_block);

default:
@@ -792,12 +814,11 @@ static void __init dump_acpi_table_heade

}

-static int __init parse_ivrs_table(struct acpi_table_header *_table)
+static int __init parse_ivrs_table(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long length;
int error = 0;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;

BUG_ON(!table);

@@ -805,17 +826,16 @@ static int __init parse_ivrs_table(struc
dump_acpi_table_header(table);

/* parse IVRS blocks */
- length = sizeof(struct acpi_ivrs_table_header);
+ length = sizeof(struct acpi_table_ivrs);
while ( (error == 0) && (table->length > (length + sizeof(*ivrs_block))) )
{
- ivrs_block = (struct acpi_ivrs_block_header *)
- ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);

AMD_IOMMU_DEBUG("IVRS Block:\n");
AMD_IOMMU_DEBUG(" Type 0x%x\n", ivrs_block->type);
AMD_IOMMU_DEBUG(" Flags 0x%x\n", ivrs_block->flags);
AMD_IOMMU_DEBUG(" Length 0x%x\n", ivrs_block->length);
- AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->dev_id);
+ AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->device_id);

if ( table->length < (length + ivrs_block->length) )
{
@@ -833,12 +853,11 @@ static int __init parse_ivrs_table(struc
return error;
}

-static int __init detect_iommu_acpi(struct acpi_table_header *_table)
+static int __init detect_iommu_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long i;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ unsigned long length = sizeof(struct acpi_table_ivrs);
u8 checksum, *raw_table;

/* validate checksum: sum of entire table == 0 */
@@ -854,12 +873,14 @@ static int __init detect_iommu_acpi(stru

while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( amd_iommu_detect_one_acpi((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ amd_iommu_detect_one_acpi(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
@@ -870,63 +891,59 @@ static int __init detect_iommu_acpi(stru
last_bdf = (x); \
} while(0);

-static int __init get_last_bdf_ivhd(void *ivhd)
+static int __init get_last_bdf_ivhd(
+ const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
- struct acpi_ivhd_block_header *ivhd_block;
-
- ivhd_block = (struct acpi_ivhd_block_header *)ivhd;

- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}

- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((u8 *)ivhd_block + block_length);

switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = sizeof(u32);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = sizeof(u64);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_header);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_alias);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_extended);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
- UPDATE_LAST_BDF(ivhd_device->range.trailer.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
- UPDATE_LAST_BDF(ivhd_device->alias_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
- UPDATE_LAST_BDF(ivhd_device->extended_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
- break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
- UPDATE_LAST_BDF(ivhd_device->special.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_special);
+ case ACPI_IVRS_TYPE_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->select.header.id);
+ dev_length = sizeof(ivhd_device->header);
+ break;
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->alias.header.id);
+ dev_length = sizeof(ivhd_device->alias);
+ break;
+ case ACPI_IVRS_TYPE_EXT_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->extended.header.id);
+ dev_length = sizeof(ivhd_device->extended);
+ break;
+ case ACPI_IVRS_TYPE_START:
+ UPDATE_LAST_BDF(ivhd_device->range.end.header.id);
+ dev_length = sizeof(ivhd_device->range);
+ break;
+ case ACPI_IVRS_TYPE_ALIAS_START:
+ UPDATE_LAST_BDF(ivhd_device->alias_range.end.header.id)
+ dev_length = sizeof(ivhd_device->alias_range);
+ break;
+ case ACPI_IVRS_TYPE_EXT_START:
+ UPDATE_LAST_BDF(ivhd_device->extended_range.end.header.id)
+ dev_length = sizeof(ivhd_device->extended_range);
+ break;
+ case ACPI_IVRS_TYPE_SPECIAL:
+ UPDATE_LAST_BDF(ivhd_device->special.used_id)
+ dev_length = sizeof(ivhd_device->special);
break;
default:
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device Type!\n");
@@ -942,20 +959,21 @@ static int __init get_last_bdf_ivhd(void
return 0;
}

-static int __init get_last_bdf_acpi(struct acpi_table_header *_table)
+static int __init get_last_bdf_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ const struct acpi_ivrs_header *ivrs_block;
+ unsigned long length = sizeof(struct acpi_table_ivrs);

while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( get_last_bdf_ivhd((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ get_last_bdf_ivhd(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
@@ -963,16 +981,16 @@ static int __init get_last_bdf_acpi(stru

int __init amd_iommu_detect_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, detect_iommu_acpi);
+ return acpi_table_parse(ACPI_SIG_IVRS, detect_iommu_acpi);
}

int __init amd_iommu_get_ivrs_dev_entries(void)
{
- acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, get_last_bdf_acpi);
+ acpi_table_parse(ACPI_SIG_IVRS, get_last_bdf_acpi);
return last_bdf + 1;
}

int __init amd_iommu_update_ivrs_mapping_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table);
+ return acpi_table_parse(ACPI_SIG_IVRS, parse_ivrs_table);
}
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -20,12 +20,12 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <xen/iommu.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>

static int __init get_iommu_msi_capabilities(
u16 seg, u8 bus, u8 dev, u8 func, struct amd_iommu *iommu)
@@ -103,23 +103,21 @@ void __init get_iommu_features(struct am
}
}

-int __init amd_iommu_detect_one_acpi(void *ivhd)
+int __init amd_iommu_detect_one_acpi(
+ const struct acpi_ivrs_hardware *ivhd_block)
{
struct amd_iommu *iommu;
u8 bus, dev, func;
- struct acpi_ivhd_block_header *ivhd_block;
int rt = 0;

- ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
-
- if ( ivhd_block->header.length < sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("Invalid IVHD Block Length!\n");
return -ENODEV;
}

- if ( !ivhd_block->header.dev_id ||
- !ivhd_block->cap_offset || !ivhd_block->mmio_base)
+ if ( !ivhd_block->header.device_id ||
+ !ivhd_block->capability_offset || !ivhd_block->base_address)
{
AMD_IOMMU_DEBUG("Invalid IVHD Block!\n");
return -ENODEV;
@@ -134,10 +132,10 @@ int __init amd_iommu_detect_one_acpi(voi

spin_lock_init(&iommu->lock);

- iommu->seg = ivhd_block->pci_segment;
- iommu->bdf = ivhd_block->header.dev_id;
- iommu->cap_offset = ivhd_block->cap_offset;
- iommu->mmio_base_phys = ivhd_block->mmio_base;
+ iommu->seg = ivhd_block->pci_segment_group;
+ iommu->bdf = ivhd_block->header.device_id;
+ iommu->cap_offset = ivhd_block->capability_offset;
+ iommu->mmio_base_phys = ivhd_block->base_address;

/* override IOMMU HT flags */
iommu->ht_flags = ivhd_block->header.flags;
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -20,6 +20,7 @@

#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
#include <xen/irq.h>
@@ -28,7 +29,6 @@
#include <asm/hvm/svm/amd-iommu-proto.h>
#include <asm-x86/fixmap.h>
#include <mach_apic.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>

static int __initdata nr_amd_iommus;

@@ -37,9 +37,8 @@ static struct radix_tree_root ivrs_maps;
struct list_head amd_iommu_head;
struct table_struct device_table;

-static int iommu_has_ht_flag(struct amd_iommu *iommu, uint8_t bit)
+static int iommu_has_ht_flag(struct amd_iommu *iommu, u8 mask)
{
- u8 mask = 1U << bit;
return iommu->ht_flags & mask;
}

@@ -80,19 +79,19 @@ static void set_iommu_ht_flags(struct am

/* Setup HT flags */
if ( iommu_has_cap(iommu, PCI_CAP_HT_TUNNEL_SHIFT) )
- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_TT_ENABLE) ?
iommu_set_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT) :
iommu_clear_bit(&entry, IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_RES_PASS_PW) ?
iommu_set_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_ISOC_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_ISOC) ?
iommu_set_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_ISOCHRONOUS_SHIFT);

- iommu_has_ht_flag(iommu, AMD_IOMMU_ACPI_PASS_PW_SHIFT) ?
+ iommu_has_ht_flag(iommu, ACPI_IVHD_PASS_PW) ?
iommu_set_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT):
iommu_clear_bit(&entry, IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT);

--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -18,12 +18,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

+#include <xen/config.h>
+#include <xen/acpi.h>
#include <xen/sched.h>
#include <asm/p2m.h>
#include <xen/hvm/iommu.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
#include "../ats.h"
#include <xen/pci.h>

@@ -215,8 +216,7 @@ void __init iommu_dte_add_device_entry(u
dte[7] = dte[6] = dte[4] = dte[2] = dte[1] = dte[0] = 0;

flags = ivrs_dev->device_flags;
- sys_mgt = get_field_from_byte(flags, AMD_IOMMU_ACPI_SYS_MGT_MASK,
- AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
+ sys_mgt = get_field_from_byte(flags, ACPI_IVHD_SYSTEM_MGMT);
dev_ex = ivrs_dev->dte_allow_exclusion;

flags &= mask;
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-acpi.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- * Author: Leo Duran <leo.duran@amd.com>
- * Author: Wei Wang <wei.wang2@amd.com> - adapted to xen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _ASM_X86_64_AMD_IOMMU_ACPI_H
-#define _ASM_X86_64_AMD_IOMMU_ACPI_H
-
-#include <xen/acpi.h>
-
-/* I/O Virtualization Reporting Structure */
-#define AMD_IOMMU_ACPI_IVRS_SIG "IVRS"
-#define AMD_IOMMU_ACPI_IVHD_TYPE 0x10
-#define AMD_IOMMU_ACPI_IVMD_ALL_TYPE 0x20
-#define AMD_IOMMU_ACPI_IVMD_ONE_TYPE 0x21
-#define AMD_IOMMU_ACPI_IVMD_RANGE_TYPE 0x22
-#define AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE 0x23
-
-/* 4-byte Device Entries */
-#define AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD 0
-#define AMD_IOMMU_ACPI_IVHD_DEV_SELECT 2
-#define AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START 3
-#define AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END 4
-
-/* 8-byte Device Entries */
-#define AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD 64
-#define AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT 66
-#define AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE 67
-#define AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT 70
-#define AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE 71
-#define AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL 72
-
-/* IVHD IOMMU Flags */
-#define AMD_IOMMU_ACPI_COHERENT_MASK 0x20
-#define AMD_IOMMU_ACPI_COHERENT_SHIFT 5
-#define AMD_IOMMU_ACPI_IOTLB_SUP_MASK 0x10
-#define AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT 4
-#define AMD_IOMMU_ACPI_ISOC_MASK 0x08
-#define AMD_IOMMU_ACPI_ISOC_SHIFT 3
-#define AMD_IOMMU_ACPI_RES_PASS_PW_MASK 0x04
-#define AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT 2
-#define AMD_IOMMU_ACPI_PASS_PW_MASK 0x02
-#define AMD_IOMMU_ACPI_PASS_PW_SHIFT 1
-#define AMD_IOMMU_ACPI_HT_TUN_ENB_MASK 0x01
-#define AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT 0
-
-/* IVHD Device Flags */
-#define AMD_IOMMU_ACPI_LINT1_PASS_MASK 0x80
-#define AMD_IOMMU_ACPI_LINT1_PASS_SHIFT 7
-#define AMD_IOMMU_ACPI_LINT0_PASS_MASK 0x40
-#define AMD_IOMMU_ACPI_LINT0_PASS_SHIFT 6
-#define AMD_IOMMU_ACPI_SYS_MGT_MASK 0x30
-#define AMD_IOMMU_ACPI_SYS_MGT_SHIFT 4
-#define AMD_IOMMU_ACPI_NMI_PASS_MASK 0x04
-#define AMD_IOMMU_ACPI_NMI_PASS_SHIFT 2
-#define AMD_IOMMU_ACPI_EINT_PASS_MASK 0x02
-#define AMD_IOMMU_ACPI_EINT_PASS_SHIFT 1
-#define AMD_IOMMU_ACPI_INIT_PASS_MASK 0x01
-#define AMD_IOMMU_ACPI_INIT_PASS_SHIFT 0
-
-/* IVHD Device Extended Flags */
-#define AMD_IOMMU_ACPI_ATS_DISABLED_MASK 0x80000000
-#define AMD_IOMMU_ACPI_ATS_DISABLED_SHIFT 31
-
-/* IVMD Device Flags */
-#define AMD_IOMMU_ACPI_EXCLUSION_RANGE_MASK 0x08
-#define AMD_IOMMU_ACPI_EXCLUSION_RANGE_SHIFT 3
-#define AMD_IOMMU_ACPI_IW_PERMISSION_MASK 0x04
-#define AMD_IOMMU_ACPI_IW_PERMISSION_SHIFT 2
-#define AMD_IOMMU_ACPI_IR_PERMISSION_MASK 0x02
-#define AMD_IOMMU_ACPI_IR_PERMISSION_SHIFT 1
-#define AMD_IOMMU_ACPI_UNITY_MAPPING_MASK 0x01
-#define AMD_IOMMU_ACPI_UNITY_MAPPING_SHIFT 0
-
-#define ACPI_OEM_ID_SIZE 6
-#define ACPI_OEM_TABLE_ID_SIZE 8
-
-#pragma pack(1)
-struct acpi_ivrs_table_header {
- struct acpi_table_header acpi_header;
- u32 io_info;
- u8 reserved[8];
-};
-
-struct acpi_ivrs_block_header {
- u8 type;
- u8 flags;
- u16 length;
- u16 dev_id;
-};
-
-struct acpi_ivhd_block_header {
- struct acpi_ivrs_block_header header;
- u16 cap_offset;
- u64 mmio_base;
- u16 pci_segment;
- u16 iommu_info;
- u8 reserved[4];
-};
-
-struct acpi_ivhd_device_header {
- u8 type;
- u16 dev_id;
- u8 flags;
-};
-
-struct acpi_ivhd_device_trailer {
- u8 type;
- u16 dev_id;
- u8 reserved;
-};
-
-struct acpi_ivhd_device_range {
- struct acpi_ivhd_device_header header;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_alias {
- struct acpi_ivhd_device_header header;
- u8 reserved1;
- u16 dev_id;
- u8 reserved2;
-};
-
-struct acpi_ivhd_device_alias_range {
- struct acpi_ivhd_device_alias alias;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_extended {
- struct acpi_ivhd_device_header header;
- u32 ext_flags;
-};
-
-struct acpi_ivhd_device_extended_range {
- struct acpi_ivhd_device_extended extended;
- struct acpi_ivhd_device_trailer trailer;
-};
-
-struct acpi_ivhd_device_special {
- struct acpi_ivhd_device_header header;
- u8 handle;
- u16 dev_id;
- u8 variety;
-};
-
-union acpi_ivhd_device {
- struct acpi_ivhd_device_header header;
- struct acpi_ivhd_device_range range;
- struct acpi_ivhd_device_alias alias;
- struct acpi_ivhd_device_alias_range alias_range;
- struct acpi_ivhd_device_extended extended;
- struct acpi_ivhd_device_extended_range extended_range;
- struct acpi_ivhd_device_special special;
-};
-
-struct acpi_ivmd_block_header {
- struct acpi_ivrs_block_header header;
- union {
- u16 last_dev_id;
- u16 cap_offset;
- u16 reserved1;
- };
- u64 reserved2;
- u64 start_addr;
- u64 mem_length;
-};
-#pragma pack()
-
-#endif /* _ASM_X86_64_AMD_IOMMU_ACPI_H */
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -26,6 +26,8 @@
#include <asm/apicdef.h>
#include <xen/domain_page.h>

+struct acpi_ivrs_hardware;
+
#define for_each_amd_iommu(amd_iommu) \
list_for_each_entry(amd_iommu, \
&amd_iommu_head, list)
@@ -41,7 +43,7 @@

/* amd-iommu-detect functions */
int amd_iommu_get_ivrs_dev_entries(void);
-int amd_iommu_detect_one_acpi(void *ivhd);
+int amd_iommu_detect_one_acpi(const struct acpi_ivrs_hardware *);
int amd_iommu_detect_acpi(void);
void get_iommu_features(struct amd_iommu *iommu);

@@ -121,11 +123,9 @@ static inline u32 set_field_in_reg_u32(u
return reg_value;
}

-static inline u8 get_field_from_byte(u8 value, u8 mask, u8 shift)
+static inline u8 get_field_from_byte(u8 value, u8 mask)
{
- u8 field;
- field = (value & mask) >> shift;
- return field;
+ return (value & mask) / (mask & -mask);
}

static inline unsigned long region_to_pages(unsigned long addr, unsigned long size)