Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 112636
b: refs/heads/master
c: 1886e8a
h: refs/heads/master
v: v3
  • Loading branch information
Suresh Siddha authored and Ingo Molnar committed Jul 12, 2008
1 parent 85a501f commit 0b12e7e
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c42d9f32443397aed2d37d37df161392e6a5862f
refs/heads/master: 1886e8a90a580f3ad343f2065c84c1b9e1dac9ef
89 changes: 73 additions & 16 deletions trunk/drivers/pci/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,37 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
struct acpi_dmar_hardware_unit *drhd;
struct dmar_drhd_unit *dmaru;
int ret = 0;
static int include_all;

dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
if (!dmaru)
return -ENOMEM;

dmaru->hdr = header;
drhd = (struct acpi_dmar_hardware_unit *)header;
dmaru->reg_base_addr = drhd->address;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */

ret = alloc_iommu(dmaru);
if (ret) {
kfree(dmaru);
return ret;
}
dmar_register_drhd_unit(dmaru);
return 0;
}

static int __init
dmar_parse_dev(struct dmar_drhd_unit *dmaru)
{
struct acpi_dmar_hardware_unit *drhd;
static int include_all;
int ret;

drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;

if (!dmaru->include_all)
ret = dmar_parse_dev_scope((void *)(drhd + 1),
((void *)drhd) + header->length,
((void *)drhd) + drhd->header.length,
&dmaru->devices_cnt, &dmaru->devices,
drhd->segment);
else {
Expand All @@ -199,10 +217,10 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
include_all = 1;
}

if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all))
if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) {
list_del(&dmaru->list);
kfree(dmaru);
else
dmar_register_drhd_unit(dmaru);
}
return ret;
}

Expand All @@ -211,23 +229,35 @@ dmar_parse_one_rmrr(struct acpi_dmar_header *header)
{
struct acpi_dmar_reserved_memory *rmrr;
struct dmar_rmrr_unit *rmrru;
int ret = 0;

rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
if (!rmrru)
return -ENOMEM;

rmrru->hdr = header;
rmrr = (struct acpi_dmar_reserved_memory *)header;
rmrru->base_address = rmrr->base_address;
rmrru->end_address = rmrr->end_address;

dmar_register_rmrr_unit(rmrru);
return 0;
}

static int __init
rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
{
struct acpi_dmar_reserved_memory *rmrr;
int ret;

rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
ret = dmar_parse_dev_scope((void *)(rmrr + 1),
((void *)rmrr) + header->length,
((void *)rmrr) + rmrr->header.length,
&rmrru->devices_cnt, &rmrru->devices, rmrr->segment);

if (ret || (rmrru->devices_cnt == 0))
if (ret || (rmrru->devices_cnt == 0)) {
list_del(&rmrru->list);
kfree(rmrru);
else
dmar_register_rmrr_unit(rmrru);
}
return ret;
}

Expand Down Expand Up @@ -333,15 +363,42 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
return NULL;
}

int __init dmar_dev_scope_init(void)
{
struct dmar_drhd_unit *drhd;
struct dmar_rmrr_unit *rmrr;
int ret = -ENODEV;

for_each_drhd_unit(drhd) {
ret = dmar_parse_dev(drhd);
if (ret)
return ret;
}

for_each_rmrr_units(rmrr) {
ret = rmrr_parse_dev(rmrr);
if (ret)
return ret;
}

return ret;
}


int __init dmar_table_init(void)
{

static int dmar_table_initialized;
int ret;

if (dmar_table_initialized)
return 0;

dmar_table_initialized = 1;

ret = parse_dmar_table();
if (ret) {
printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
if (ret != -ENODEV)
printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
return ret;
}

Expand Down Expand Up @@ -377,7 +434,7 @@ int __init early_dmar_detect(void)
return (ACPI_SUCCESS(status) ? 1 : 0);
}

struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
int alloc_iommu(struct dmar_drhd_unit *drhd)
{
struct intel_iommu *iommu;
int map_size;
Expand All @@ -386,7 +443,7 @@ struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)

iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
return NULL;
return -ENOMEM;

iommu->seq_id = iommu_allocated++;

Expand Down Expand Up @@ -419,10 +476,10 @@ struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
spin_lock_init(&iommu->register_lock);

drhd->iommu = iommu;
return iommu;
return 0;
error:
kfree(iommu);
return NULL;
return -1;
}

void free_iommu(struct intel_iommu *iommu)
Expand Down
10 changes: 5 additions & 5 deletions trunk/drivers/pci/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1665,11 +1665,8 @@ int __init init_dmars(void)
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
iommu = alloc_iommu(drhd);
if (!iommu) {
ret = -ENOMEM;
goto error;
}

iommu = drhd->iommu;

ret = iommu_init_domains(iommu);
if (ret)
Expand Down Expand Up @@ -2324,6 +2321,9 @@ int __init intel_iommu_init(void)
if (dmar_table_init())
return -ENODEV;

if (dmar_dev_scope_init())
return -ENODEV;

iommu_init_mempool();
dmar_init_reserved_ranges();

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/pci/intel-iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ struct intel_iommu {

extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);

extern struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd);
extern int alloc_iommu(struct dmar_drhd_unit *drhd);
extern void free_iommu(struct intel_iommu *iommu);

#endif
10 changes: 9 additions & 1 deletion trunk/include/linux/dmar.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ extern int intel_iommu_init(void);

extern int dmar_table_init(void);
extern int early_dmar_detect(void);
extern int dmar_dev_scope_init(void);

extern struct list_head dmar_drhd_units;
extern struct list_head dmar_rmrr_units;

struct dmar_drhd_unit {
struct list_head list; /* list of drhd units */
struct acpi_dmar_header *hdr; /* ACPI header */
u64 reg_base_addr; /* register base address*/
struct pci_dev **devices; /* target device array */
int devices_cnt; /* target device count */
Expand All @@ -62,6 +64,7 @@ struct dmar_drhd_unit {

struct dmar_rmrr_unit {
struct list_head list; /* list of rmrr units */
struct acpi_dmar_header *hdr; /* ACPI header */
u64 base_address; /* reserved base address*/
u64 end_address; /* reserved end address */
struct pci_dev **devices; /* target devices */
Expand All @@ -72,6 +75,8 @@ struct dmar_rmrr_unit {
list_for_each_entry(drhd, &dmar_drhd_units, list)
#define for_each_rmrr_units(rmrr) \
list_for_each_entry(rmrr, &dmar_rmrr_units, list)

extern int alloc_iommu(struct dmar_drhd_unit *);
#else
static inline void detect_intel_iommu(void)
{
Expand All @@ -81,6 +86,9 @@ static inline int intel_iommu_init(void)
{
return -ENODEV;
}

static inline int dmar_table_init(void)
{
return -ENODEV;
}
#endif /* !CONFIG_DMAR */
#endif /* __DMAR_H__ */

0 comments on commit 0b12e7e

Please sign in to comment.