intel_iommu.c (e85c0d14014514a2f0faeae5b4c23fab5b234de4) | intel_iommu.c (8991c460be5a0811194fd4d2b49ba7146a23526b) |
---|---|
1/* 2 * QEMU emulation of an Intel IOMMU (VT-d) 3 * (DMA Remapping device) 4 * 5 * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com> 6 * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 1436 unchanged lines hidden (view full) --- 1445 1446 default: 1447 trace_vtd_err("IOTLB flush: invalid granularity."); 1448 iaig = 0; 1449 } 1450 return iaig; 1451} 1452 | 1/* 2 * QEMU emulation of an Intel IOMMU (VT-d) 3 * (DMA Remapping device) 4 * 5 * Copyright (C) 2013 Knut Omang, Oracle <knut.omang@oracle.com> 6 * Copyright (C) 2014 Le Tan, <tamlokveer@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 1436 unchanged lines hidden (view full) --- 1445 1446 default: 1447 trace_vtd_err("IOTLB flush: invalid granularity."); 1448 iaig = 0; 1449 } 1450 return iaig; 1451} 1452 |
1453static inline bool vtd_queued_inv_enable_check(IntelIOMMUState *s) 1454{ 1455 return s->iq_tail == 0; 1456} | 1453static void vtd_fetch_inv_desc(IntelIOMMUState *s); |
1457 1458static inline bool vtd_queued_inv_disable_check(IntelIOMMUState *s) 1459{ 1460 return s->qi_enabled && (s->iq_tail == s->iq_head) && 1461 (s->iq_last_desc_type == VTD_INV_DESC_WAIT); 1462} 1463 1464static void vtd_handle_gcmd_qie(IntelIOMMUState *s, bool en) 1465{ 1466 uint64_t iqa_val = vtd_get_quad_raw(s, DMAR_IQA_REG); 1467 1468 trace_vtd_inv_qi_enable(en); 1469 1470 if (en) { | 1454 1455static inline bool vtd_queued_inv_disable_check(IntelIOMMUState *s) 1456{ 1457 return s->qi_enabled && (s->iq_tail == s->iq_head) && 1458 (s->iq_last_desc_type == VTD_INV_DESC_WAIT); 1459} 1460 1461static void vtd_handle_gcmd_qie(IntelIOMMUState *s, bool en) 1462{ 1463 uint64_t iqa_val = vtd_get_quad_raw(s, DMAR_IQA_REG); 1464 1465 trace_vtd_inv_qi_enable(en); 1466 1467 if (en) { |
1471 if (vtd_queued_inv_enable_check(s)) { 1472 s->iq = iqa_val & VTD_IQA_IQA_MASK; 1473 /* 2^(x+8) entries */ 1474 s->iq_size = 1UL << ((iqa_val & VTD_IQA_QS) + 8); 1475 s->qi_enabled = true; 1476 trace_vtd_inv_qi_setup(s->iq, s->iq_size); 1477 /* Ok - report back to driver */ 1478 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_QIES); 1479 } else { 1480 trace_vtd_err_qi_enable(s->iq_tail); | 1468 s->iq = iqa_val & VTD_IQA_IQA_MASK; 1469 /* 2^(x+8) entries */ 1470 s->iq_size = 1UL << ((iqa_val & VTD_IQA_QS) + 8); 1471 s->qi_enabled = true; 1472 trace_vtd_inv_qi_setup(s->iq, s->iq_size); 1473 /* Ok - report back to driver */ 1474 vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_QIES); 1475 1476 if (s->iq_tail != 0) { 1477 /* 1478 * This is a spec violation but Windows guests are known to set up 1479 * Queued Invalidation this way so we allow the write and process 1480 * Invalidation Descriptors right away. 1481 */ 1482 trace_vtd_warn_invalid_qi_tail(s->iq_tail); 1483 if (!(vtd_get_long_raw(s, DMAR_FSTS_REG) & VTD_FSTS_IQE)) { 1484 vtd_fetch_inv_desc(s); 1485 } |
1481 } 1482 } else { 1483 if (vtd_queued_inv_disable_check(s)) { 1484 /* disable Queued Invalidation */ 1485 vtd_set_quad_raw(s, DMAR_IQH_REG, 0); 1486 s->iq_head = 0; 1487 s->qi_enabled = false; 1488 /* Ok - report back to driver */ --- 1573 unchanged lines hidden --- | 1486 } 1487 } else { 1488 if (vtd_queued_inv_disable_check(s)) { 1489 /* disable Queued Invalidation */ 1490 vtd_set_quad_raw(s, DMAR_IQH_REG, 0); 1491 s->iq_head = 0; 1492 s->qi_enabled = false; 1493 /* Ok - report back to driver */ --- 1573 unchanged lines hidden --- |