xref: /freebsd-14-stable/sys/x86/iommu/intel_utils.c (revision f279f9ec29236d8517d2800f6d109a37d73c3143)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2013 The FreeBSD Foundation
5  *
6  * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
7  * under sponsorship from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/memdesc.h>
38 #include <sys/mutex.h>
39 #include <sys/proc.h>
40 #include <sys/queue.h>
41 #include <sys/rman.h>
42 #include <sys/rwlock.h>
43 #include <sys/sched.h>
44 #include <sys/sf_buf.h>
45 #include <sys/sysctl.h>
46 #include <sys/systm.h>
47 #include <sys/taskqueue.h>
48 #include <sys/time.h>
49 #include <sys/tree.h>
50 #include <sys/vmem.h>
51 #include <vm/vm.h>
52 #include <vm/vm_extern.h>
53 #include <vm/vm_kern.h>
54 #include <vm/vm_object.h>
55 #include <vm/vm_page.h>
56 #include <vm/vm_map.h>
57 #include <vm/vm_pageout.h>
58 #include <dev/pci/pcireg.h>
59 #include <dev/pci/pcivar.h>
60 #include <machine/bus.h>
61 #include <machine/cpu.h>
62 #include <machine/intr_machdep.h>
63 #include <x86/include/apicvar.h>
64 #include <x86/include/busdma_impl.h>
65 #include <dev/iommu/busdma_iommu.h>
66 #include <x86/iommu/intel_reg.h>
67 #include <x86/iommu/x86_iommu.h>
68 #include <x86/iommu/intel_dmar.h>
69 
70 u_int
dmar_nd2mask(u_int nd)71 dmar_nd2mask(u_int nd)
72 {
73 	static const u_int masks[] = {
74 		0x000f,	/* nd == 0 */
75 		0x002f,	/* nd == 1 */
76 		0x00ff,	/* nd == 2 */
77 		0x02ff,	/* nd == 3 */
78 		0x0fff,	/* nd == 4 */
79 		0x2fff,	/* nd == 5 */
80 		0xffff,	/* nd == 6 */
81 		0x0000,	/* nd == 7 reserved */
82 	};
83 
84 	KASSERT(nd <= 6, ("number of domains %d", nd));
85 	return (masks[nd]);
86 }
87 
88 static const struct sagaw_bits_tag {
89 	int agaw;
90 	int cap;
91 	int awlvl;
92 	int pglvl;
93 } sagaw_bits[] = {
94 	{.agaw = 30, .cap = DMAR_CAP_SAGAW_2LVL, .awlvl = DMAR_CTX2_AW_2LVL,
95 	    .pglvl = 2},
96 	{.agaw = 39, .cap = DMAR_CAP_SAGAW_3LVL, .awlvl = DMAR_CTX2_AW_3LVL,
97 	    .pglvl = 3},
98 	{.agaw = 48, .cap = DMAR_CAP_SAGAW_4LVL, .awlvl = DMAR_CTX2_AW_4LVL,
99 	    .pglvl = 4},
100 	{.agaw = 57, .cap = DMAR_CAP_SAGAW_5LVL, .awlvl = DMAR_CTX2_AW_5LVL,
101 	    .pglvl = 5}
102 	/*
103 	 * 6-level paging (DMAR_CAP_SAGAW_6LVL) is not supported on any
104 	 * current VT-d hardware and its SAGAW field value is listed as
105 	 * reserved in the VT-d spec.  If support is added in the future,
106 	 * this structure and the logic in dmar_maxaddr2mgaw() will need
107 	 * to change to avoid attempted comparison against 1ULL << 64.
108 	 */
109 };
110 
111 bool
dmar_pglvl_supported(struct dmar_unit * unit,int pglvl)112 dmar_pglvl_supported(struct dmar_unit *unit, int pglvl)
113 {
114 	int i;
115 
116 	for (i = 0; i < nitems(sagaw_bits); i++) {
117 		if (sagaw_bits[i].pglvl != pglvl)
118 			continue;
119 		if ((DMAR_CAP_SAGAW(unit->hw_cap) & sagaw_bits[i].cap) != 0)
120 			return (true);
121 	}
122 	return (false);
123 }
124 
125 int
domain_set_agaw(struct dmar_domain * domain,int mgaw)126 domain_set_agaw(struct dmar_domain *domain, int mgaw)
127 {
128 	int sagaw, i;
129 
130 	domain->mgaw = mgaw;
131 	sagaw = DMAR_CAP_SAGAW(domain->dmar->hw_cap);
132 	for (i = 0; i < nitems(sagaw_bits); i++) {
133 		if (sagaw_bits[i].agaw >= mgaw) {
134 			domain->agaw = sagaw_bits[i].agaw;
135 			domain->pglvl = sagaw_bits[i].pglvl;
136 			domain->awlvl = sagaw_bits[i].awlvl;
137 			return (0);
138 		}
139 	}
140 	device_printf(domain->dmar->iommu.dev,
141 	    "context request mgaw %d: no agaw found, sagaw %x\n",
142 	    mgaw, sagaw);
143 	return (EINVAL);
144 }
145 
146 /*
147  * Find a best fit mgaw for the given maxaddr:
148  *   - if allow_less is false, must find sagaw which maps all requested
149  *     addresses (used by identity mappings);
150  *   - if allow_less is true, and no supported sagaw can map all requested
151  *     address space, accept the biggest sagaw, whatever is it.
152  */
153 int
dmar_maxaddr2mgaw(struct dmar_unit * unit,iommu_gaddr_t maxaddr,bool allow_less)154 dmar_maxaddr2mgaw(struct dmar_unit *unit, iommu_gaddr_t maxaddr, bool allow_less)
155 {
156 	int i;
157 
158 	for (i = 0; i < nitems(sagaw_bits); i++) {
159 		if ((1ULL << sagaw_bits[i].agaw) >= maxaddr &&
160 		    (DMAR_CAP_SAGAW(unit->hw_cap) & sagaw_bits[i].cap) != 0)
161 			break;
162 	}
163 	if (allow_less && i == nitems(sagaw_bits)) {
164 		do {
165 			i--;
166 		} while ((DMAR_CAP_SAGAW(unit->hw_cap) & sagaw_bits[i].cap)
167 		    == 0);
168 	}
169 	if (i < nitems(sagaw_bits))
170 		return (sagaw_bits[i].agaw);
171 	KASSERT(0, ("no mgaw for maxaddr %jx allow_less %d",
172 	    (uintmax_t) maxaddr, allow_less));
173 	return (-1);
174 }
175 
176 /*
177  * Return true if the page table level lvl supports the superpage for
178  * the context ctx.
179  */
180 int
domain_is_sp_lvl(struct dmar_domain * domain,int lvl)181 domain_is_sp_lvl(struct dmar_domain *domain, int lvl)
182 {
183 	int alvl, cap_sps;
184 	static const int sagaw_sp[] = {
185 		DMAR_CAP_SPS_2M,
186 		DMAR_CAP_SPS_1G,
187 		DMAR_CAP_SPS_512G,
188 		DMAR_CAP_SPS_1T
189 	};
190 
191 	alvl = domain->pglvl - lvl - 1;
192 	cap_sps = DMAR_CAP_SPS(domain->dmar->hw_cap);
193 	return (alvl < nitems(sagaw_sp) && (sagaw_sp[alvl] & cap_sps) != 0);
194 }
195 
196 iommu_gaddr_t
domain_page_size(struct dmar_domain * domain,int lvl)197 domain_page_size(struct dmar_domain *domain, int lvl)
198 {
199 
200 	return (pglvl_page_size(domain->pglvl, lvl));
201 }
202 
203 int
calc_am(struct dmar_unit * unit,iommu_gaddr_t base,iommu_gaddr_t size,iommu_gaddr_t * isizep)204 calc_am(struct dmar_unit *unit, iommu_gaddr_t base, iommu_gaddr_t size,
205     iommu_gaddr_t *isizep)
206 {
207 	iommu_gaddr_t isize;
208 	int am;
209 
210 	for (am = DMAR_CAP_MAMV(unit->hw_cap);; am--) {
211 		isize = 1ULL << (am + IOMMU_PAGE_SHIFT);
212 		if ((base & (isize - 1)) == 0 && size >= isize)
213 			break;
214 		if (am == 0)
215 			break;
216 	}
217 	*isizep = isize;
218 	return (am);
219 }
220 
221 int haw;
222 int dmar_tbl_pagecnt;
223 
224 static void
dmar_flush_transl_to_ram(struct dmar_unit * unit,void * dst,size_t sz)225 dmar_flush_transl_to_ram(struct dmar_unit *unit, void *dst, size_t sz)
226 {
227 
228 	if (DMAR_IS_COHERENT(unit))
229 		return;
230 	/*
231 	 * If DMAR does not snoop paging structures accesses, flush
232 	 * CPU cache to memory.
233 	 */
234 	pmap_force_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz);
235 }
236 
237 void
dmar_flush_pte_to_ram(struct dmar_unit * unit,iommu_pte_t * dst)238 dmar_flush_pte_to_ram(struct dmar_unit *unit, iommu_pte_t *dst)
239 {
240 
241 	dmar_flush_transl_to_ram(unit, dst, sizeof(*dst));
242 }
243 
244 void
dmar_flush_ctx_to_ram(struct dmar_unit * unit,dmar_ctx_entry_t * dst)245 dmar_flush_ctx_to_ram(struct dmar_unit *unit, dmar_ctx_entry_t *dst)
246 {
247 
248 	dmar_flush_transl_to_ram(unit, dst, sizeof(*dst));
249 }
250 
251 void
dmar_flush_root_to_ram(struct dmar_unit * unit,dmar_root_entry_t * dst)252 dmar_flush_root_to_ram(struct dmar_unit *unit, dmar_root_entry_t *dst)
253 {
254 
255 	dmar_flush_transl_to_ram(unit, dst, sizeof(*dst));
256 }
257 
258 /*
259  * Load the root entry pointer into the hardware, busily waiting for
260  * the completion.
261  */
262 int
dmar_load_root_entry_ptr(struct dmar_unit * unit)263 dmar_load_root_entry_ptr(struct dmar_unit *unit)
264 {
265 	vm_page_t root_entry;
266 	int error;
267 
268 	/*
269 	 * Access to the GCMD register must be serialized while the
270 	 * command is submitted.
271 	 */
272 	DMAR_ASSERT_LOCKED(unit);
273 
274 	VM_OBJECT_RLOCK(unit->ctx_obj);
275 	root_entry = vm_page_lookup(unit->ctx_obj, 0);
276 	VM_OBJECT_RUNLOCK(unit->ctx_obj);
277 	dmar_write8(unit, DMAR_RTADDR_REG, VM_PAGE_TO_PHYS(root_entry));
278 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_SRTP);
279 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_RTPS)
280 	    != 0));
281 	return (error);
282 }
283 
284 /*
285  * Globally invalidate the context entries cache, busily waiting for
286  * the completion.
287  */
288 int
dmar_inv_ctx_glob(struct dmar_unit * unit)289 dmar_inv_ctx_glob(struct dmar_unit *unit)
290 {
291 	int error;
292 
293 	/*
294 	 * Access to the CCMD register must be serialized while the
295 	 * command is submitted.
296 	 */
297 	DMAR_ASSERT_LOCKED(unit);
298 	KASSERT(!unit->qi_enabled, ("QI enabled"));
299 
300 	/*
301 	 * The DMAR_CCMD_ICC bit in the upper dword should be written
302 	 * after the low dword write is completed.  Amd64
303 	 * dmar_write8() does not have this issue, i386 dmar_write8()
304 	 * writes the upper dword last.
305 	 */
306 	dmar_write8(unit, DMAR_CCMD_REG, DMAR_CCMD_ICC | DMAR_CCMD_CIRG_GLOB);
307 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_CCMD_REG + 4) & DMAR_CCMD_ICC32)
308 	    == 0));
309 	return (error);
310 }
311 
312 /*
313  * Globally invalidate the IOTLB, busily waiting for the completion.
314  */
315 int
dmar_inv_iotlb_glob(struct dmar_unit * unit)316 dmar_inv_iotlb_glob(struct dmar_unit *unit)
317 {
318 	int error, reg;
319 
320 	DMAR_ASSERT_LOCKED(unit);
321 	KASSERT(!unit->qi_enabled, ("QI enabled"));
322 
323 	reg = 16 * DMAR_ECAP_IRO(unit->hw_ecap);
324 	/* See a comment about DMAR_CCMD_ICC in dmar_inv_ctx_glob. */
325 	dmar_write8(unit, reg + DMAR_IOTLB_REG_OFF, DMAR_IOTLB_IVT |
326 	    DMAR_IOTLB_IIRG_GLB | DMAR_IOTLB_DR | DMAR_IOTLB_DW);
327 	DMAR_WAIT_UNTIL(((dmar_read4(unit, reg + DMAR_IOTLB_REG_OFF + 4) &
328 	    DMAR_IOTLB_IVT32) == 0));
329 	return (error);
330 }
331 
332 /*
333  * Flush the chipset write buffers.  See 11.1 "Write Buffer Flushing"
334  * in the architecture specification.
335  */
336 int
dmar_flush_write_bufs(struct dmar_unit * unit)337 dmar_flush_write_bufs(struct dmar_unit *unit)
338 {
339 	int error;
340 
341 	DMAR_ASSERT_LOCKED(unit);
342 
343 	/*
344 	 * DMAR_GCMD_WBF is only valid when CAP_RWBF is reported.
345 	 */
346 	KASSERT((unit->hw_cap & DMAR_CAP_RWBF) != 0,
347 	    ("dmar%d: no RWBF", unit->iommu.unit));
348 
349 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_WBF);
350 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_WBFS)
351 	    != 0));
352 	return (error);
353 }
354 
355 /*
356  * Some BIOSes protect memory region they reside in by using DMAR to
357  * prevent devices from doing any DMA transactions to that part of RAM.
358  * AMI refers to this as "DMA Control Guarantee".
359  * We need to disable this when address translation is enabled.
360  */
361 int
dmar_disable_protected_regions(struct dmar_unit * unit)362 dmar_disable_protected_regions(struct dmar_unit *unit)
363 {
364 	uint32_t reg;
365 	int error;
366 
367 	DMAR_ASSERT_LOCKED(unit);
368 
369 	/* Check if we support the feature. */
370 	if ((unit->hw_cap & (DMAR_CAP_PLMR | DMAR_CAP_PHMR)) == 0)
371 		return (0);
372 
373 	reg = dmar_read4(unit, DMAR_PMEN_REG);
374 	if ((reg & DMAR_PMEN_EPM) == 0)
375 		return (0);
376 
377 	reg &= ~DMAR_PMEN_EPM;
378 	dmar_write4(unit, DMAR_PMEN_REG, reg);
379 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_PMEN_REG) & DMAR_PMEN_PRS)
380 	    != 0));
381 
382 	return (error);
383 }
384 
385 int
dmar_enable_translation(struct dmar_unit * unit)386 dmar_enable_translation(struct dmar_unit *unit)
387 {
388 	int error;
389 
390 	DMAR_ASSERT_LOCKED(unit);
391 	unit->hw_gcmd |= DMAR_GCMD_TE;
392 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd);
393 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_TES)
394 	    != 0));
395 	return (error);
396 }
397 
398 int
dmar_disable_translation(struct dmar_unit * unit)399 dmar_disable_translation(struct dmar_unit *unit)
400 {
401 	int error;
402 
403 	DMAR_ASSERT_LOCKED(unit);
404 	unit->hw_gcmd &= ~DMAR_GCMD_TE;
405 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd);
406 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_TES)
407 	    == 0));
408 	return (error);
409 }
410 
411 int
dmar_load_irt_ptr(struct dmar_unit * unit)412 dmar_load_irt_ptr(struct dmar_unit *unit)
413 {
414 	uint64_t irta, s;
415 	int error;
416 
417 	DMAR_ASSERT_LOCKED(unit);
418 	irta = unit->irt_phys;
419 	if (DMAR_X2APIC(unit))
420 		irta |= DMAR_IRTA_EIME;
421 	s = fls(unit->irte_cnt) - 2;
422 	KASSERT(unit->irte_cnt >= 2 && s <= DMAR_IRTA_S_MASK &&
423 	    powerof2(unit->irte_cnt),
424 	    ("IRTA_REG_S overflow %x", unit->irte_cnt));
425 	irta |= s;
426 	dmar_write8(unit, DMAR_IRTA_REG, irta);
427 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd | DMAR_GCMD_SIRTP);
428 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRTPS)
429 	    != 0));
430 	return (error);
431 }
432 
433 int
dmar_enable_ir(struct dmar_unit * unit)434 dmar_enable_ir(struct dmar_unit *unit)
435 {
436 	int error;
437 
438 	DMAR_ASSERT_LOCKED(unit);
439 	unit->hw_gcmd |= DMAR_GCMD_IRE;
440 	unit->hw_gcmd &= ~DMAR_GCMD_CFI;
441 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd);
442 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRES)
443 	    != 0));
444 	return (error);
445 }
446 
447 int
dmar_disable_ir(struct dmar_unit * unit)448 dmar_disable_ir(struct dmar_unit *unit)
449 {
450 	int error;
451 
452 	DMAR_ASSERT_LOCKED(unit);
453 	unit->hw_gcmd &= ~DMAR_GCMD_IRE;
454 	dmar_write4(unit, DMAR_GCMD_REG, unit->hw_gcmd);
455 	DMAR_WAIT_UNTIL(((dmar_read4(unit, DMAR_GSTS_REG) & DMAR_GSTS_IRES)
456 	    == 0));
457 	return (error);
458 }
459 
460 #define BARRIER_F				\
461 	u_int f_done, f_inproc, f_wakeup;	\
462 						\
463 	f_done = 1 << (barrier_id * 3);		\
464 	f_inproc = 1 << (barrier_id * 3 + 1);	\
465 	f_wakeup = 1 << (barrier_id * 3 + 2)
466 
467 bool
dmar_barrier_enter(struct dmar_unit * dmar,u_int barrier_id)468 dmar_barrier_enter(struct dmar_unit *dmar, u_int barrier_id)
469 {
470 	BARRIER_F;
471 
472 	DMAR_LOCK(dmar);
473 	if ((dmar->barrier_flags & f_done) != 0) {
474 		DMAR_UNLOCK(dmar);
475 		return (false);
476 	}
477 
478 	if ((dmar->barrier_flags & f_inproc) != 0) {
479 		while ((dmar->barrier_flags & f_inproc) != 0) {
480 			dmar->barrier_flags |= f_wakeup;
481 			msleep(&dmar->barrier_flags, &dmar->iommu.lock, 0,
482 			    "dmarb", 0);
483 		}
484 		KASSERT((dmar->barrier_flags & f_done) != 0,
485 		    ("dmar%d barrier %d missing done", dmar->iommu.unit,
486 		    barrier_id));
487 		DMAR_UNLOCK(dmar);
488 		return (false);
489 	}
490 
491 	dmar->barrier_flags |= f_inproc;
492 	DMAR_UNLOCK(dmar);
493 	return (true);
494 }
495 
496 void
dmar_barrier_exit(struct dmar_unit * dmar,u_int barrier_id)497 dmar_barrier_exit(struct dmar_unit *dmar, u_int barrier_id)
498 {
499 	BARRIER_F;
500 
501 	DMAR_ASSERT_LOCKED(dmar);
502 	KASSERT((dmar->barrier_flags & (f_done | f_inproc)) == f_inproc,
503 	    ("dmar%d barrier %d missed entry", dmar->iommu.unit, barrier_id));
504 	dmar->barrier_flags |= f_done;
505 	if ((dmar->barrier_flags & f_wakeup) != 0)
506 		wakeup(&dmar->barrier_flags);
507 	dmar->barrier_flags &= ~(f_inproc | f_wakeup);
508 	DMAR_UNLOCK(dmar);
509 }
510 
511 struct timespec dmar_hw_timeout = {
512 	.tv_sec = 0,
513 	.tv_nsec = 1000000
514 };
515 
516 static const uint64_t d = 1000000000;
517 
518 void
dmar_update_timeout(uint64_t newval)519 dmar_update_timeout(uint64_t newval)
520 {
521 
522 	/* XXXKIB not atomic */
523 	dmar_hw_timeout.tv_sec = newval / d;
524 	dmar_hw_timeout.tv_nsec = newval % d;
525 }
526 
527 uint64_t
dmar_get_timeout(void)528 dmar_get_timeout(void)
529 {
530 
531 	return ((uint64_t)dmar_hw_timeout.tv_sec * d +
532 	    dmar_hw_timeout.tv_nsec);
533 }
534 
535 static int
dmar_timeout_sysctl(SYSCTL_HANDLER_ARGS)536 dmar_timeout_sysctl(SYSCTL_HANDLER_ARGS)
537 {
538 	uint64_t val;
539 	int error;
540 
541 	val = dmar_get_timeout();
542 	error = sysctl_handle_long(oidp, &val, 0, req);
543 	if (error != 0 || req->newptr == NULL)
544 		return (error);
545 	dmar_update_timeout(val);
546 	return (error);
547 }
548 
549 SYSCTL_PROC(_hw_iommu_dmar, OID_AUTO, timeout,
550     CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0,
551     dmar_timeout_sysctl, "QU",
552     "Timeout for command wait, in nanoseconds");
553