Page MenuHomeFreeBSD

D47291.diff
No OneTemporary

D47291.diff

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -112,6 +112,7 @@
static void acpi_lookup(void *arg, const char *name, device_t *dev);
static int acpi_modevent(struct module *mod, int event, void *junk);
+static int acpi_parse_pxm(device_t dev);
static device_probe_t acpi_probe;
static device_attach_t acpi_attach;
@@ -142,6 +143,7 @@
static bus_hint_device_unit_t acpi_hint_device_unit;
static bus_get_property_t acpi_bus_get_prop;
static bus_get_device_path_t acpi_get_device_path;
+static bus_get_domain_t acpibus_get_domain_method;
static acpi_id_probe_t acpi_device_id_probe;
static acpi_evaluate_object_t acpi_device_eval_obj;
@@ -219,7 +221,7 @@
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
- DEVMETHOD(bus_get_domain, acpi_get_domain),
+ DEVMETHOD(bus_get_domain, acpibus_get_domain_method),
DEVMETHOD(bus_get_property, acpi_bus_get_prop),
DEVMETHOD(bus_get_device_path, acpi_get_device_path),
@@ -819,6 +821,7 @@
if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT | M_ZERO)) == NULL)
return (NULL);
+ ad->ad_domain = ACPI_DEV_DOMAIN_UNKNOWN;
resource_list_init(&ad->ad_rl);
child = device_add_child_ordered(bus, order, name, unit);
@@ -1055,6 +1058,9 @@
case ACPI_IVAR_FLAGS:
*(int *)result = ad->ad_flags;
break;
+ case ACPI_IVAR_DOMAIN:
+ *(int *)result = ad->ad_domain;
+ break;
case ISA_IVAR_VENDORID:
case ISA_IVAR_SERIAL:
case ISA_IVAR_COMPATID:
@@ -1099,6 +1105,9 @@
case ACPI_IVAR_FLAGS:
ad->ad_flags = (int)value;
break;
+ case ACPI_IVAR_DOMAIN:
+ ad->ad_domain = (int)value;
+ break;
default:
panic("bad ivar write request (%d)", index);
return (ENOENT);
@@ -1306,7 +1315,7 @@
* determined, return ENOENT.
*/
int
-acpi_get_domain(device_t dev, device_t child, int *domain)
+acpi_get_domain_method(device_t dev, device_t child, int *domain)
{
int d;
@@ -1322,6 +1331,25 @@
return (bus_generic_get_domain(dev, child, domain));
}
+static int
+acpibus_get_domain_method(device_t dev, device_t child, int *domain)
+{
+ int error, d;
+
+ error = acpi_read_ivar(dev, child, ACPI_IVAR_DOMAIN,
+ (uintptr_t *)domain);
+ if (error == 0 && *domain != ACPI_DEV_DOMAIN_UNKNOWN)
+ return (0);
+
+ d = acpi_parse_pxm(child);
+ if (d >= 0) {
+ *domain = d;
+ acpi_write_ivar(dev, child, ACPI_IVAR_DOMAIN, d);
+ return (0);
+ }
+ return (ENOENT);
+}
+
static struct rman *
acpi_get_rman(device_t bus, int type, u_int flags)
{
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -108,7 +108,7 @@
DEVMETHOD(bus_get_device_path, acpi_pci_get_device_path),
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag),
- DEVMETHOD(bus_get_domain, acpi_get_domain),
+ DEVMETHOD(bus_get_domain, acpi_get_domain_method),
/* PCI interface */
DEVMETHOD(pci_alloc_devinfo, acpi_pci_alloc_devinfo),
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -89,6 +89,7 @@
void *ad_private;
int ad_flags;
int ad_cls_class;
+ int ad_domain;
ACPI_BUFFER dsd; /* Device Specific Data */
const ACPI_OBJECT *dsd_pkg;
@@ -269,6 +270,12 @@
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
+#define ACPI_IVAR_DOMAIN 0x104
+
+/*
+ * ad_domain NUMA domain special value.
+ */
+#define ACPI_DEV_DOMAIN_UNKNOWN (-1)
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
@@ -294,6 +301,7 @@
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
+__ACPI_BUS_ACCESSOR(acpi, domain, ACPI, DOMAIN, int)
void acpi_fake_objhandler(ACPI_HANDLE h, void *data);
static __inline device_t
@@ -590,7 +598,7 @@
*/
int acpi_map_pxm_to_vm_domainid(int pxm);
bus_get_cpus_t acpi_get_cpus;
-bus_get_domain_t acpi_get_domain;
+bus_get_domain_t acpi_get_domain_method;
#ifdef __aarch64__
/*
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
@@ -266,6 +266,7 @@
DEVICE_SYSCTL_PNPINFO,
DEVICE_SYSCTL_PARENT,
DEVICE_SYSCTL_IOMMU,
+ DEVICE_SYSCTL_DOMAIN,
};
static int
@@ -324,11 +325,32 @@
return (error);
}
+static int
+device_sysctl_handler_int(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ int domain, error;
+
+ bus_topo_lock();
+ switch (arg2) {
+ case DEVICE_SYSCTL_DOMAIN:
+ error = bus_get_domain(dev, &domain);
+ if (error != 0)
+ domain = -1;
+ error = sysctl_handle_int(oidp, &domain, 0, req);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ bus_topo_unlock();
+ return (error);
+}
+
static void
device_sysctl_init(device_t dev)
{
devclass_t dc = dev->devclass;
- int domain;
if (dev->sysctl_tree != NULL)
return;
@@ -367,10 +389,11 @@
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",
- CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, domain, "NUMA domain");
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ OID_AUTO, "%domain",
+ CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ dev, DEVICE_SYSCTL_DOMAIN, device_sysctl_handler_int, "I",
+ "NUMA domain");
}
static void
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
@@ -160,6 +160,27 @@
return (1);
}
+/* Remapping Hardware Static Affinity Structure lookup */
+struct rhsa_iter_arg {
+ uint64_t base;
+ u_int proxim_dom;
+};
+
+static int
+dmar_rhsa_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
+{
+ struct rhsa_iter_arg *ria;
+ ACPI_DMAR_RHSA *adr;
+
+ if (dmarh->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) {
+ ria = arg;
+ adr = (ACPI_DMAR_RHSA *)dmarh;
+ if (adr->BaseAddress == ria->base)
+ ria->proxim_dom = adr->ProximityDomain;
+ }
+ return (1);
+}
+
int dmar_rmrr_enable = 1;
static int dmar_enable = 0;
@@ -168,6 +189,7 @@
{
ACPI_TABLE_DMAR *dmartbl;
ACPI_DMAR_HARDWARE_UNIT *dmarh;
+ struct rhsa_iter_arg ria;
ACPI_STATUS status;
int i, error;
@@ -217,7 +239,15 @@
i, (uintmax_t)dmarh->Address, error);
device_delete_child(parent, dmar_devs[i]);
dmar_devs[i] = NULL;
+ continue;
}
+
+ ria.base = dmarh->Address;
+ ria.proxim_dom = -1;
+ dmar_iterate_tbl(dmar_rhsa_iter, &ria);
+ acpi_set_domain(dmar_devs[i], ria.proxim_dom == -1 ?
+ ACPI_DEV_DOMAIN_UNKNOWN :
+ acpi_map_pxm_to_vm_domainid(ria.proxim_dom));
}
}
@@ -326,34 +356,12 @@
DMAR_ECAP_IRO(unit->hw_ecap));
}
-/* Remapping Hardware Static Affinity Structure lookup */
-struct rhsa_iter_arg {
- uint64_t base;
- u_int proxim_dom;
-};
-
-static int
-dmar_rhsa_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
-{
- struct rhsa_iter_arg *ria;
- ACPI_DMAR_RHSA *adr;
-
- if (dmarh->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) {
- ria = arg;
- adr = (ACPI_DMAR_RHSA *)dmarh;
- if (adr->BaseAddress == ria->base)
- ria->proxim_dom = adr->ProximityDomain;
- }
- return (1);
-}
-
static int
dmar_attach(device_t dev)
{
struct dmar_unit *unit;
ACPI_DMAR_HARDWARE_UNIT *dmaru;
struct iommu_msi_data *dmd;
- struct rhsa_iter_arg ria;
uint64_t timeout;
int disable_pmr;
int i, error;
@@ -381,13 +389,7 @@
if (bootverbose)
dmar_print_caps(dev, unit, dmaru);
dmar_quirks_post_ident(unit);
- unit->memdomain = -1;
- ria.base = unit->base;
- ria.proxim_dom = -1;
- dmar_iterate_tbl(dmar_rhsa_iter, &ria);
- if (ria.proxim_dom != -1)
- unit->memdomain = acpi_map_pxm_to_vm_domainid(ria.proxim_dom);
-
+ unit->memdomain = acpi_get_domain(dev);
timeout = dmar_get_timeout();
TUNABLE_UINT64_FETCH("hw.iommu.dmar.timeout", &timeout);
dmar_update_timeout(timeout);

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 27, 5:26 PM (21 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14360345
Default Alt Text
D47291.diff (8 KB)

Event Timeline