Skip to content

Commit f66e3d6

Browse files
committed
IOMMU/x86: switch to alternatives-call patching in further instances
This is, once again, to limit the number of indirect calls as much as possible. The only hook invocation which isn't sensible to convert is setup(). And of course Arm-only use sites are left alone as well. Note regarding the introduction / use of local variables in pci.c: struct pci_dev's involved fields are const. This const propagates, via typeof(), to the local helper variables in the altcall macros. These helper variables are, however, used as outputs (and hence can't be const). In iommu_get_device_group() make use of the new local variables to also simplify some adjacent code. Signed-off-by: Jan Beulich <[email protected]> Reviewed-by: Paul Durrant <[email protected]> Reviewed-by: Rahul Singh <[email protected]> Tested-by: Rahul Singh <[email protected]>
1 parent c5539e6 commit f66e3d6

File tree

3 files changed

+32
-27
lines changed

3 files changed

+32
-27
lines changed

xen/drivers/passthrough/iommu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ int iommu_domain_init(struct domain *d, unsigned int opts)
198198
return ret;
199199

200200
hd->platform_ops = iommu_get_ops();
201-
ret = hd->platform_ops->init(d);
201+
ret = iommu_call(hd->platform_ops, init, d);
202202
if ( ret || is_system_domain(d) )
203203
return ret;
204204

@@ -233,7 +233,7 @@ void __hwdom_init iommu_hwdom_init(struct domain *d)
233233

234234
register_keyhandler('o', &iommu_dump_page_tables, "dump iommu page tables", 0);
235235

236-
hd->platform_ops->hwdom_init(d);
236+
iommu_vcall(hd->platform_ops, hwdom_init, d);
237237
}
238238

239239
static void iommu_teardown(struct domain *d)
@@ -576,7 +576,7 @@ int iommu_get_reserved_device_memory(iommu_grdm_t *func, void *ctxt)
576576
if ( !ops->get_reserved_device_memory )
577577
return 0;
578578

579-
return ops->get_reserved_device_memory(func, ctxt);
579+
return iommu_call(ops, get_reserved_device_memory, func, ctxt);
580580
}
581581

582582
bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature)
@@ -603,7 +603,7 @@ static void iommu_dump_page_tables(unsigned char key)
603603
continue;
604604
}
605605

606-
dom_iommu(d)->platform_ops->dump_page_tables(d);
606+
iommu_vcall(dom_iommu(d)->platform_ops, dump_page_tables, d);
607607
}
608608

609609
rcu_read_unlock(&domlist_read_lock);

xen/drivers/passthrough/pci.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -861,15 +861,15 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
861861
devfn += pdev->phantom_stride;
862862
if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
863863
break;
864-
ret = hd->platform_ops->reassign_device(d, target, devfn,
865-
pci_to_dev(pdev));
864+
ret = iommu_call(hd->platform_ops, reassign_device, d, target, devfn,
865+
pci_to_dev(pdev));
866866
if ( ret )
867867
goto out;
868868
}
869869

870870
devfn = pdev->devfn;
871-
ret = hd->platform_ops->reassign_device(d, target, devfn,
872-
pci_to_dev(pdev));
871+
ret = iommu_call(hd->platform_ops, reassign_device, d, target, devfn,
872+
pci_to_dev(pdev));
873873
if ( ret )
874874
goto out;
875875

@@ -1300,7 +1300,7 @@ static int iommu_add_device(struct pci_dev *pdev)
13001300
{
13011301
const struct domain_iommu *hd;
13021302
int rc;
1303-
u8 devfn;
1303+
unsigned int devfn = pdev->devfn;
13041304

13051305
if ( !pdev->domain )
13061306
return -EINVAL;
@@ -1311,16 +1311,16 @@ static int iommu_add_device(struct pci_dev *pdev)
13111311
if ( !is_iommu_enabled(pdev->domain) )
13121312
return 0;
13131313

1314-
rc = hd->platform_ops->add_device(pdev->devfn, pci_to_dev(pdev));
1314+
rc = iommu_call(hd->platform_ops, add_device, devfn, pci_to_dev(pdev));
13151315
if ( rc || !pdev->phantom_stride )
13161316
return rc;
13171317

1318-
for ( devfn = pdev->devfn ; ; )
1318+
for ( ; ; )
13191319
{
13201320
devfn += pdev->phantom_stride;
13211321
if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
13221322
return 0;
1323-
rc = hd->platform_ops->add_device(devfn, pci_to_dev(pdev));
1323+
rc = iommu_call(hd->platform_ops, add_device, devfn, pci_to_dev(pdev));
13241324
if ( rc )
13251325
printk(XENLOG_WARNING "IOMMU: add %pp failed (%d)\n",
13261326
&pdev->sbdf, rc);
@@ -1341,7 +1341,7 @@ static int iommu_enable_device(struct pci_dev *pdev)
13411341
!hd->platform_ops->enable_device )
13421342
return 0;
13431343

1344-
return hd->platform_ops->enable_device(pci_to_dev(pdev));
1344+
return iommu_call(hd->platform_ops, enable_device, pci_to_dev(pdev));
13451345
}
13461346

