Changeset 84677 in vbox for trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
- Timestamp:
- Jun 4, 2020 1:12:06 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84651 r84677 4548 4548 * @param uDevId The device ID. 4549 4549 * @param pDte The device table entry. 4550 * @param GCPhysIn The source MSI address.4551 * @param uDataIn The source MSI data.4552 4550 * @param enmOp The IOMMU operation being performed. 4553 * @param p GCPhysOut Where to store the remapped MSI address.4554 * @param p uDataOut Where to store the remapped MSI data.4551 * @param pMsiIn The source MSI. 4552 * @param pMsiOut Where to store the remapped MSI. 4555 4553 * 4556 4554 * @thread Any. 4557 4555 */ 4558 static int iommuAmdRemapIntr(PPDMDEVINS pDevIns, uint16_t uDevId, PCDTE_T pDte, RTGCPHYS GCPhysIn, uint32_t uDataIn, 4559 IOMMUOP enmOp, PRTGCPHYS pGCPhysOut, uint32_t *puDataOut) 4560 { 4561 /** @todo Replace GCPhys[Out|In], uData[Out|In] with MSIMSG. */ 4556 static int iommuAmdRemapIntr(PPDMDEVINS pDevIns, uint16_t uDevId, PCDTE_T pDte, IOMMUOP enmOp, PCMSIMSG pMsiIn, 4557 PMSIMSG pMsiOut) 4558 { 4562 4559 Assert(pDte->n.u2IntrCtrl == IOMMU_INTR_CTRL_REMAP); 4563 4560 4564 4561 IRTE_T Irte; 4565 int rc = iommuAmdReadIrte(pDevIns, uDevId, pDte, GCPhysIn, uDataIn, enmOp, &Irte);4562 int rc = iommuAmdReadIrte(pDevIns, uDevId, pDte, pMsiIn->Addr.u64, pMsiIn->Data.u32, enmOp, &Irte); 4566 4563 if (RT_SUCCESS(rc)) 4567 4564 { … … 4572 4569 if (Irte.n.u3IntrType < VBOX_MSI_DELIVERY_MODE_LOWEST_PRIO) 4573 4570 { 4574 MSIADDR MsiAddrIn;4575 MsiAddrIn.u64 = GCPhysIn;4576 4577 MSIDATA MsiDataIn;4578 MsiDataIn.u32 = uDataIn;4579 4580 PMSIADDR pMsiAddrOut = (PMSIADDR)pGCPhysOut;4581 PMSIDATA pMsiDataOut = (PMSIDATA)puDataOut;4582 4583 4571 /* Preserve all bits from the source MSI address that don't map 1:1 from the IRTE. */ 4584 pMsi AddrOut->u64 = GCPhysIn;4585 pMsi AddrOut->n.u1DestMode = Irte.n.u1DestMode;4586 pMsi AddrOut->n.u8DestId = Irte.n.u8Dest;4572 pMsiOut->Addr.u64 = pMsiIn->Addr.u64; 4573 pMsiOut->Addr.n.u1DestMode = Irte.n.u1DestMode; 4574 pMsiOut->Addr.n.u8DestId = Irte.n.u8Dest; 4587 4575 4588 4576 /* Preserve all bits from the source MSI data that don't map 1:1 from the IRTE. */ 4589 pMsi DataOut->u32 = uDataIn;4590 pMsi DataOut->n.u8Vector = Irte.n.u8Vector;4591 pMsi DataOut->n.u3DeliveryMode = Irte.n.u3IntrType;4577 pMsiOut->Data.u32 = pMsiIn->Data.u32; 4578 pMsiOut->Data.n.u8Vector = Irte.n.u8Vector; 4579 pMsiOut->Data.n.u3DeliveryMode = Irte.n.u3IntrType; 4592 4580 4593 4581 return VINF_SUCCESS; … … 4596 4584 Log((IOMMU_LOG_PFX ": Interrupt type (%#x) invalid -> IOPF", Irte.n.u3IntrType)); 4597 4585 EVT_IO_PAGE_FAULT_T EvtIoPageFault; 4598 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, GCPhysIn, Irte.n.u1RemapEnable, true /* fRsvdNotZero */,4599 false /* fPermDenied */, enmOp, &EvtIoPageFault);4586 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, pMsiIn->Addr.u64, Irte.n.u1RemapEnable, 4587 true /* fRsvdNotZero */, false /* fPermDenied */, enmOp, &EvtIoPageFault); 4600 4588 iommuAmdRaiseIoPageFaultEvent(pDevIns, pDte, &Irte, enmOp, &EvtIoPageFault, kIoPageFaultType_IrteRsvdIntType); 4601 4589 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; … … 4604 4592 Log((IOMMU_LOG_PFX ": Guest mode not supported -> IOPF")); 4605 4593 EVT_IO_PAGE_FAULT_T EvtIoPageFault; 4606 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, GCPhysIn, Irte.n.u1RemapEnable, true /* fRsvdNotZero */,4607 false /* fPermDenied */, enmOp, &EvtIoPageFault);4594 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, pMsiIn->Addr.u64, Irte.n.u1RemapEnable, 4595 true /* fRsvdNotZero */, false /* fPermDenied */, enmOp, &EvtIoPageFault); 4608 4596 iommuAmdRaiseIoPageFaultEvent(pDevIns, pDte, &Irte, enmOp, &EvtIoPageFault, kIoPageFaultType_IrteRsvdNotZero); 4609 4597 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; … … 4612 4600 Log((IOMMU_LOG_PFX ": Remapping disabled -> IOPF")); 4613 4601 EVT_IO_PAGE_FAULT_T EvtIoPageFault; 4614 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, GCPhysIn, Irte.n.u1RemapEnable, false /* fRsvdNotZero */,4615 false /* f PermDenied */, enmOp, &EvtIoPageFault);4602 iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, pMsiIn->Addr.u64, Irte.n.u1RemapEnable, 4603 false /* fRsvdNotZero */, false /* fPermDenied */, enmOp, &EvtIoPageFault); 4616 4604 iommuAmdRaiseIoPageFaultEvent(pDevIns, pDte, &Irte, enmOp, &EvtIoPageFault, kIoPageFaultType_IrteRemapEn); 4617 4605 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; … … 4628 4616 * @param pDevIns The IOMMU instance data. 4629 4617 * @param uDevId The device ID. 4630 * @param GCPhysIn The source MSI address.4631 * @param uDataIn The source MSI data.4632 4618 * @param enmOp The IOMMU operation being performed. 4633 * @param p GCPhysOut Where to store the remapped MSI address.4634 * @param p uDataOut Where to store the remapped MSI data.4619 * @param pMsiIn The source MSI. 4620 * @param pMsiOut Where to store the remapped MSI. 4635 4621 * 4636 4622 * @thread Any. 4637 4623 */ 4638 static int iommuAmdLookupIntrTable(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysIn, uint32_t uDataIn, IOMMUOP enmOp, 4639 PRTGCPHYS pGCPhysOut, uint32_t *puDataOut) 4624 static int iommuAmdLookupIntrTable(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PCMSIMSG pMsiIn, PMSIMSG pMsiOut) 4640 4625 { 4641 4626 /* Read the device table entry from memory. */ … … 4658 4643 fRsvd1)); 4659 4644 EVT_ILLEGAL_DTE_T Event; 4660 iommuAmdInitIllegalDteEvent(uDevId, GCPhysIn, true /* fRsvdNotZero */, enmOp, &Event);4645 iommuAmdInitIllegalDteEvent(uDevId, pMsiIn->Addr.u64, true /* fRsvdNotZero */, enmOp, &Event); 4661 4646 iommuAmdRaiseIllegalDteEvent(pDevIns, enmOp, &Event, kIllegalDteType_RsvdNotZero); 4662 4647 return VERR_IOMMU_INTR_REMAP_FAILED; … … 4680 4665 * See Intel spec. 10.11.1 "Message Address Register Format". 4681 4666 */ 4682 MSIADDR MsiAddrIn; 4683 MsiAddrIn.u64 = GCPhysIn; 4684 if ((MsiAddrIn.u64 & VBOX_MSI_ADDR_ADDR_MASK) == VBOX_MSI_ADDR_BASE) 4667 if ((pMsiIn->Addr.u64 & VBOX_MSI_ADDR_ADDR_MASK) == VBOX_MSI_ADDR_BASE) 4685 4668 { 4686 MSIDATA MsiDataIn;4687 MsiDataIn.u32 = uDataIn;4688 4689 4669 /* 4690 4670 * The IOMMU remaps fixed and arbitrated interrupts using the IRTE. 4691 4671 * See AMD IOMMU spec. "2.2.5.1 Interrupt Remapping Tables, Guest Virtual APIC Not Enabled". 4692 4672 */ 4693 uint8_t const u8DeliveryMode = MsiDataIn.n.u3DeliveryMode;4673 uint8_t const u8DeliveryMode = pMsiIn->Data.n.u3DeliveryMode; 4694 4674 bool fPassThru = false; 4695 4675 switch (u8DeliveryMode) … … 4729 4709 NOREF(pThis); 4730 4710 4731 return iommuAmdRemapIntr(pDevIns, uDevId, &Dte, GCPhysIn, uDataIn, enmOp, pGCPhysOut, puDataOut);4711 return iommuAmdRemapIntr(pDevIns, uDevId, &Dte, enmOp, pMsiIn, pMsiOut); 4732 4712 } 4733 4713 4734 4714 Log((IOMMU_LOG_PFX ": Invalid interrupt table length %#x -> Illegal DTE\n", uIntTabLen)); 4735 4715 EVT_ILLEGAL_DTE_T Event; 4736 iommuAmdInitIllegalDteEvent(uDevId, GCPhysIn, false /* fRsvdNotZero */, enmOp, &Event);4716 iommuAmdInitIllegalDteEvent(uDevId, pMsiIn->Addr.u64, false /* fRsvdNotZero */, enmOp, &Event); 4737 4717 iommuAmdRaiseIllegalDteEvent(pDevIns, enmOp, &Event, kIllegalDteType_RsvdIntTabLen); 4738 4718 return VERR_IOMMU_INTR_REMAP_FAILED; … … 4744 4724 Log((IOMMU_LOG_PFX ":IntCtl mode invalid %#x -> Illegal DTE", uIntrCtrl)); 4745 4725 EVT_ILLEGAL_DTE_T Event; 4746 iommuAmdInitIllegalDteEvent(uDevId, GCPhysIn, true /* fRsvdNotZero */, enmOp, &Event);4726 iommuAmdInitIllegalDteEvent(uDevId, pMsiIn->Addr.u64, true /* fRsvdNotZero */, enmOp, &Event); 4747 4727 iommuAmdRaiseIllegalDteEvent(pDevIns, enmOp, &Event, kIllegalDteType_RsvdIntCtl); 4748 4728 return VERR_IOMMU_INTR_REMAP_FAILED; … … 4764 4744 if (fPassThru) 4765 4745 { 4766 *pGCPhysOut = GCPhysIn; 4767 *puDataOut = uDataIn; 4746 *pMsiOut = *pMsiIn; 4768 4747 return VINF_SUCCESS; 4769 4748 } … … 4774 4753 else 4775 4754 { 4776 Log((IOMMU_LOG_PFX ":MSI address region invalid %#RX64.", MsiAddrIn.u64));4755 Log((IOMMU_LOG_PFX ":MSI address region invalid %#RX64.", pMsiIn->Addr.u64)); 4777 4756 return VERR_IOMMU_INTR_REMAP_FAILED; 4778 4757 } … … 4781 4760 { 4782 4761 /** @todo IOMMU: Add to interrupt remapping cache. */ 4783 *pGCPhysOut = GCPhysIn; 4784 *puDataOut = uDataIn; 4762 *pMsiOut = *pMsiIn; 4785 4763 return VINF_SUCCESS; 4786 4764 } … … 4798 4776 * @param pDevIns The IOMMU device instance. 4799 4777 * @param uDevId The device ID (bus, device, function). 4800 * @param GCPhysIn The source MSI address. 4801 * @param uDataIn The source MSI data. 4802 * @param pGCPhysOut Where to store the remapped MSI address. 4803 * @param puDataOut Where to store the remapped MSI data. 4804 */ 4805 static int iommuAmdDeviceMsiRemap(PPDMDEVINS pDevIns, uint16_t uDevId, RTGCPHYS GCPhysIn, uint32_t uDataIn, 4806 PRTGCPHYS pGCPhysOut, uint32_t *puDataOut) 4778 * @param pMsiIn The source MSI. 4779 * @param pMsiOut Where to store the remapped MSI. 4780 */ 4781 static int iommuAmdDeviceMsiRemap(PPDMDEVINS pDevIns, uint16_t uDevId, PCMSIMSG pMsiIn, PMSIMSG pMsiOut) 4807 4782 { 4808 4783 /* Validate. */ 4809 4784 Assert(pDevIns); 4810 Assert(pGCPhysOut); 4811 Assert(puDataOut); 4812 4813 /* Remove later. */ 4814 RT_NOREF(uDevId, GCPhysIn, uDataIn, pGCPhysOut, puDataOut); 4785 Assert(pMsiIn); 4786 Assert(pMsiOut); 4815 4787 4816 4788 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); … … 4822 4794 /** @todo Cache? */ 4823 4795 4824 return iommuAmdLookupIntrTable(pDevIns, uDevId, GCPhysIn, uDataIn, IOMMUOP_INTR_REQ, pGCPhysOut, puDataOut); 4825 } 4826 4827 *pGCPhysOut = GCPhysIn; 4828 *puDataOut = uDataIn; 4796 return iommuAmdLookupIntrTable(pDevIns, uDevId, IOMMUOP_INTR_REQ, pMsiIn, pMsiOut); 4797 } 4798 4799 *pMsiOut = *pMsiIn; 4829 4800 return VINF_SUCCESS; 4830 4801 }
Note:
See TracChangeset
for help on using the changeset viewer.