Right now we're casting away const-ness, to initialize the individual elements despite the field(s) being declared const. Eclair validly recognizes this as a Misra rule 11.8 violation. Hide this by switching to the use of memcpy(), deriving the destination address from the (mutable) struct pci_dev * which we hold in hands.
No functional change intended. Signed-off-by: Jan Beulich <[email protected]> --- Subsequently we may want to further leverage the sbdf local variable we now have in the function. Yet of course the primary question is: Is this an okay game to play in the first place? --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -318,6 +318,7 @@ static void apply_quirks(struct pci_dev static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn) { struct pci_dev *pdev; + pci_sbdf_t sbdf = { .seg = pseg->nr, .bus = bus, .devfn = devfn }; unsigned int pos; int rc; @@ -329,9 +330,15 @@ static struct pci_dev *alloc_pdev(struct if ( !pdev ) return NULL; - *(u16*) &pdev->seg = pseg->nr; - *((u8*) &pdev->bus) = bus; - *((u8*) &pdev->devfn) = devfn; + /* + * pdev->sbdf is deliberately const, i.e. it can't be written by structure + * or field assignment. Writing by memcpy() works, as long as it's not + * &pdev->sbdf which is passed. Since memcpy() isn't type-safe, have an + * explicit type check first. + */ + (void)(&pdev->sbdf != &sbdf); + memcpy((void *)pdev + offsetof(struct pci_dev, sbdf), &sbdf, sizeof(sbdf)); + pdev->domain = NULL; INIT_LIST_HEAD(&pdev->vf_list); @@ -390,7 +397,6 @@ static struct pci_dev *alloc_pdev(struct phantom_devs[i].slot == PCI_SLOT(devfn) && phantom_devs[i].stride > PCI_FUNC(devfn) ) { - pci_sbdf_t sbdf = pdev->sbdf; unsigned int stride = phantom_devs[i].stride; while ( (sbdf.fn += stride) > PCI_FUNC(devfn) )
