!205 [next] Zhaoxin: iommu/vt-d: Add support for detecting ACPI namespace device in RMRR
Merge pull request !205 from LeoLiu-oc/next-6.6-22-iommu
This commit is contained in:
commit
389e22e6a7
|
@ -562,6 +562,25 @@ resv_iova:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iova_reserve_domain_addr(struct iommu_domain *domain, dma_addr_t start, dma_addr_t end)
|
||||
{
|
||||
struct iommu_dma_cookie *cookie = domain->iova_cookie;
|
||||
struct iova_domain *iovad = &cookie->iovad;
|
||||
|
||||
unsigned long lo, hi;
|
||||
|
||||
lo = iova_pfn(iovad, start);
|
||||
hi = iova_pfn(iovad, end);
|
||||
|
||||
if (!cookie)
|
||||
return -EINVAL;
|
||||
|
||||
reserve_iova(iovad, lo, hi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iova_reserve_domain_addr);
|
||||
|
||||
static int iova_reserve_iommu_regions(struct device *dev,
|
||||
struct iommu_domain *domain)
|
||||
{
|
||||
|
|
|
@ -767,6 +767,59 @@ static void __init dmar_acpi_insert_dev_scope(u8 device_number,
|
|||
device_number, dev_name(&adev->dev));
|
||||
}
|
||||
|
||||
/* Return: > 0 if match found, 0 if no match found */
|
||||
bool dmar_rmrr_acpi_insert_dev_scope(u8 device_number,
|
||||
struct acpi_device *adev,
|
||||
void *start, void *end,
|
||||
struct dmar_dev_scope *devices,
|
||||
int devices_cnt)
|
||||
{
|
||||
struct acpi_dmar_device_scope *scope;
|
||||
struct device *tmp;
|
||||
int i;
|
||||
struct acpi_dmar_pci_path *path;
|
||||
|
||||
for (; start < end; start += scope->length) {
|
||||
scope = start;
|
||||
if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE)
|
||||
continue;
|
||||
if (scope->enumeration_id != device_number)
|
||||
continue;
|
||||
path = (void *)(scope + 1);
|
||||
pr_info("ACPI device \"%s\" under DMAR as %02x:%02x.%d\n", dev_name(&adev->dev),
|
||||
scope->bus, path->device, path->function);
|
||||
for_each_dev_scope(devices, devices_cnt, i, tmp)
|
||||
if (tmp == NULL) {
|
||||
devices[i].bus = scope->bus;
|
||||
devices[i].devfn = PCI_DEVFN(path->device, path->function);
|
||||
rcu_assign_pointer(devices[i].dev, get_device(&adev->dev));
|
||||
return true;
|
||||
}
|
||||
WARN_ON(i >= devices_cnt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int dmar_acpi_bus_add_dev(u8 device_number, struct acpi_device *adev)
|
||||
{
|
||||
struct dmar_drhd_unit *dmaru;
|
||||
struct acpi_dmar_hardware_unit *drhd;
|
||||
int ret;
|
||||
|
||||
for_each_drhd_unit(dmaru) {
|
||||
drhd = container_of(dmaru->hdr, struct acpi_dmar_hardware_unit, header);
|
||||
ret = dmar_rmrr_acpi_insert_dev_scope(device_number, adev, (void *)(drhd+1),
|
||||
((void *)drhd)+drhd->header.length,
|
||||
dmaru->devices, dmaru->devices_cnt);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
if (ret > 0)
|
||||
ret = dmar_rmrr_add_acpi_dev(device_number, adev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init dmar_acpi_dev_scope_init(void)
|
||||
{
|
||||
struct acpi_dmar_andd *andd;
|
||||
|
@ -794,7 +847,11 @@ static int __init dmar_acpi_dev_scope_init(void)
|
|||
andd->device_name);
|
||||
continue;
|
||||
}
|
||||
dmar_acpi_insert_dev_scope(andd->device_number, adev);
|
||||
|
||||
if (apply_zhaoxin_dmar_acpi_a_behavior())
|
||||
dmar_acpi_bus_add_dev(andd->device_number, adev);
|
||||
else
|
||||
dmar_acpi_insert_dev_scope(andd->device_number, adev);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -3468,6 +3468,24 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int dmar_rmrr_add_acpi_dev(u8 device_number, struct acpi_device *adev)
|
||||
{
|
||||
int ret;
|
||||
struct dmar_rmrr_unit *rmrru;
|
||||
struct acpi_dmar_reserved_memory *rmrr;
|
||||
|
||||
list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
|
||||
rmrr = container_of(rmrru->hdr, struct acpi_dmar_reserved_memory, header);
|
||||
ret = dmar_rmrr_acpi_insert_dev_scope(device_number, adev, (void *)(rmrr + 1),
|
||||
((void *)rmrr) + rmrr->header.length,
|
||||
rmrru->devices, rmrru->devices_cnt);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
|
||||
{
|
||||
int ret;
|
||||
|
@ -3726,6 +3744,43 @@ static int __init platform_optin_force_iommu(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline int acpi_rmrr_device_create_direct_mappings(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_info("rmrr andd dev:%s enter to %s\n", dev_name(dev), __func__);
|
||||
ret = __acpi_rmrr_device_create_direct_mappings(domain, dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int acpi_rmrr_andd_probe(struct device *dev)
|
||||
{
|
||||
struct intel_iommu *iommu = NULL;
|
||||
struct pci_dev *pci_device = NULL;
|
||||
u8 bus, devfn;
|
||||
int ret = 0;
|
||||
|
||||
ret = iommu_probe_device(dev);
|
||||
|
||||
iommu = device_to_iommu(dev, &bus, &devfn);
|
||||
if (!iommu) {
|
||||
pr_info("dpoint-- cannot get acpi device corresponding iommu\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pci_device = pci_get_domain_bus_and_slot(iommu->segment, bus, devfn);
|
||||
if (!pci_device) {
|
||||
pr_info("dpoint-- cannot get acpi devie corresponding pci_device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = acpi_rmrr_device_create_direct_mappings(iommu_get_domain_for_dev(&pci_device->dev),
|
||||
dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init probe_acpi_namespace_devices(void)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
|
@ -3748,6 +3803,10 @@ static int __init probe_acpi_namespace_devices(void)
|
|||
list_for_each_entry(pn,
|
||||
&adev->physical_node_list, node) {
|
||||
ret = iommu_probe_device(pn->dev);
|
||||
|
||||
if (apply_zhaoxin_dmar_acpi_a_behavior())
|
||||
ret = acpi_rmrr_andd_probe(dev);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1103,7 +1103,8 @@ map_end:
|
|||
map_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_zhaoxin_dmar_acpi_a_behavior())
|
||||
iova_reserve_domain_addr(domain, start, end);
|
||||
}
|
||||
|
||||
if (!list_empty(&mappings) && iommu_is_dma_domain(domain))
|
||||
|
@ -1171,6 +1172,16 @@ err_free_device:
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
int __acpi_rmrr_device_create_direct_mappings(struct iommu_domain *domain, struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iommu_create_device_direct_mappings(domain, dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__acpi_rmrr_device_create_direct_mappings);
|
||||
|
||||
/**
|
||||
* iommu_group_add_device - add a device to an iommu group
|
||||
* @group: the group into which to add the device (reference should be held)
|
||||
|
|
|
@ -112,6 +112,9 @@ extern int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
|
|||
void *start, void*end, u16 segment,
|
||||
struct dmar_dev_scope *devices,
|
||||
int devices_cnt);
|
||||
extern bool dmar_rmrr_acpi_insert_dev_scope(u8 device_number,
|
||||
struct acpi_device *adev, void *start, void *end,
|
||||
struct dmar_dev_scope *devices, int devices_cnt);
|
||||
extern int dmar_remove_dev_scope(struct dmar_pci_notify_info *info,
|
||||
u16 segment, struct dmar_dev_scope *devices,
|
||||
int count);
|
||||
|
@ -144,6 +147,7 @@ extern int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg);
|
|||
extern int dmar_parse_one_satc(struct acpi_dmar_header *hdr, void *arg);
|
||||
extern int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg);
|
||||
extern int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert);
|
||||
extern int dmar_rmrr_add_acpi_dev(u8 device_number, struct acpi_device *adev);
|
||||
extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info);
|
||||
#else /* !CONFIG_INTEL_IOMMU: */
|
||||
static inline int intel_iommu_init(void) { return -ENODEV; }
|
||||
|
@ -155,6 +159,11 @@ static inline void intel_iommu_shutdown(void) { }
|
|||
#define dmar_release_one_atsr dmar_res_noop
|
||||
#define dmar_parse_one_satc dmar_res_noop
|
||||
|
||||
static inline int dmar_rmrr_add_acpi_dev(u8 device_number, struct acpi_device *adev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -586,6 +586,21 @@ void iommu_set_dma_strict(void);
|
|||
extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
|
||||
unsigned long iova, int flags);
|
||||
|
||||
static inline bool apply_zhaoxin_dmar_acpi_a_behavior(void)
|
||||
{
|
||||
#if defined(CONFIG_CPU_SUP_ZHAOXIN) || defined(CONFIG_CPU_SUP_CENTAUR)
|
||||
if (((boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) ||
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN)) &&
|
||||
((boot_cpu_data.x86 == 7) && (boot_cpu_data.x86_model == 0x3b)))
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
extern int iova_reserve_domain_addr(struct iommu_domain *domain, dma_addr_t start, dma_addr_t end);
|
||||
|
||||
int __acpi_rmrr_device_create_direct_mappings(struct iommu_domain *domain, struct device *dev);
|
||||
|
||||
static inline void iommu_flush_iotlb_all(struct iommu_domain *domain)
|
||||
{
|
||||
if (domain->ops->flush_iotlb_all)
|
||||
|
|
Loading…
Reference in New Issue