Skip to content

Commit dce3ab4

Browse files
committed
Merge tag 'for-linus-6.15-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross: - cleanup: remove an used function - add support for a XenServer specific virtual PCI device - fix the handling of a sparse Xen hypervisor symbol table - avoid warnings when building the kernel with gcc 15 - fix use of devices behind a VMD bridge when running as a Xen PV dom0 * tag 'for-linus-6.15-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag PCI: vmd: Disable MSI remapping bypass under Xen xen/pci: Do not register devices with segments >= 0x10000 xen/pciback: Remove unused pcistub_get_pci_dev xenfs/xensyms: respect hypervisor's "next" indication xen/mcelog: Add __nonstring annotations for unterminated strings xen: Add support for XenServer 6.1 platform device
2 parents edb0e8f + c3164d2 commit dce3ab4

File tree

11 files changed

+85
-49
lines changed

11 files changed

+85
-49
lines changed

arch/x86/pci/xen.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,8 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = {
436436
};
437437

438438
static struct msi_domain_info xen_pci_msi_domain_info = {
439-
.flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
439+
.flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS |
440+
MSI_FLAG_DEV_SYSFS | MSI_FLAG_NO_MASK,
440441
.ops = &xen_pci_msi_domain_ops,
441442
};
442443

@@ -484,11 +485,6 @@ static __init void xen_setup_pci_msi(void)
484485
* in allocating the native domain and never use it.
485486
*/
486487
x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain;
487-
/*
488-
* With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely
489-
* controlled by the hypervisor.
490-
*/
491-
pci_msi_ignore_mask = 1;
492488
}
493489

494490
#else /* CONFIG_PCI_MSI */

drivers/pci/controller/vmd.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <linux/rculist.h>
1818
#include <linux/rcupdate.h>
1919

20+
#include <xen/xen.h>
21+
2022
#include <asm/irqdomain.h>
2123

2224
#define VMD_CFGBAR 0
@@ -970,6 +972,24 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
970972
struct vmd_dev *vmd;
971973
int err;
972974

975+
if (xen_domain()) {
976+
/*
977+
* Xen doesn't have knowledge about devices in the VMD bus
978+
* because the config space of devices behind the VMD bridge is
979+
* not known to Xen, and hence Xen cannot discover or configure
980+
* them in any way.
981+
*
982+
* Bypass of MSI remapping won't work in that case as direct
983+
* write by Linux to the MSI entries won't result in functional
984+
* interrupts, as Xen is the entity that manages the host
985+
* interrupt controller and must configure interrupts. However
986+
* multiplexing of interrupts by the VMD bridge will work under
987+
* Xen, so force the usage of that mode which must always be
988+
* supported by VMD bridges.
989+
*/
990+
features &= ~VMD_FEAT_CAN_BYPASS_MSI_REMAP;
991+
}
992+
973993
if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20))
974994
return -ENOMEM;
975995

drivers/pci/msi/msi.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
#include <linux/err.h>
1111
#include <linux/export.h>
1212
#include <linux/irq.h>
13+
#include <linux/irqdomain.h>
1314

1415
#include "../pci.h"
1516
#include "msi.h"
1617

1718
int pci_msi_enable = 1;
18-
int pci_msi_ignore_mask;
1919

2020
/**
2121
* pci_msi_supported - check whether MSI may be enabled on a device
@@ -285,6 +285,8 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
285285
static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
286286
struct irq_affinity_desc *masks)
287287
{
288+
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
289+
const struct msi_domain_info *info = d->host_data;
288290
struct msi_desc desc;
289291
u16 control;
290292

@@ -295,8 +297,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
295297
/* Lies, damned lies, and MSIs */
296298
if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
297299
control |= PCI_MSI_FLAGS_MASKBIT;
298-
/* Respect XEN's mask disabling */
299-
if (pci_msi_ignore_mask)
300+
if (info->flags & MSI_FLAG_NO_MASK)
300301
control &= ~PCI_MSI_FLAGS_MASKBIT;
301302

