From 1f0e4d50b2b66edc5aa711c915c4a66817193c80 Mon Sep 17 00:00:00 2001 From: kib <kib@FreeBSD.org> Date: Sun, 26 Mar 2017 00:40:35 +0000 Subject: [PATCH] Provide less laborius way to enable busdma DMAR to only short list of devices. Kernel environment variable hw.busdma.default can take values 'bounce' and 'dmar' and selects corresponding busdma backend as default. Per-device environment variable hw.busdma.pci<domain>.<bus>.<slot>.<func> takes the same values and overrides hw.busdma.default for the given device. Note that even with hw.busdma.default=bounce, DMA translation engines are still started if DMARs are enabled, to disable them use hw.dmar.dma tunable, as before. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/iommu/busdma_dmar.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/sys/x86/iommu/busdma_dmar.c b/sys/x86/iommu/busdma_dmar.c index 434ae8291862..73bf8b292b9e 100644 --- a/sys/x86/iommu/busdma_dmar.c +++ b/sys/x86/iommu/busdma_dmar.c @@ -74,14 +74,34 @@ static bool dmar_bus_dma_is_dev_disabled(int domain, int bus, int slot, int func) { char str[128], *env; + int default_bounce; + bool ret; + static const char bounce_str[] = "bounce"; + static const char dmar_str[] = "dmar"; - snprintf(str, sizeof(str), "hw.busdma.pci%d.%d.%d.%d.bounce", + default_bounce = 0; + env = kern_getenv("hw.busdma.default"); + if (env != NULL) { + if (strcmp(env, bounce_str) == 0) + default_bounce = 1; + else if (strcmp(env, dmar_str) == 0) + default_bounce = 0; + freeenv(env); + } + + snprintf(str, sizeof(str), "hw.busdma.pci%d.%d.%d.%d", domain, bus, slot, func); env = kern_getenv(str); if (env == NULL) - return (false); + return (default_bounce != 0); + if (strcmp(env, bounce_str) == 0) + ret = true; + else if (strcmp(env, dmar_str) == 0) + ret = false; + else + ret = default_bounce != 0; freeenv(env); - return (true); + return (ret); } /*