cap_t CONST Arch_updateCapData(bool_t preserve, word_t data, cap_t cap) { /* Avoid a switch statement with just a 'default' case as the C parser does not like this */ #ifdef CONFIG_IOMMU switch (cap_get_capType(cap)) { case cap_io_space_cap: { io_space_capdata_t w = { { data } }; uint16_t PCIDevice = io_space_capdata_get_PCIDevice(w); uint16_t domainID = io_space_capdata_get_domainID(w); if (!preserve && cap_io_space_cap_get_capPCIDevice(cap) == 0 && domainID >= x86KSFirstValidIODomain && domainID != 0 && domainID <= MASK(x86KSnumIODomainIDBits)) { return cap_io_space_cap_new(domainID, PCIDevice); } else { return cap_null_cap_new(); } } default: return cap; } #endif return cap; }
cap_t CONST Arch_updateCapData(bool_t preserve, word_t data, cap_t cap) { switch (cap_get_capType(cap)) { #ifdef CONFIG_IOMMU case cap_io_space_cap: { io_space_capdata_t w = { { data } }; uint16_t PCIDevice = io_space_capdata_get_PCIDevice(w); uint16_t domainID = io_space_capdata_get_domainID(w); vtd_cte_t *vtd_context_table = (vtd_cte_t*)vtd_rte_get_ctp(ia32KSvtdRootTable[get_pci_bus(data)]); if (!preserve && cap_io_space_cap_get_capPCIDevice(cap) == 0 && vtd_rte_get_present(ia32KSvtdRootTable[get_pci_bus(data)]) && (!vtd_cte_get_present(vtd_context_table[PCIDevice & 0xff]) || vtd_cte_get_translation_type(vtd_context_table[PCIDevice & 0xff]) != 2) && domainID <= MASK(ia32KSnumIODomainIDBits)) { return cap_io_space_cap_new(domainID, PCIDevice); } else { return cap_null_cap_new(); } } #endif case cap_io_port_cap: { io_port_capdata_t w = { .words = { data } }; uint16_t firstPort = io_port_capdata_get_firstPort(w); uint16_t lastPort = io_port_capdata_get_lastPort(w); uint16_t capFirstPort = cap_io_port_cap_get_capIOPortFirstPort(cap); uint16_t capLastPort = cap_io_port_cap_get_capIOPortLastPort(cap); assert(capFirstPort <= capLastPort); /* Ensure input data is ordered correctly. */ if (firstPort > lastPort) { return cap_null_cap_new(); } /* Allow the update if the new cap has range no larger than the old * cap. */ if ((firstPort >= capFirstPort) && (lastPort <= capLastPort)) { return cap_io_port_cap_new(firstPort, lastPort); } else { return cap_null_cap_new(); } } default: return cap; } }