302303
desc.nvec_used = nvec;
@@ -603,12 +604,15 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
603604
*/
604605
void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
605606
{
607+
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
608+
const struct msi_domain_info *info = d->host_data;
609+
606610
desc->nvec_used = 1;
607611
desc->pci.msi_attrib.is_msix = 1;
608612
desc->pci.msi_attrib.is_64 = 1;
609613
desc->pci.msi_attrib.default_irq = dev->irq;
610614
desc->pci.mask_base = dev->msix_base;
611-
desc->pci.msi_attrib.can_mask = !pci_msi_ignore_mask &&
615+
desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) &&
612616
!desc->pci.msi_attrib.is_virtual;
613617

614618
if (desc->pci.msi_attrib.can_mask) {
@@ -658,9 +662,6 @@ static void msix_mask_all(void __iomem *base, int tsize)
658662
u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT;
659663
int i;
660664

661-
if (pci_msi_ignore_mask)
662-
return;
663-
664665
for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE)
665666
writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL);
666667
}
@@ -714,6 +715,8 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
714715
static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
715716
int nvec, struct irq_affinity *affd)
716717
{
718+
const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
719+
const struct msi_domain_info *info = d->host_data;
717720
int ret, tsize;
718721
u16 control;
719722

@@ -744,15 +747,17 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
744747
/* Disable INTX */
745748
pci_intx_for_msi(dev, 0);
746749

747-
/*
748-
* Ensure that all table entries are masked to prevent
749-
* stale entries from firing in a crash kernel.
750-
*
751-
* Done late to deal with a broken Marvell NVME device
752-
* which takes the MSI-X mask bits into account even
753-
* when MSI-X is disabled, which prevents MSI delivery.
754-
*/
755-
msix_mask_all(dev->msix_base, tsize);
750+
if (!(info->flags & MSI_FLAG_NO_MASK)) {
751+
/*
752+
* Ensure that all table entries are masked to prevent
753+
* stale entries from firing in a crash kernel.
754+
*
755+
* Done late to deal with a broken Marvell NVME device
756+
* which takes the MSI-X mask bits into account even
757+
* when MSI-X is disabled, which prevents MSI delivery.
758+
*/
759+
msix_mask_all(dev->msix_base, tsize);
760+
}
756761
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
757762

758763
pcibios_free_irq(dev);

drivers/xen/pci.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ static int xen_add_device(struct device *dev)
4343
pci_mcfg_reserved = true;
4444
}
4545
#endif
46+
47+
if (pci_domain_nr(pci_dev->bus) >> 16) {
48+
/*
49+
* The hypercall interface is limited to 16bit PCI segment
50+
* values, do not attempt to register devices with Xen in
51+
* segments greater or equal than 0x10000.
52+
*/
53+
dev_info(dev,
54+
"not registering with Xen: invalid PCI segment\n");
55+
return 0;
56+
}
57+
4658
if (pci_seg_supported) {
4759
DEFINE_RAW_FLEX(struct physdev_pci_device_add, add, optarr, 1);
4860

@@ -149,6 +161,16 @@ static int xen_remove_device(struct device *dev)
149161
int r;
150162
struct pci_dev *pci_dev = to_pci_dev(dev);
151163

164+
if (pci_domain_nr(pci_dev->bus) >> 16) {
165+
/*
166+
* The hypercall interface is limited to 16bit PCI segment
167+
* values.
168+
*/
169+
dev_info(dev,
170+
"not unregistering with Xen: invalid PCI segment\n");
171+
return 0;
172+
}
173+
152174
if (pci_seg_supported) {
153175
struct physdev_pci_device device = {
154176
.seg = pci_domain_nr(pci_dev->bus),
@@ -182,6 +204,16 @@ int xen_reset_device(const struct pci_dev *dev)
182204
.flags = PCI_DEVICE_RESET_FLR,
183205
};
184206

207+
if (pci_domain_nr(dev->bus) >> 16) {
208+
/*
209+
* The hypercall interface is limited to 16bit PCI segment
210+
* values.
211+
*/
212+
dev_info(&dev->dev,
213+
"unable to notify Xen of device reset: invalid PCI segment\n");
214+
return 0;
215+
}
216+
185217
return HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_reset, &device);
186218
}
187219
EXPORT_SYMBOL_GPL(xen_reset_device);

