|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 13/14] passthrough/PCI: rework (s,b,d,f) init of struct pci_dev
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 <jbeulich@xxxxxxxx>
---
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) )
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |