Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109379218
D47098.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D47098.diff
View Options
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -29,6 +29,7 @@
#include <sys/cdefs.h>
#include "opt_bus.h"
#include "opt_ddb.h"
+#include "opt_iommu.h"
#include <sys/param.h>
#include <sys/conf.h>
@@ -60,6 +61,8 @@
#include <vm/uma.h>
#include <vm/vm.h>
+#include <dev/iommu/iommu.h>
+
#include <ddb/ddb.h>
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
@@ -261,6 +264,7 @@
DEVICE_SYSCTL_LOCATION,
DEVICE_SYSCTL_PNPINFO,
DEVICE_SYSCTL_PARENT,
+ DEVICE_SYSCTL_IOMMU,
};
static int
@@ -268,7 +272,10 @@
{
struct sbuf sb;
device_t dev = (device_t)arg1;
+ device_t iommu;
int error;
+ uint16_t rid;
+ const char *c;
sbuf_new_for_sysctl(&sb, NULL, 1024, req);
sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
@@ -289,6 +296,22 @@
case DEVICE_SYSCTL_PARENT:
sbuf_cat(&sb, dev->parent ? dev->parent->nameunit : "");
break;
+ case DEVICE_SYSCTL_IOMMU:
+ iommu = NULL;
+ error = device_get_prop(dev, DEV_PROP_NAME_IOMMU,
+ (void **)&iommu);
+ c = "";
+ if (error == 0 && iommu != NULL) {
+ sbuf_printf(&sb, "unit=%s", device_get_nameunit(iommu));
+ c = " ";
+ }
+ rid = 0;
+#ifdef IOMMU
+ iommu_get_requester(dev, &rid);
+#endif
+ if (rid != 0)
+ sbuf_printf(&sb, "%srid=%#x", c, rid);
+ break;
default:
error = EINVAL;
goto out;
@@ -338,6 +361,11 @@
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A",
"parent device");
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ OID_AUTO, "%iommu",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, DEVICE_SYSCTL_IOMMU, device_sysctl_handler, "A",
+ "iommu unit handling the device requests");
if (bus_get_domain(dev, &domain) == 0)
SYSCTL_ADD_INT(&dev->sysctl_ctx,
SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%domain",
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -924,6 +924,7 @@
void dev_wired_cache_fini(device_location_cache_t *dcp);
bool dev_wired_cache_match(device_location_cache_t *dcp, device_t dev, const char *at);
+#define DEV_PROP_NAME_IOMMU "iommu-unit"
typedef void (*device_prop_dtr_t)(device_t dev, const char *name, void *val,
void *dtr_ctx);
int device_set_prop(device_t dev, const char *name, void *val,
diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c
--- a/sys/x86/iommu/intel_drv.c
+++ b/sys/x86/iommu/intel_drv.c
@@ -757,6 +757,7 @@
dmar_print_path(dev_busno, dev_path_len, dev_path);
printf("\n");
}
+ iommu_device_set_iommu_prop(dev, unit->iommu.dev);
return (unit);
}
@@ -826,16 +827,28 @@
struct dmar_unit *
dmar_find_hpet(device_t dev, uint16_t *rid)
{
+ struct dmar_unit *unit;
- return (dmar_find_nonpci(hpet_get_uid(dev), ACPI_DMAR_SCOPE_TYPE_HPET,
- rid));
+ unit = dmar_find_nonpci(hpet_get_uid(dev), ACPI_DMAR_SCOPE_TYPE_HPET,
+ rid);
+ if (unit != NULL)
+ iommu_device_set_iommu_prop(dev, unit->iommu.dev);
+ return (unit);
}
struct dmar_unit *
dmar_find_ioapic(u_int apic_id, uint16_t *rid)
{
+ struct dmar_unit *unit;
+ device_t apic_dev;
- return (dmar_find_nonpci(apic_id, ACPI_DMAR_SCOPE_TYPE_IOAPIC, rid));
+ unit = dmar_find_nonpci(apic_id, ACPI_DMAR_SCOPE_TYPE_IOAPIC, rid);
+ if (unit != NULL) {
+ apic_dev = ioapic_get_dev(apic_id);
+ if (apic_dev != NULL)
+ iommu_device_set_iommu_prop(apic_dev, unit->iommu.dev);
+ }
+ return (unit);
}
struct rmrr_iter_args {
diff --git a/sys/x86/iommu/iommu_utils.c b/sys/x86/iommu/iommu_utils.c
--- a/sys/x86/iommu/iommu_utils.c
+++ b/sys/x86/iommu/iommu_utils.c
@@ -758,6 +758,19 @@
return (pg_sz[rlvl]);
}
+void
+iommu_device_set_iommu_prop(device_t dev, device_t iommu)
+{
+ device_t iommu_dev;
+ int error;
+
+ bus_topo_lock();
+ error = device_get_prop(dev, DEV_PROP_NAME_IOMMU, (void **)&iommu_dev);
+ if (error == ENOENT)
+ device_set_prop(dev, DEV_PROP_NAME_IOMMU, iommu, NULL, NULL);
+ bus_topo_unlock();
+}
+
#ifdef DDB
#include <ddb/ddb.h>
#include <ddb/db_lex.h>
diff --git a/sys/x86/iommu/x86_iommu.h b/sys/x86/iommu/x86_iommu.h
--- a/sys/x86/iommu/x86_iommu.h
+++ b/sys/x86/iommu/x86_iommu.h
@@ -188,6 +188,7 @@
void iommu_release_intr(struct iommu_unit *unit, int idx);
void iommu_device_tag_init(struct iommu_ctx *ctx, device_t dev);
+void iommu_device_set_iommu_prop(device_t dev, device_t iommu);
int pglvl_pgtbl_pte_off(int pglvl, iommu_gaddr_t base, int lvl);
vm_pindex_t pglvl_pgtbl_get_pindex(int pglvl, iommu_gaddr_t base, int lvl);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 5, 7:24 AM (21 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16469804
Default Alt Text
D47098.diff (4 KB)
Attached To
Mode
D47098: devices: report iommu translating device' requests in the dev. sysctl tree
Attached
Detach File
Event Timeline
Log In to Comment