drivers/xen/platform-pci.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#define DRV_NAME "xen-platform-pci"
2828

29+
#define PCI_DEVICE_ID_XEN_PLATFORM_XS61 0x0002
30+
2931
static unsigned long platform_mmio;
3032
static unsigned long platform_mmio_alloc;
3133
static unsigned long platform_mmiolen;
@@ -174,6 +176,8 @@ static int platform_pci_probe(struct pci_dev *pdev,
174176
static const struct pci_device_id platform_pci_tbl[] = {
175177
{PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM,
176178
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
179+
{PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM_XS61,
180+
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
177181
{0,}
178182
};
179183

drivers/xen/xen-pciback/pci_stub.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -262,26 +262,6 @@ struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
262262
return found_dev;
263263
}
264264

265-
struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
266-
struct pci_dev *dev)
267-
{
268-
struct pcistub_device *psdev;
269-
struct pci_dev *found_dev = NULL;
270-
unsigned long flags;
271-
272-
spin_lock_irqsave(&pcistub_devices_lock, flags);
273-
274-
list_for_each_entry(psdev, &pcistub_devices, dev_list) {
275-
if (psdev->dev == dev) {
276-
found_dev = pcistub_device_get_pci_dev(pdev, psdev);
277-
break;
278-
}
279-
}
280-
281-
spin_unlock_irqrestore(&pcistub_devices_lock, flags);
282-
return found_dev;
283-
}
284-
285265
/*
286266
* Called when:
287267
* - XenBus state has been reconfigure (pci unplug). See xen_pcibk_remove_device

drivers/xen/xen-pciback/pciback.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ extern struct list_head xen_pcibk_quirks;
6767
struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
6868
int domain, int bus,
6969
int slot, int func);
70-
struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
71-
struct pci_dev *dev);
7270
void pcistub_put_pci_dev(struct pci_dev *dev);
7371

7472
static inline bool xen_pcibk_pv_support(void)

drivers/xen/xenfs/xensyms.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int xensyms_next_sym(struct xensyms *xs)
4848
return -ENOMEM;
4949

5050
set_xen_guest_handle(symdata->name, xs->name);
51-
symdata->symnum--; /* Rewind */
51+
symdata->symnum = symnum; /* Rewind */
5252

5353
ret = HYPERVISOR_platform_op(&xs->op);
5454
if (ret < 0)
@@ -78,7 +78,7 @@ static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
7878
{
7979
struct xensyms *xs = m->private;
8080

81-
xs->op.u.symdata.symnum = ++(*pos);
81+
*pos = xs->op.u.symdata.symnum;
8282

8383
if (xensyms_next_sym(xs))
8484
return NULL;

include/linux/msi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ struct msi_msg {
7373
};
7474
};
7575

76-
extern int pci_msi_ignore_mask;
7776
/* Helper functions */
7877
struct msi_desc;
7978
struct pci_dev;
@@ -558,6 +557,8 @@ enum {
558557
MSI_FLAG_PCI_MSIX_ALLOC_DYN = (1 << 20),
559558
/* PCI MSIs cannot be steered separately to CPU cores */
560559
MSI_FLAG_NO_AFFINITY = (1 << 21),
560+
/* Inhibit usage of entry masking */
561+
MSI_FLAG_NO_MASK = (1 << 22),
561562
};
562563

563564
/*

include/xen/interface/xen-mca.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ struct xen_mce {
372372
#define XEN_MCE_LOG_LEN 32
373373

374374
struct xen_mce_log {
375-
char signature[12]; /* "MACHINECHECK" */
375+
char signature[12] __nonstring; /* "MACHINECHECK" */
376376
unsigned len; /* = XEN_MCE_LOG_LEN */
377377
unsigned next;
378378
unsigned flags;

0 commit comments

Comments
 (0)