13471347
static int iommu_remove_device(struct pci_dev *pdev)
@@ -1363,15 +1363,18 @@ static int iommu_remove_device(struct pci_dev *pdev)
13631363
devfn += pdev->phantom_stride;
13641364
if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
13651365
break;
1366-
rc = hd->platform_ops->remove_device(devfn, pci_to_dev(pdev));
1366+
rc = iommu_call(hd->platform_ops, remove_device, devfn,
1367+
pci_to_dev(pdev));
13671368
if ( !rc )
13681369
continue;
13691370

13701371
printk(XENLOG_ERR "IOMMU: remove %pp failed (%d)\n", &pdev->sbdf, rc);
13711372
return rc;
13721373
}
13731374

1374-
return hd->platform_ops->remove_device(pdev->devfn, pci_to_dev(pdev));
1375+
devfn = pdev->devfn;
1376+
1377+
return iommu_call(hd->platform_ops, remove_device, devfn, pci_to_dev(pdev));
13751378
}
13761379

13771380
static int device_assigned(u16 seg, u8 bus, u8 devfn)
@@ -1421,15 +1424,17 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
14211424

14221425
pdev->fault.count = 0;
14231426

1424-
if ( (rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag)) )
1427+
if ( (rc = iommu_call(hd->platform_ops, assign_device, d, devfn,
1428+
pci_to_dev(pdev), flag)) )
14251429
goto done;
14261430

14271431
for ( ; pdev->phantom_stride; rc = 0 )
14281432
{
14291433
devfn += pdev->phantom_stride;
14301434
if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
14311435
break;
1432-
rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag);
1436+
rc = iommu_call(hd->platform_ops, assign_device, d, devfn,
1437+
pci_to_dev(pdev), flag);
14331438
}
14341439

14351440
done:
@@ -1457,24 +1462,24 @@ static int iommu_get_device_group(
14571462
if ( !is_iommu_enabled(d) || !ops->get_device_group_id )
14581463
return 0;
14591464

1460-
group_id = ops->get_device_group_id(seg, bus, devfn);
1465+
group_id = iommu_call(ops, get_device_group_id, seg, bus, devfn);
14611466

14621467
pcidevs_lock();
14631468
for_each_pdev( d, pdev )
14641469
{
1465-
if ( (pdev->seg != seg) ||
1466-
((pdev->bus == bus) && (pdev->devfn == devfn)) )
1470+
unsigned int b = pdev->bus;
1471+
unsigned int df = pdev->devfn;
1472+
1473+
if ( (pdev->seg != seg) || ((b == bus) && (df == devfn)) )
14671474
continue;
14681475

1469-
if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (pdev->bus << 8) | pdev->devfn) )
1476+
if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (b << 8) | df) )
14701477
continue;
14711478

1472-
sdev_id = ops->get_device_group_id(seg, pdev->bus, pdev->devfn);
1479+
sdev_id = iommu_call(ops, get_device_group_id, seg, b, df);
14731480
if ( (sdev_id == group_id) && (i < max_sdevs) )
14741481
{
1475-
bdf = 0;
1476-
bdf |= (pdev->bus & 0xff) << 16;
1477-
bdf |= (pdev->devfn & 0xff) << 8;
1482+
bdf = (b << 16) | (df << 8);
14781483

14791484
if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) )
14801485
{

xen/drivers/passthrough/x86/iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ unsigned int iommu_read_apic_from_ire(unsigned int apic, unsigned int reg)
145145
int __init iommu_setup_hpet_msi(struct msi_desc *msi)
146146
{
147147
const struct iommu_ops *ops = iommu_get_ops();
148-
return ops->setup_hpet_msi ? ops->setup_hpet_msi(msi) : -ENODEV;
148+
return ops->setup_hpet_msi ? iommu_call(ops, setup_hpet_msi, msi) : -ENODEV;
149149
}
150150

151151
void __hwdom_init arch_iommu_check_autotranslated_hwdom(struct domain *d)
@@ -406,7 +406,7 @@ int iommu_free_pgtables(struct domain *d)
406406
* Pages will be moved to the free list below. So we want to
407407
* clear the root page-table to avoid any potential use after-free.
408408
*/
409-
hd->platform_ops->clear_root_pgtable(d);
409+
iommu_vcall(hd->platform_ops, clear_root_pgtable, d);
410410

411411
while ( (pg = page_list_remove_head(&hd->arch.pgtables.list)) )
412412
{

0 commit comments

Comments
 (0)