svn commit: r346663 - stable/12/sys/x86/iommu
Konstantin Belousov
kib at FreeBSD.org
Thu Apr 25 08:28:56 UTC 2019
Author: kib
Date: Thu Apr 25 08:28:54 2019
New Revision: 346663
URL: https://svnweb.freebsd.org/changeset/base/346663
Log:
MFC r346352, r346355:
Correct handling of RMRR during early enumeration stages.
Modified:
stable/12/sys/x86/iommu/busdma_dmar.c
stable/12/sys/x86/iommu/intel_ctx.c
stable/12/sys/x86/iommu/intel_dmar.h
stable/12/sys/x86/iommu/intel_drv.c
stable/12/sys/x86/iommu/intel_intrmap.c
stable/12/sys/x86/iommu/intel_utils.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/x86/iommu/busdma_dmar.c
==============================================================================
--- stable/12/sys/x86/iommu/busdma_dmar.c Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/busdma_dmar.c Thu Apr 25 08:28:54 2019 (r346663)
@@ -275,7 +275,7 @@ dmar_get_dma_tag(device_t dev, device_t child)
struct dmar_ctx *ctx;
bus_dma_tag_t res;
- dmar = dmar_find(child);
+ dmar = dmar_find(child, bootverbose);
/* Not in scope of any DMAR ? */
if (dmar == NULL)
return (NULL);
Modified: stable/12/sys/x86/iommu/intel_ctx.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_ctx.c Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/intel_ctx.c Thu Apr 25 08:28:54 2019 (r346663)
@@ -62,6 +62,8 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/md_var.h>
#include <machine/specialreg.h>
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
@@ -203,7 +205,9 @@ dmar_flush_for_ctx_entry(struct dmar_unit *dmar, bool
}
static int
-domain_init_rmrr(struct dmar_domain *domain, device_t dev)
+domain_init_rmrr(struct dmar_domain *domain, device_t dev, int bus,
+ int slot, int func, int dev_domain, int dev_busno,
+ const void *dev_path, int dev_path_len)
{
struct dmar_map_entries_tailq rmrr_entries;
struct dmar_map_entry *entry, *entry1;
@@ -214,7 +218,8 @@ domain_init_rmrr(struct dmar_domain *domain, device_t
error = 0;
TAILQ_INIT(&rmrr_entries);
- dmar_dev_parse_rmrr(domain, dev, &rmrr_entries);
+ dmar_dev_parse_rmrr(domain, dev_domain, dev_busno, dev_path,
+ dev_path_len, &rmrr_entries);
TAILQ_FOREACH_SAFE(entry, &rmrr_entries, unroll_link, entry1) {
/*
* VT-d specification requires that the start of an
@@ -227,12 +232,19 @@ domain_init_rmrr(struct dmar_domain *domain, device_t
*/
start = entry->start;
end = entry->end;
+ if (bootverbose)
+ printf("dmar%d ctx pci%d:%d:%d RMRR [%#jx, %#jx]\n",
+ domain->dmar->unit, bus, slot, func,
+ (uintmax_t)start, (uintmax_t)end);
entry->start = trunc_page(start);
entry->end = round_page(end);
if (entry->start == entry->end) {
/* Workaround for some AMI (?) BIOSes */
if (bootverbose) {
- device_printf(dev, "BIOS bug: dmar%d RMRR "
+ if (dev != NULL)
+ device_printf(dev, "");
+ printf("pci%d:%d:%d ", bus, slot, func);
+ printf("BIOS bug: dmar%d RMRR "
"region (%jx, %jx) corrected\n",
domain->dmar->unit, start, end);
}
@@ -260,9 +272,13 @@ domain_init_rmrr(struct dmar_domain *domain, device_t
DMAR_UNLOCK(domain->dmar);
} else {
if (error1 != 0) {
- device_printf(dev,
+ if (dev != NULL)
+ device_printf(dev, "");
+ printf("pci%d:%d:%d ", bus, slot, func);
+ printf(
"dmar%d failed to map RMRR region (%jx, %jx) %d\n",
- domain->dmar->unit, start, end, error1);
+ domain->dmar->unit, start, end,
+ error1);
error = error1;
}
TAILQ_REMOVE(&rmrr_entries, entry, unroll_link);
@@ -404,8 +420,9 @@ dmar_domain_destroy(struct dmar_domain *domain)
free(domain, M_DMAR_DOMAIN);
}
-struct dmar_ctx *
-dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t dev, uint16_t rid,
+static struct dmar_ctx *
+dmar_get_ctx_for_dev1(struct dmar_unit *dmar, device_t dev, uint16_t rid,
+ int dev_domain, int dev_busno, const void *dev_path, int dev_path_len,
bool id_mapped, bool rmrr_init)
{
struct dmar_domain *domain, *domain1;
@@ -415,9 +432,15 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
int bus, slot, func, error;
bool enable;
- bus = pci_get_bus(dev);
- slot = pci_get_slot(dev);
- func = pci_get_function(dev);
+ if (dev != NULL) {
+ bus = pci_get_bus(dev);
+ slot = pci_get_slot(dev);
+ func = pci_get_function(dev);
+ } else {
+ bus = PCI_RID2BUS(rid);
+ slot = PCI_RID2SLOT(rid);
+ func = PCI_RID2FUNC(rid);
+ }
enable = false;
TD_PREP_PINNED_ASSERT;
DMAR_LOCK(dmar);
@@ -436,7 +459,9 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
return (NULL);
}
if (!id_mapped) {
- error = domain_init_rmrr(domain1, dev);
+ error = domain_init_rmrr(domain1, dev, bus,
+ slot, func, dev_domain, dev_busno, dev_path,
+ dev_path_len);
if (error != 0) {
dmar_domain_destroy(domain1);
TD_PINNED_ASSERT;
@@ -468,12 +493,14 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
enable = true;
LIST_INSERT_HEAD(&dmar->domains, domain, link);
ctx_id_entry_init(ctx, ctxp, false);
- device_printf(dev,
+ if (dev != NULL) {
+ device_printf(dev,
"dmar%d pci%d:%d:%d:%d rid %x domain %d mgaw %d "
- "agaw %d %s-mapped\n",
- dmar->unit, dmar->segment, bus, slot,
- func, rid, domain->domain, domain->mgaw,
- domain->agaw, id_mapped ? "id" : "re");
+ "agaw %d %s-mapped\n",
+ dmar->unit, dmar->segment, bus, slot,
+ func, rid, domain->domain, domain->mgaw,
+ domain->agaw, id_mapped ? "id" : "re");
+ }
dmar_unmap_pgtbl(sf);
} else {
dmar_unmap_pgtbl(sf);
@@ -485,6 +512,8 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
}
} else {
domain = ctx->domain;
+ if (ctx->ctx_tag.owner == NULL)
+ ctx->ctx_tag.owner = dev;
ctx->refs++; /* tag referenced us */
}
@@ -502,7 +531,14 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
*/
if (enable && !rmrr_init && (dmar->hw_gcmd & DMAR_GCMD_TE) == 0) {
error = dmar_enable_translation(dmar);
- if (error != 0) {
+ if (error == 0) {
+ if (bootverbose) {
+ printf("dmar%d: enabled translation\n",
+ dmar->unit);
+ }
+ } else {
+ printf("dmar%d: enabling translation failed, "
+ "error %d\n", dmar->unit, error);
dmar_free_ctx_locked(dmar, ctx);
TD_PINNED_ASSERT;
return (NULL);
@@ -511,6 +547,31 @@ dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t
DMAR_UNLOCK(dmar);
TD_PINNED_ASSERT;
return (ctx);
+}
+
+struct dmar_ctx *
+dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t dev, uint16_t rid,
+ bool id_mapped, bool rmrr_init)
+{
+ int dev_domain, dev_path_len, dev_busno;
+
+ dev_domain = pci_get_domain(dev);
+ dev_path_len = dmar_dev_depth(dev);
+ ACPI_DMAR_PCI_PATH dev_path[dev_path_len];
+ dmar_dev_path(dev, &dev_busno, dev_path, dev_path_len);
+ return (dmar_get_ctx_for_dev1(dmar, dev, rid, dev_domain, dev_busno,
+ dev_path, dev_path_len, id_mapped, rmrr_init));
+}
+
+struct dmar_ctx *
+dmar_get_ctx_for_devpath(struct dmar_unit *dmar, uint16_t rid,
+ int dev_domain, int dev_busno,
+ const void *dev_path, int dev_path_len,
+ bool id_mapped, bool rmrr_init)
+{
+
+ return (dmar_get_ctx_for_dev1(dmar, NULL, rid, dev_domain, dev_busno,
+ dev_path, dev_path_len, id_mapped, rmrr_init));
}
int
Modified: stable/12/sys/x86/iommu/intel_dmar.h
==============================================================================
--- stable/12/sys/x86/iommu/intel_dmar.h Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/intel_dmar.h Thu Apr 25 08:28:54 2019 (r346663)
@@ -258,7 +258,7 @@ struct dmar_unit {
#define DMAR_BARRIER_RMRR 0
#define DMAR_BARRIER_USEQ 1
-struct dmar_unit *dmar_find(device_t dev);
+struct dmar_unit *dmar_find(device_t dev, bool verbose);
struct dmar_unit *dmar_find_hpet(device_t dev, uint16_t *rid);
struct dmar_unit *dmar_find_ioapic(u_int apic_id, uint16_t *rid);
@@ -325,10 +325,16 @@ void domain_flush_iotlb_sync(struct dmar_domain *domai
int domain_alloc_pgtbl(struct dmar_domain *domain);
void domain_free_pgtbl(struct dmar_domain *domain);
+int dmar_dev_depth(device_t child);
+void dmar_dev_path(device_t child, int *busno, void *path1, int depth);
+
struct dmar_ctx *dmar_instantiate_ctx(struct dmar_unit *dmar, device_t dev,
bool rmrr);
struct dmar_ctx *dmar_get_ctx_for_dev(struct dmar_unit *dmar, device_t dev,
uint16_t rid, bool id_mapped, bool rmrr_init);
+struct dmar_ctx *dmar_get_ctx_for_devpath(struct dmar_unit *dmar, uint16_t rid,
+ int dev_domain, int dev_busno, const void *dev_path, int dev_path_len,
+ bool id_mapped, bool rmrr_init);
int dmar_move_ctx_to_domain(struct dmar_domain *domain, struct dmar_ctx *ctx);
void dmar_free_ctx_locked(struct dmar_unit *dmar, struct dmar_ctx *ctx);
void dmar_free_ctx(struct dmar_ctx *ctx);
@@ -360,7 +366,8 @@ int dmar_gas_map_region(struct dmar_domain *domain,
int dmar_gas_reserve_region(struct dmar_domain *domain, dmar_gaddr_t start,
dmar_gaddr_t end);
-void dmar_dev_parse_rmrr(struct dmar_domain *domain, device_t dev,
+void dmar_dev_parse_rmrr(struct dmar_domain *domain, int dev_domain,
+ int dev_busno, const void *dev_path, int dev_path_len,
struct dmar_map_entries_tailq *rmrr_entries);
int dmar_instantiate_rmrr_ctxs(struct dmar_unit *dmar);
@@ -382,7 +389,6 @@ void dmar_fini_irt(struct dmar_unit *unit);
extern dmar_haddr_t dmar_high;
extern int haw;
extern int dmar_tbl_pagecnt;
-extern int dmar_match_verbose;
extern int dmar_batch_coalesce;
extern int dmar_check_free;
Modified: stable/12/sys/x86/iommu/intel_drv.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_drv.c Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/intel_drv.c Thu Apr 25 08:28:54 2019 (r346663)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/tree.h>
#include <sys/vmem.h>
#include <machine/bus.h>
+#include <machine/pci_cfgreg.h>
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
@@ -176,7 +177,6 @@ dmar_identify(driver_t *driver, device_t parent)
#ifdef INVARIANTS
TUNABLE_INT_FETCH("hw.dmar.check_free", &dmar_check_free);
#endif
- TUNABLE_INT_FETCH("hw.dmar.match_verbose", &dmar_match_verbose);
status = AcpiGetTable(ACPI_SIG_DMAR, 1, (ACPI_TABLE_HEADER **)&dmartbl);
if (ACPI_FAILURE(status))
return;
@@ -595,21 +595,20 @@ DRIVER_MODULE(dmar, acpi, dmar_driver, dmar_devclass,
MODULE_DEPEND(dmar, acpi, 1, 1, 1);
static void
-dmar_print_path(device_t dev, const char *banner, int busno, int depth,
- const ACPI_DMAR_PCI_PATH *path)
+dmar_print_path(int busno, int depth, const ACPI_DMAR_PCI_PATH *path)
{
int i;
- device_printf(dev, "%s [%d, ", banner, busno);
+ printf("[%d, ", busno);
for (i = 0; i < depth; i++) {
if (i != 0)
printf(", ");
printf("(%d, %d)", path[i].Device, path[i].Function);
}
- printf("]\n");
+ printf("]");
}
-static int
+int
dmar_dev_depth(device_t child)
{
devclass_t pci_class;
@@ -627,13 +626,15 @@ dmar_dev_depth(device_t child)
}
}
-static void
-dmar_dev_path(device_t child, int *busno, ACPI_DMAR_PCI_PATH *path, int depth)
+void
+dmar_dev_path(device_t child, int *busno, void *path1, int depth)
{
devclass_t pci_class;
device_t bus, pcib;
+ ACPI_DMAR_PCI_PATH *path;
pci_class = devclass_find("pci");
+ path = path1;
for (depth--; depth != -1; depth--) {
path[depth].Device = pci_get_slot(child);
path[depth].Function = pci_get_function(child);
@@ -673,14 +674,14 @@ dmar_match_pathes(int busno1, const ACPI_DMAR_PCI_PATH
}
static int
-dmar_match_devscope(ACPI_DMAR_DEVICE_SCOPE *devscope, device_t dev,
- int dev_busno, const ACPI_DMAR_PCI_PATH *dev_path, int dev_path_len)
+dmar_match_devscope(ACPI_DMAR_DEVICE_SCOPE *devscope, int dev_busno,
+ const ACPI_DMAR_PCI_PATH *dev_path, int dev_path_len)
{
ACPI_DMAR_PCI_PATH *path;
int path_len;
if (devscope->Length < sizeof(*devscope)) {
- printf("dmar_find: corrupted DMAR table, dl %d\n",
+ printf("dmar_match_devscope: corrupted DMAR table, dl %d\n",
devscope->Length);
return (-1);
}
@@ -689,99 +690,112 @@ dmar_match_devscope(ACPI_DMAR_DEVICE_SCOPE *devscope,
return (0);
path_len = devscope->Length - sizeof(*devscope);
if (path_len % 2 != 0) {
- printf("dmar_find_bsf: corrupted DMAR table, dl %d\n",
+ printf("dmar_match_devscope: corrupted DMAR table, dl %d\n",
devscope->Length);
return (-1);
}
path_len /= 2;
path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
if (path_len == 0) {
- printf("dmar_find: corrupted DMAR table, dl %d\n",
+ printf("dmar_match_devscope: corrupted DMAR table, dl %d\n",
devscope->Length);
return (-1);
}
- if (dmar_match_verbose)
- dmar_print_path(dev, "DMAR", devscope->Bus, path_len, path);
return (dmar_match_pathes(devscope->Bus, path, path_len, dev_busno,
dev_path, dev_path_len, devscope->EntryType));
}
-struct dmar_unit *
-dmar_find(device_t dev)
+static bool
+dmar_match_by_path(struct dmar_unit *unit, int dev_domain, int dev_busno,
+ const ACPI_DMAR_PCI_PATH *dev_path, int dev_path_len, const char **banner)
{
- device_t dmar_dev;
ACPI_DMAR_HARDWARE_UNIT *dmarh;
ACPI_DMAR_DEVICE_SCOPE *devscope;
char *ptr, *ptrend;
- int i, match, dev_domain, dev_busno, dev_path_len;
+ int match;
+ dmarh = dmar_find_by_index(unit->unit);
+ if (dmarh == NULL)
+ return (false);
+ if (dmarh->Segment != dev_domain)
+ return (false);
+ if ((dmarh->Flags & ACPI_DMAR_INCLUDE_ALL) != 0) {
+ if (banner != NULL)
+ *banner = "INCLUDE_ALL";
+ return (true);
+ }
+ ptr = (char *)dmarh + sizeof(*dmarh);
+ ptrend = (char *)dmarh + dmarh->Header.Length;
+ while (ptr < ptrend) {
+ devscope = (ACPI_DMAR_DEVICE_SCOPE *)ptr;
+ ptr += devscope->Length;
+ match = dmar_match_devscope(devscope, dev_busno, dev_path,
+ dev_path_len);
+ if (match == -1)
+ return (false);
+ if (match == 1) {
+ if (banner != NULL)
+ *banner = "specific match";
+ return (true);
+ }
+ }
+ return (false);
+}
+
+static struct dmar_unit *
+dmar_find_by_scope(int dev_domain, int dev_busno,
+ const ACPI_DMAR_PCI_PATH *dev_path, int dev_path_len)
+{
+ struct dmar_unit *unit;
+ int i;
+
+ for (i = 0; i < dmar_devcnt; i++) {
+ if (dmar_devs[i] == NULL)
+ continue;
+ unit = device_get_softc(dmar_devs[i]);
+ if (dmar_match_by_path(unit, dev_domain, dev_busno, dev_path,
+ dev_path_len, NULL))
+ return (unit);
+ }
+ return (NULL);
+}
+
+struct dmar_unit *
+dmar_find(device_t dev, bool verbose)
+{
+ device_t dmar_dev;
+ struct dmar_unit *unit;
+ const char *banner;
+ int i, dev_domain, dev_busno, dev_path_len;
+
dmar_dev = NULL;
dev_domain = pci_get_domain(dev);
dev_path_len = dmar_dev_depth(dev);
ACPI_DMAR_PCI_PATH dev_path[dev_path_len];
dmar_dev_path(dev, &dev_busno, dev_path, dev_path_len);
- if (dmar_match_verbose)
- dmar_print_path(dev, "PCI", dev_busno, dev_path_len, dev_path);
+ banner = "";
for (i = 0; i < dmar_devcnt; i++) {
if (dmar_devs[i] == NULL)
continue;
- dmarh = dmar_find_by_index(i);
- if (dmarh == NULL)
- continue;
- if (dmarh->Segment != dev_domain)
- continue;
- if ((dmarh->Flags & ACPI_DMAR_INCLUDE_ALL) != 0) {
- dmar_dev = dmar_devs[i];
- if (dmar_match_verbose) {
- device_printf(dev,
- "pci%d:%d:%d:%d matched dmar%d INCLUDE_ALL\n",
- dev_domain, pci_get_bus(dev),
- pci_get_slot(dev),
- pci_get_function(dev),
- ((struct dmar_unit *)device_get_softc(
- dmar_dev))->unit);
- }
- goto found;
- }
- ptr = (char *)dmarh + sizeof(*dmarh);
- ptrend = (char *)dmarh + dmarh->Header.Length;
- for (;;) {
- if (ptr >= ptrend)
- break;
- devscope = (ACPI_DMAR_DEVICE_SCOPE *)ptr;
- ptr += devscope->Length;
- if (dmar_match_verbose) {
- device_printf(dev,
- "pci%d:%d:%d:%d matching dmar%d\n",
- dev_domain, pci_get_bus(dev),
- pci_get_slot(dev),
- pci_get_function(dev),
- ((struct dmar_unit *)device_get_softc(
- dmar_devs[i]))->unit);
- }
- match = dmar_match_devscope(devscope, dev, dev_busno,
- dev_path, dev_path_len);
- if (dmar_match_verbose) {
- if (match == -1)
- printf("table error\n");
- else if (match == 0)
- printf("not matched\n");
- else
- printf("matched\n");
- }
- if (match == -1)
- return (NULL);
- else if (match == 1) {
- dmar_dev = dmar_devs[i];
- goto found;
- }
- }
+ unit = device_get_softc(dmar_devs[i]);
+ if (dmar_match_by_path(unit, dev_domain, dev_busno,
+ dev_path, dev_path_len, &banner))
+ break;
}
- return (NULL);
-found:
- return (device_get_softc(dmar_dev));
+ if (i == dmar_devcnt)
+ return (NULL);
+
+ if (verbose) {
+ device_printf(dev, "pci%d:%d:%d:%d matched dmar%d by %s",
+ dev_domain, pci_get_bus(dev), pci_get_slot(dev),
+ pci_get_function(dev), unit->unit, banner);
+ printf(" scope path ");
+ dmar_print_path(dev_busno, dev_path_len, dev_path);
+ printf("\n");
+ }
+ return (unit);
}
static struct dmar_unit *
@@ -865,10 +879,9 @@ dmar_find_ioapic(u_int apic_id, uint16_t *rid)
struct rmrr_iter_args {
struct dmar_domain *domain;
- device_t dev;
int dev_domain;
int dev_busno;
- ACPI_DMAR_PCI_PATH *dev_path;
+ const ACPI_DMAR_PCI_PATH *dev_path;
int dev_path_len;
struct dmar_map_entries_tailq *rmrr_entries;
};
@@ -888,12 +901,6 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
ria = arg;
resmem = (ACPI_DMAR_RESERVED_MEMORY *)dmarh;
- if (dmar_match_verbose) {
- printf("RMRR [%jx,%jx] segment %d\n",
- (uintmax_t)resmem->BaseAddress,
- (uintmax_t)resmem->EndAddress,
- resmem->Segment);
- }
if (resmem->Segment != ria->dev_domain)
return (1);
@@ -904,11 +911,9 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
break;
devscope = (ACPI_DMAR_DEVICE_SCOPE *)ptr;
ptr += devscope->Length;
- match = dmar_match_devscope(devscope, ria->dev, ria->dev_busno,
+ match = dmar_match_devscope(devscope, ria->dev_busno,
ria->dev_path, ria->dev_path_len);
if (match == 1) {
- if (dmar_match_verbose)
- printf("matched\n");
entry = dmar_gas_alloc_entry(ria->domain,
DMAR_PGF_WAITOK);
entry->start = resmem->BaseAddress;
@@ -916,8 +921,6 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
entry->end = resmem->EndAddress;
TAILQ_INSERT_TAIL(ria->rmrr_entries, entry,
unroll_link);
- } else if (dmar_match_verbose) {
- printf("not matched, err %d\n", match);
}
}
@@ -925,25 +928,17 @@ dmar_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg)
}
void
-dmar_dev_parse_rmrr(struct dmar_domain *domain, device_t dev,
+dmar_dev_parse_rmrr(struct dmar_domain *domain, int dev_domain, int dev_busno,
+ const void *dev_path, int dev_path_len,
struct dmar_map_entries_tailq *rmrr_entries)
{
struct rmrr_iter_args ria;
- ria.dev_domain = pci_get_domain(dev);
- ria.dev_path_len = dmar_dev_depth(dev);
- ACPI_DMAR_PCI_PATH dev_path[ria.dev_path_len];
- dmar_dev_path(dev, &ria.dev_busno, dev_path, ria.dev_path_len);
-
- if (dmar_match_verbose) {
- device_printf(dev, "parsing RMRR entries for ");
- dmar_print_path(dev, "PCI", ria.dev_busno, ria.dev_path_len,
- dev_path);
- }
-
ria.domain = domain;
- ria.dev = dev;
- ria.dev_path = dev_path;
+ ria.dev_domain = dev_domain;
+ ria.dev_busno = dev_busno;
+ ria.dev_path = (const ACPI_DMAR_PCI_PATH *)dev_path;
+ ria.dev_path_len = dev_path_len;
ria.rmrr_entries = rmrr_entries;
dmar_iterate_tbl(dmar_rmrr_iter, &ria);
}
@@ -954,28 +949,22 @@ struct inst_rmrr_iter_args {
static device_t
dmar_path_dev(int segment, int path_len, int busno,
- const ACPI_DMAR_PCI_PATH *path)
+ const ACPI_DMAR_PCI_PATH *path, uint16_t *rid)
{
- devclass_t pci_class;
- device_t bus, pcib, dev;
+ device_t dev;
int i;
- pci_class = devclass_find("pci");
dev = NULL;
- for (i = 0; i < path_len; i++, path++) {
+ for (i = 0; i < path_len; i++) {
dev = pci_find_dbsf(segment, busno, path->Device,
path->Function);
- if (dev == NULL)
- break;
if (i != path_len - 1) {
- bus = device_get_parent(dev);
- pcib = device_get_parent(bus);
- if (device_get_devclass(device_get_parent(pcib)) !=
- pci_class)
- return (NULL);
+ busno = pci_cfgregread(busno, path->Device,
+ path->Function, PCIR_SECBUS_1, 1);
+ path++;
}
- busno = pcib_get_bus(dev);
}
+ *rid = PCI_RID(busno, path->Device, path->Function);
return (dev);
}
@@ -986,21 +975,19 @@ dmar_inst_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg
const ACPI_DMAR_DEVICE_SCOPE *devscope;
struct inst_rmrr_iter_args *iria;
const char *ptr, *ptrend;
- struct dmar_unit *dev_dmar;
device_t dev;
+ struct dmar_unit *unit;
+ int dev_path_len;
+ uint16_t rid;
+ iria = arg;
+
if (dmarh->Type != ACPI_DMAR_TYPE_RESERVED_MEMORY)
return (1);
- iria = arg;
resmem = (ACPI_DMAR_RESERVED_MEMORY *)dmarh;
if (resmem->Segment != iria->dmar->segment)
return (1);
- if (dmar_match_verbose) {
- printf("dmar%d: RMRR [%jx,%jx]\n", iria->dmar->unit,
- (uintmax_t)resmem->BaseAddress,
- (uintmax_t)resmem->EndAddress);
- }
ptr = (const char *)resmem + sizeof(*resmem);
ptrend = (const char *)resmem + resmem->Header.Length;
@@ -1012,31 +999,40 @@ dmar_inst_rmrr_iter(ACPI_DMAR_HEADER *dmarh, void *arg
/* XXXKIB bridge */
if (devscope->EntryType != ACPI_DMAR_SCOPE_TYPE_ENDPOINT)
continue;
- if (dmar_match_verbose) {
- dmar_print_path(iria->dmar->dev, "RMRR scope",
- devscope->Bus, (devscope->Length -
- sizeof(ACPI_DMAR_DEVICE_SCOPE)) / 2,
- (const ACPI_DMAR_PCI_PATH *)(devscope + 1));
- }
- dev = dmar_path_dev(resmem->Segment, (devscope->Length -
- sizeof(ACPI_DMAR_DEVICE_SCOPE)) / 2, devscope->Bus,
- (const ACPI_DMAR_PCI_PATH *)(devscope + 1));
+ rid = 0;
+ dev_path_len = (devscope->Length -
+ sizeof(ACPI_DMAR_DEVICE_SCOPE)) / 2;
+ dev = dmar_path_dev(resmem->Segment, dev_path_len,
+ devscope->Bus,
+ (const ACPI_DMAR_PCI_PATH *)(devscope + 1), &rid);
if (dev == NULL) {
- if (dmar_match_verbose)
- printf("null dev\n");
- continue;
- }
- dev_dmar = dmar_find(dev);
- if (dev_dmar != iria->dmar) {
- if (dmar_match_verbose) {
- printf("dmar%d matched, skipping\n",
- dev_dmar->unit);
+ if (bootverbose) {
+ printf("dmar%d no dev found for RMRR "
+ "[%#jx, %#jx] rid %#x scope path ",
+ iria->dmar->unit,
+ (uintmax_t)resmem->BaseAddress,
+ (uintmax_t)resmem->EndAddress,
+ rid);
+ dmar_print_path(devscope->Bus, dev_path_len,
+ (const ACPI_DMAR_PCI_PATH *)(devscope + 1));
+ printf("\n");
}
- continue;
+ unit = dmar_find_by_scope(resmem->Segment,
+ devscope->Bus,
+ (const ACPI_DMAR_PCI_PATH *)(devscope + 1),
+ dev_path_len);
+ if (iria->dmar != unit)
+ continue;
+ dmar_get_ctx_for_devpath(iria->dmar, rid,
+ resmem->Segment, devscope->Bus,
+ (const ACPI_DMAR_PCI_PATH *)(devscope + 1),
+ dev_path_len, false, true);
+ } else {
+ unit = dmar_find(dev, false);
+ if (iria->dmar != unit)
+ continue;
+ dmar_instantiate_ctx(iria->dmar, dev, true);
}
- if (dmar_match_verbose)
- printf("matched, instantiating RMRR context\n");
- dmar_instantiate_ctx(iria->dmar, dev, true);
}
return (1);
@@ -1057,8 +1053,6 @@ dmar_instantiate_rmrr_ctxs(struct dmar_unit *dmar)
error = 0;
iria.dmar = dmar;
- if (dmar_match_verbose)
- printf("dmar%d: instantiating RMRR contexts\n", dmar->unit);
dmar_iterate_tbl(dmar_inst_rmrr_iter, &iria);
DMAR_LOCK(dmar);
if (!LIST_EMPTY(&dmar->domains)) {
@@ -1066,6 +1060,15 @@ dmar_instantiate_rmrr_ctxs(struct dmar_unit *dmar)
("dmar%d: RMRR not handled but translation is already enabled",
dmar->unit));
error = dmar_enable_translation(dmar);
+ if (bootverbose) {
+ if (error == 0) {
+ printf("dmar%d: enabled translation\n",
+ dmar->unit);
+ } else {
+ printf("dmar%d: enabling translation failed, "
+ "error %d\n", dmar->unit, error);
+ }
+ }
}
dmar_barrier_exit(dmar, DMAR_BARRIER_RMRR);
return (error);
Modified: stable/12/sys/x86/iommu/intel_intrmap.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_intrmap.c Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/intel_intrmap.c Thu Apr 25 08:28:54 2019 (r346663)
@@ -251,7 +251,7 @@ dmar_ir_find(device_t src, uint16_t *rid, int *is_dmar
} else if (src_class == devclass_find("hpet")) {
unit = dmar_find_hpet(src, rid);
} else {
- unit = dmar_find(src);
+ unit = dmar_find(src, bootverbose);
if (unit != NULL && rid != NULL)
dmar_get_requester(src, rid);
}
Modified: stable/12/sys/x86/iommu/intel_utils.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_utils.c Thu Apr 25 08:27:00 2019 (r346662)
+++ stable/12/sys/x86/iommu/intel_utils.c Thu Apr 25 08:28:54 2019 (r346663)
@@ -614,7 +614,6 @@ dmar_barrier_exit(struct dmar_unit *dmar, u_int barrie
DMAR_UNLOCK(dmar);
}
-int dmar_match_verbose;
int dmar_batch_coalesce = 100;
struct timespec dmar_hw_timeout = {
.tv_sec = 0,
@@ -658,9 +657,6 @@ static SYSCTL_NODE(_hw, OID_AUTO, dmar, CTLFLAG_RD, NU
SYSCTL_INT(_hw_dmar, OID_AUTO, tbl_pagecnt, CTLFLAG_RD,
&dmar_tbl_pagecnt, 0,
"Count of pages used for DMAR pagetables");
-SYSCTL_INT(_hw_dmar, OID_AUTO, match_verbose, CTLFLAG_RWTUN,
- &dmar_match_verbose, 0,
- "Verbose matching of the PCI devices to DMAR paths");
SYSCTL_INT(_hw_dmar, OID_AUTO, batch_coalesce, CTLFLAG_RWTUN,
&dmar_batch_coalesce, 0,
"Number of qi batches between interrupt");
More information about the svn-src-stable-12
mailing list