Commit ca995ce4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-6.7-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross:

 - two small cleanup patches

 - a fix for PCI passthrough under Xen

 - a four patch series speeding up virtio under Xen with user space
   backends

* tag 'for-linus-6.7-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen-pciback: Consider INTx disabled when MSI/MSI-X is enabled
  xen: privcmd: Add support for ioeventfd
  xen: evtchn: Allow shared registration of IRQ handers
  xen: irqfd: Use _IOW instead of the internal _IOC() macro
  xen: Make struct privcmd_irqfd's layout architecture independent
  xen/xenbus: Add __counted_by for struct read_buffer and use struct_size()
  xenbus: fix error exit in xenbus_init()
parents 8999ad99 2c269f42
...@@ -269,12 +269,12 @@ config XEN_PRIVCMD ...@@ -269,12 +269,12 @@ config XEN_PRIVCMD
disaggregated Xen setups this driver might be needed for other disaggregated Xen setups this driver might be needed for other
domains, too. domains, too.
config XEN_PRIVCMD_IRQFD config XEN_PRIVCMD_EVENTFD
bool "Xen irqfd support" bool "Xen Ioeventfd and irqfd support"
depends on XEN_PRIVCMD && XEN_VIRTIO && EVENTFD depends on XEN_PRIVCMD && XEN_VIRTIO && EVENTFD
help help
Using the irqfd mechanism a virtio backend running in a daemon can Using the ioeventfd / irqfd mechanism a virtio backend running in a
speed up interrupt injection into a guest. daemon can speed up interrupt delivery from / to a guest.
config XEN_ACPI_PROCESSOR config XEN_ACPI_PROCESSOR
tristate "Xen ACPI processor" tristate "Xen ACPI processor"
......
...@@ -1229,7 +1229,8 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip, ...@@ -1229,7 +1229,8 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
bind_evtchn_to_cpu(evtchn, 0, false); bind_evtchn_to_cpu(evtchn, 0, false);
} else { } else {
struct irq_info *info = info_for_irq(irq); struct irq_info *info = info_for_irq(irq);
WARN_ON(info == NULL || info->type != IRQT_EVTCHN); if (!WARN_ON(!info || info->type != IRQT_EVTCHN))
info->refcnt++;
} }
out: out:
......
...@@ -397,7 +397,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, ...@@ -397,7 +397,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port,
if (rc < 0) if (rc < 0)
goto err; goto err;
rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, 0, rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, IRQF_SHARED,
u->name, evtchn); u->name, evtchn);
if (rc < 0) if (rc < 0)
goto err; goto err;
......
This diff is collapsed.
...@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) ...@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
u16 val; u16 val;
int ret = 0; int ret = 0;
err = pci_read_config_word(dev, PCI_COMMAND, &val);
if (err)
return err;
if (!(val & PCI_COMMAND_INTX_DISABLE))
ret |= INTERRUPT_TYPE_INTX;
/* /*
* Do not trust dev->msi(x)_enabled here, as enabling could be done * Do not trust dev->msi(x)_enabled here, as enabling could be done
* bypassing the pci_*msi* functions, by the qemu. * bypassing the pci_*msi* functions, by the qemu.
...@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) ...@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
if (val & PCI_MSIX_FLAGS_ENABLE) if (val & PCI_MSIX_FLAGS_ENABLE)
ret |= INTERRUPT_TYPE_MSIX; ret |= INTERRUPT_TYPE_MSIX;
} }
/*
* PCIe spec says device cannot use INTx if MSI/MSI-X is enabled,
* so check for INTx only when both are disabled.
*/
if (!ret) {
err = pci_read_config_word(dev, PCI_COMMAND, &val);
if (err)
return err;
if (!(val & PCI_COMMAND_INTX_DISABLE))
ret |= INTERRUPT_TYPE_INTX;
}
return ret ?: INTERRUPT_TYPE_NONE; return ret ?: INTERRUPT_TYPE_NONE;
} }
......
...@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value, ...@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;
if (new_value & field_config->enable_bit) { if (new_value & field_config->enable_bit) {
/* don't allow enabling together with other interrupt types */ /*
* Don't allow enabling together with other interrupt type, but do
* allow enabling MSI(-X) while INTx is still active to please Linuxes
* MSI(-X) startup sequence. It is safe to do, as according to PCI
* spec, device with enabled MSI(-X) shouldn't use INTx.
*/
int int_type = xen_pcibk_get_interrupt_type(dev); int int_type = xen_pcibk_get_interrupt_type(dev);
if (int_type == INTERRUPT_TYPE_NONE || if (int_type == INTERRUPT_TYPE_NONE ||
int_type == INTERRUPT_TYPE_INTX ||
int_type == field_config->int_type) int_type == field_config->int_type)
goto write; goto write;
return PCIBIOS_SET_FAILED; return PCIBIOS_SET_FAILED;
......
...@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) ...@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
pci_clear_mwi(dev); pci_clear_mwi(dev);
} }
if (dev_data && dev_data->allow_interrupt_control) { if (dev_data && dev_data->allow_interrupt_control &&
if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) { ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))
if (value & PCI_COMMAND_INTX_DISABLE) { pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));
pci_intx(dev, 0);
} else {
/* Do not allow enabling INTx together with MSI or MSI-X. */
switch (xen_pcibk_get_interrupt_type(dev)) {
case INTERRUPT_TYPE_NONE:
pci_intx(dev, 1);
break;
case INTERRUPT_TYPE_INTX:
break;
default:
return PCIBIOS_SET_FAILED;
}
}
}
}
cmd->val = value; cmd->val = value;
......
...@@ -82,7 +82,7 @@ struct read_buffer { ...@@ -82,7 +82,7 @@ struct read_buffer {
struct list_head list; struct list_head list;
unsigned int cons; unsigned int cons;
unsigned int len; unsigned int len;
char msg[]; char msg[] __counted_by(len);
}; };
struct xenbus_file_priv { struct xenbus_file_priv {
...@@ -195,7 +195,7 @@ static int queue_reply(struct list_head *queue, const void *data, size_t len) ...@@ -195,7 +195,7 @@ static int queue_reply(struct list_head *queue, const void *data, size_t len)
if (len > XENSTORE_PAYLOAD_MAX) if (len > XENSTORE_PAYLOAD_MAX)
return -EINVAL; return -EINVAL;
rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL); rb = kmalloc(struct_size(rb, msg, len), GFP_KERNEL);
if (rb == NULL) if (rb == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void) ...@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void)
if (err < 0) { if (err < 0) {
pr_err("xenstore_late_init couldn't bind irq err=%d\n", pr_err("xenstore_late_init couldn't bind irq err=%d\n",
err); err);
return err; goto out_error;
} }
xs_init_irq = err; xs_init_irq = err;
......
...@@ -102,7 +102,7 @@ struct privcmd_mmap_resource { ...@@ -102,7 +102,7 @@ struct privcmd_mmap_resource {
#define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0) #define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0)
struct privcmd_irqfd { struct privcmd_irqfd {
void __user *dm_op; __u64 dm_op;
__u32 size; /* Size of structure pointed by dm_op */ __u32 size; /* Size of structure pointed by dm_op */
__u32 fd; __u32 fd;
__u32 flags; __u32 flags;
...@@ -110,6 +110,22 @@ struct privcmd_irqfd { ...@@ -110,6 +110,22 @@ struct privcmd_irqfd {
__u8 pad[2]; __u8 pad[2];
}; };
/* For privcmd_ioeventfd::flags */
#define PRIVCMD_IOEVENTFD_FLAG_DEASSIGN (1 << 0)
struct privcmd_ioeventfd {
__u64 ioreq;
__u64 ports;
__u64 addr;
__u32 addr_len;
__u32 event_fd;
__u32 vcpus;
__u32 vq;
__u32 flags;
domid_t dom;
__u8 pad[2];
};
/* /*
* @cmd: IOCTL_PRIVCMD_HYPERCALL * @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t * @arg: &privcmd_hypercall_t
...@@ -138,6 +154,8 @@ struct privcmd_irqfd { ...@@ -138,6 +154,8 @@ struct privcmd_irqfd {
#define IOCTL_PRIVCMD_MMAP_RESOURCE \ #define IOCTL_PRIVCMD_MMAP_RESOURCE \
_IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource)) _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))
#define IOCTL_PRIVCMD_IRQFD \ #define IOCTL_PRIVCMD_IRQFD \
_IOC(_IOC_NONE, 'P', 8, sizeof(struct privcmd_irqfd)) _IOW('P', 8, struct privcmd_irqfd)
#define IOCTL_PRIVCMD_IOEVENTFD \
_IOW('P', 9, struct privcmd_ioeventfd)
#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */ #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
/* SPDX-License-Identifier: MIT */
/*
* ioreq.h: I/O request definitions for device models
* Copyright (c) 2004, Intel Corporation.
*/
#ifndef __XEN_PUBLIC_HVM_IOREQ_H__
#define __XEN_PUBLIC_HVM_IOREQ_H__
#define IOREQ_READ 1
#define IOREQ_WRITE 0
#define STATE_IOREQ_NONE 0
#define STATE_IOREQ_READY 1
#define STATE_IOREQ_INPROCESS 2
#define STATE_IORESP_READY 3
#define IOREQ_TYPE_PIO 0 /* pio */
#define IOREQ_TYPE_COPY 1 /* mmio ops */
#define IOREQ_TYPE_PCI_CONFIG 2
#define IOREQ_TYPE_TIMEOFFSET 7
#define IOREQ_TYPE_INVALIDATE 8 /* mapcache */
/*
* VMExit dispatcher should cooperate with instruction decoder to
* prepare this structure and notify service OS and DM by sending
* virq.
*
* For I/O type IOREQ_TYPE_PCI_CONFIG, the physical address is formatted
* as follows:
*
* 63....48|47..40|39..35|34..32|31........0
* SEGMENT |BUS |DEV |FN |OFFSET
*/
struct ioreq {
uint64_t addr; /* physical address */
uint64_t data; /* data (or paddr of data) */
uint32_t count; /* for rep prefixes */
uint32_t size; /* size in bytes */
uint32_t vp_eport; /* evtchn for notifications to/from device model */
uint16_t _pad0;
uint8_t state:4;
uint8_t data_is_ptr:1; /* if 1, data above is the guest paddr
* of the real data to use. */
uint8_t dir:1; /* 1=read, 0=write */
uint8_t df:1;
uint8_t _pad1:1;
uint8_t type; /* I/O type */
};
#endif /* __XEN_PUBLIC_HVM_IOREQ_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment