Commit 5d6a0f4d authored by Linus Torvalds's avatar Linus Torvalds

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

Pull more xen updates from Juergen Gross:

 - fix the handling of the "persistent grants" feature negotiation
   between Xen blkfront and Xen blkback drivers

 - a cleanup of xen.config and adding xen.config to Xen section in
   MAINTAINERS

 - support HVMOP_set_evtchn_upcall_vector, which is more compliant to
   "normal" interrupt handling than the global callback used up to now

 - further small cleanups

* tag 'for-linus-6.0-rc1b-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  MAINTAINERS: add xen config fragments to XEN HYPERVISOR sections
  xen: remove XEN_SCRUB_PAGES in xen.config
  xen/pciback: Fix comment typo
  xen/xenbus: fix return type in xenbus_file_read()
  xen-blkfront: Apply 'feature_persistent' parameter when connect
  xen-blkback: Apply 'feature_persistent' parameter when connect
  xen-blkback: fix persistent grants negotiation
  x86/xen: Add support for HVMOP_set_evtchn_upcall_vector
parents 96f86ff0 5ad3134d
...@@ -42,5 +42,5 @@ KernelVersion: 5.10 ...@@ -42,5 +42,5 @@ KernelVersion: 5.10
Contact: Maximilian Heyne <mheyne@amazon.de> Contact: Maximilian Heyne <mheyne@amazon.de>
Description: Description:
Whether to enable the persistent grants feature or not. Note Whether to enable the persistent grants feature or not. Note
that this option only takes effect on newly created backends. that this option only takes effect on newly connected backends.
The default is Y (enable). The default is Y (enable).
...@@ -15,5 +15,5 @@ KernelVersion: 5.10 ...@@ -15,5 +15,5 @@ KernelVersion: 5.10
Contact: Maximilian Heyne <mheyne@amazon.de> Contact: Maximilian Heyne <mheyne@amazon.de>
Description: Description:
Whether to enable the persistent grants feature or not. Note Whether to enable the persistent grants feature or not. Note
that this option only takes effect on newly created frontends. that this option only takes effect on newly connected frontends.
The default is Y (enable). The default is Y (enable).
...@@ -22200,12 +22200,14 @@ F: drivers/*/xen-*front.c ...@@ -22200,12 +22200,14 @@ F: drivers/*/xen-*front.c
F: drivers/xen/ F: drivers/xen/
F: include/uapi/xen/ F: include/uapi/xen/
F: include/xen/ F: include/xen/
F: kernel/configs/xen.config
XEN HYPERVISOR X86 XEN HYPERVISOR X86
M: Juergen Gross <jgross@suse.com> M: Juergen Gross <jgross@suse.com>
R: Boris Ostrovsky <boris.ostrovsky@oracle.com> R: Boris Ostrovsky <boris.ostrovsky@oracle.com>
L: xen-devel@lists.xenproject.org (moderated for non-subscribers) L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
S: Supported S: Supported
F: arch/x86/configs/xen.config
F: arch/x86/include/asm/pvclock-abi.h F: arch/x86/include/asm/pvclock-abi.h
F: arch/x86/include/asm/xen/ F: arch/x86/include/asm/xen/
F: arch/x86/platform/pvh/ F: arch/x86/platform/pvh/
......
...@@ -107,6 +107,8 @@ ...@@ -107,6 +107,8 @@
* ID field from 8 to 15 bits, allowing to target APIC IDs up 32768. * ID field from 8 to 15 bits, allowing to target APIC IDs up 32768.
*/ */
#define XEN_HVM_CPUID_EXT_DEST_ID (1u << 5) #define XEN_HVM_CPUID_EXT_DEST_ID (1u << 5)
/* Per-vCPU event channel upcalls */
#define XEN_HVM_CPUID_UPCALL_VECTOR (1u << 6)
/* /*
* Leaf 6 (0x40000x05) * Leaf 6 (0x40000x05)
......
...@@ -23,7 +23,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) ...@@ -23,7 +23,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
/* No need for a barrier -- XCHG is a barrier on x86. */ /* No need for a barrier -- XCHG is a barrier on x86. */
#define xchg_xen_ulong(ptr, val) xchg((ptr), (val)) #define xchg_xen_ulong(ptr, val) xchg((ptr), (val))
extern int xen_have_vector_callback; extern bool xen_have_vector_callback;
/* /*
* Events delivered via platform PCI interrupts are always * Events delivered via platform PCI interrupts are always
...@@ -34,4 +34,5 @@ static inline bool xen_support_evtchn_rebind(void) ...@@ -34,4 +34,5 @@ static inline bool xen_support_evtchn_rebind(void)
return (!xen_hvm_domain() || xen_have_vector_callback); return (!xen_hvm_domain() || xen_have_vector_callback);
} }
extern bool xen_percpu_upcall;
#endif /* _ASM_X86_XEN_EVENTS_H */ #endif /* _ASM_X86_XEN_EVENTS_H */
...@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(xen_start_info); ...@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(xen_start_info);
struct shared_info xen_dummy_shared_info; struct shared_info xen_dummy_shared_info;
__read_mostly int xen_have_vector_callback; __read_mostly bool xen_have_vector_callback = true;
EXPORT_SYMBOL_GPL(xen_have_vector_callback); EXPORT_SYMBOL_GPL(xen_have_vector_callback);
/* /*
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <xen/features.h> #include <xen/features.h>
#include <xen/events.h> #include <xen/events.h>
#include <xen/hvm.h>
#include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/memory.h> #include <xen/interface/memory.h>
#include <asm/apic.h> #include <asm/apic.h>
...@@ -31,6 +33,9 @@ ...@@ -31,6 +33,9 @@
static unsigned long shared_info_pfn; static unsigned long shared_info_pfn;
__ro_after_init bool xen_percpu_upcall;
EXPORT_SYMBOL_GPL(xen_percpu_upcall);
void xen_hvm_init_shared_info(void) void xen_hvm_init_shared_info(void)
{ {
struct xen_add_to_physmap xatp; struct xen_add_to_physmap xatp;
...@@ -126,6 +131,9 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback) ...@@ -126,6 +131,9 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
if (xen_percpu_upcall)
ack_APIC_irq();
inc_irq_stat(irq_hv_callback_count); inc_irq_stat(irq_hv_callback_count);
xen_hvm_evtchn_do_upcall(); xen_hvm_evtchn_do_upcall();
...@@ -169,6 +177,15 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) ...@@ -169,6 +177,15 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu)
if (!xen_have_vector_callback) if (!xen_have_vector_callback)
return 0; return 0;
if (xen_percpu_upcall) {
rc = xen_set_upcall_vector(cpu);
if (rc) {
WARN(1, "HVMOP_set_evtchn_upcall_vector"
" for CPU %d failed: %d\n", cpu, rc);
return rc;
}
}
if (xen_feature(XENFEAT_hvm_safe_pvclock)) if (xen_feature(XENFEAT_hvm_safe_pvclock))
xen_setup_timer(cpu); xen_setup_timer(cpu);
...@@ -189,8 +206,6 @@ static int xen_cpu_dead_hvm(unsigned int cpu) ...@@ -189,8 +206,6 @@ static int xen_cpu_dead_hvm(unsigned int cpu)
return 0; return 0;
} }
static bool no_vector_callback __initdata;
static void __init xen_hvm_guest_init(void) static void __init xen_hvm_guest_init(void)
{ {
if (xen_pv_domain()) if (xen_pv_domain())
...@@ -213,9 +228,6 @@ static void __init xen_hvm_guest_init(void) ...@@ -213,9 +228,6 @@ static void __init xen_hvm_guest_init(void)
xen_panic_handler_init(); xen_panic_handler_init();
if (!no_vector_callback && xen_feature(XENFEAT_hvm_callback_vector))
xen_have_vector_callback = 1;
xen_hvm_smp_init(); xen_hvm_smp_init();
WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm)); WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm));
xen_unplug_emulated_devices(); xen_unplug_emulated_devices();
...@@ -241,7 +253,7 @@ early_param("xen_nopv", xen_parse_nopv); ...@@ -241,7 +253,7 @@ early_param("xen_nopv", xen_parse_nopv);
static __init int xen_parse_no_vector_callback(char *arg) static __init int xen_parse_no_vector_callback(char *arg)
{ {
no_vector_callback = true; xen_have_vector_callback = false;
return 0; return 0;
} }
early_param("xen_no_vector_callback", xen_parse_no_vector_callback); early_param("xen_no_vector_callback", xen_parse_no_vector_callback);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <xen/hvm.h> #include <xen/hvm.h>
#include <xen/features.h> #include <xen/features.h>
#include <xen/interface/features.h> #include <xen/interface/features.h>
#include <xen/events.h>
#include "xen-ops.h" #include "xen-ops.h"
...@@ -14,6 +15,13 @@ void xen_hvm_post_suspend(int suspend_cancelled) ...@@ -14,6 +15,13 @@ void xen_hvm_post_suspend(int suspend_cancelled)
xen_hvm_init_shared_info(); xen_hvm_init_shared_info();
xen_vcpu_restore(); xen_vcpu_restore();
} }
xen_setup_callback_vector(); if (xen_percpu_upcall) {
unsigned int cpu;
for_each_online_cpu(cpu)
BUG_ON(xen_set_upcall_vector(cpu));
} else {
xen_setup_callback_vector();
}
xen_unplug_emulated_devices(); xen_unplug_emulated_devices();
} }
...@@ -157,6 +157,11 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) ...@@ -157,6 +157,11 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
return 0; return 0;
} }
/* Enable the persistent grants feature. */
static bool feature_persistent = true;
module_param(feature_persistent, bool, 0644);
MODULE_PARM_DESC(feature_persistent, "Enables the persistent grants feature");
static struct xen_blkif *xen_blkif_alloc(domid_t domid) static struct xen_blkif *xen_blkif_alloc(domid_t domid)
{ {
struct xen_blkif *blkif; struct xen_blkif *blkif;
...@@ -472,12 +477,6 @@ static void xen_vbd_free(struct xen_vbd *vbd) ...@@ -472,12 +477,6 @@ static void xen_vbd_free(struct xen_vbd *vbd)
vbd->bdev = NULL; vbd->bdev = NULL;
} }
/* Enable the persistent grants feature. */
static bool feature_persistent = true;
module_param(feature_persistent, bool, 0644);
MODULE_PARM_DESC(feature_persistent,
"Enables the persistent grants feature");
static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
unsigned major, unsigned minor, int readonly, unsigned major, unsigned minor, int readonly,
int cdrom) int cdrom)
...@@ -520,8 +519,6 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, ...@@ -520,8 +519,6 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
if (bdev_max_secure_erase_sectors(bdev)) if (bdev_max_secure_erase_sectors(bdev))
vbd->discard_secure = true; vbd->discard_secure = true;
vbd->feature_gnt_persistent = feature_persistent;
pr_debug("Successful creation of handle=%04x (dom=%u)\n", pr_debug("Successful creation of handle=%04x (dom=%u)\n",
handle, blkif->domid); handle, blkif->domid);
return 0; return 0;
...@@ -1087,10 +1084,9 @@ static int connect_ring(struct backend_info *be) ...@@ -1087,10 +1084,9 @@ static int connect_ring(struct backend_info *be)
xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
return -ENOSYS; return -ENOSYS;
} }
if (blkif->vbd.feature_gnt_persistent)
blkif->vbd.feature_gnt_persistent = blkif->vbd.feature_gnt_persistent = feature_persistent &&
xenbus_read_unsigned(dev->otherend, xenbus_read_unsigned(dev->otherend, "feature-persistent", 0);
"feature-persistent", 0);
blkif->vbd.overflow_max_grants = 0; blkif->vbd.overflow_max_grants = 0;
......
...@@ -1988,8 +1988,6 @@ static int blkfront_probe(struct xenbus_device *dev, ...@@ -1988,8 +1988,6 @@ static int blkfront_probe(struct xenbus_device *dev,
info->vdevice = vdevice; info->vdevice = vdevice;
info->connected = BLKIF_STATE_DISCONNECTED; info->connected = BLKIF_STATE_DISCONNECTED;
info->feature_persistent = feature_persistent;
/* Front end dir is a number, which is used as the id. */ /* Front end dir is a number, which is used as the id. */
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
dev_set_drvdata(&dev->dev, info); dev_set_drvdata(&dev->dev, info);
...@@ -2283,7 +2281,7 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) ...@@ -2283,7 +2281,7 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0)) if (xenbus_read_unsigned(info->xbdev->otherend, "feature-discard", 0))
blkfront_setup_discard(info); blkfront_setup_discard(info);
if (info->feature_persistent) if (feature_persistent)
info->feature_persistent = info->feature_persistent =
!!xenbus_read_unsigned(info->xbdev->otherend, !!xenbus_read_unsigned(info->xbdev->otherend,
"feature-persistent", 0); "feature-persistent", 0);
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/i8259.h> #include <asm/i8259.h>
#include <asm/xen/cpuid.h>
#include <asm/xen/pci.h> #include <asm/xen/pci.h>
#endif #endif
#include <asm/sync_bitops.h> #include <asm/sync_bitops.h>
...@@ -2184,6 +2185,7 @@ static struct irq_chip xen_percpu_chip __read_mostly = { ...@@ -2184,6 +2185,7 @@ static struct irq_chip xen_percpu_chip __read_mostly = {
.irq_ack = ack_dynirq, .irq_ack = ack_dynirq,
}; };
#ifdef CONFIG_X86
#ifdef CONFIG_XEN_PVHVM #ifdef CONFIG_XEN_PVHVM
/* Vector callbacks are better than PCI interrupts to receive event /* Vector callbacks are better than PCI interrupts to receive event
* channel notifications because we can receive vector callbacks on any * channel notifications because we can receive vector callbacks on any
...@@ -2196,11 +2198,48 @@ void xen_setup_callback_vector(void) ...@@ -2196,11 +2198,48 @@ void xen_setup_callback_vector(void)
callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR); callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR);
if (xen_set_callback_via(callback_via)) { if (xen_set_callback_via(callback_via)) {
pr_err("Request for Xen HVM callback vector failed\n"); pr_err("Request for Xen HVM callback vector failed\n");
xen_have_vector_callback = 0; xen_have_vector_callback = false;
} }
} }
} }
/*
* Setup per-vCPU vector-type callbacks. If this setup is unavailable,
* fallback to the global vector-type callback.
*/
static __init void xen_init_setup_upcall_vector(void)
{
if (!xen_have_vector_callback)
return;
if ((cpuid_eax(xen_cpuid_base() + 4) & XEN_HVM_CPUID_UPCALL_VECTOR) &&
!xen_set_upcall_vector(0))
xen_percpu_upcall = true;
else if (xen_feature(XENFEAT_hvm_callback_vector))
xen_setup_callback_vector();
else
xen_have_vector_callback = false;
}
int xen_set_upcall_vector(unsigned int cpu)
{
int rc;
xen_hvm_evtchn_upcall_vector_t op = {
.vector = HYPERVISOR_CALLBACK_VECTOR,
.vcpu = per_cpu(xen_vcpu_id, cpu),
};
rc = HYPERVISOR_hvm_op(HVMOP_set_evtchn_upcall_vector, &op);
if (rc)
return rc;
/* Trick toolstack to think we are enlightened. */
if (!cpu)
rc = xen_set_callback_via(1);
return rc;
}
static __init void xen_alloc_callback_vector(void) static __init void xen_alloc_callback_vector(void)
{ {
if (!xen_have_vector_callback) if (!xen_have_vector_callback)
...@@ -2211,8 +2250,11 @@ static __init void xen_alloc_callback_vector(void) ...@@ -2211,8 +2250,11 @@ static __init void xen_alloc_callback_vector(void)
} }
#else #else
void xen_setup_callback_vector(void) {} void xen_setup_callback_vector(void) {}
static inline void xen_init_setup_upcall_vector(void) {}
int xen_set_upcall_vector(unsigned int cpu) {}
static inline void xen_alloc_callback_vector(void) {} static inline void xen_alloc_callback_vector(void) {}
#endif #endif /* CONFIG_XEN_PVHVM */
#endif /* CONFIG_X86 */
bool xen_fifo_events = true; bool xen_fifo_events = true;
module_param_named(fifo_events, xen_fifo_events, bool, 0); module_param_named(fifo_events, xen_fifo_events, bool, 0);
...@@ -2272,10 +2314,9 @@ void __init xen_init_IRQ(void) ...@@ -2272,10 +2314,9 @@ void __init xen_init_IRQ(void)
if (xen_initial_domain()) if (xen_initial_domain())
pci_xen_initial_domain(); pci_xen_initial_domain();
} }
if (xen_feature(XENFEAT_hvm_callback_vector)) { xen_init_setup_upcall_vector();
xen_setup_callback_vector(); xen_alloc_callback_vector();
xen_alloc_callback_vector();
}
if (xen_hvm_domain()) { if (xen_hvm_domain()) {
native_init_IRQ(); native_init_IRQ();
......
...@@ -159,7 +159,7 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, ...@@ -159,7 +159,7 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
return XEN_PCI_ERR_op_failed; return XEN_PCI_ERR_op_failed;
} }
/* The value the guest needs is actually the IDT vector, not the /* The value the guest needs is actually the IDT vector, not
* the local domain's IRQ number. */ * the local domain's IRQ number. */
op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0; op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
......
...@@ -128,7 +128,7 @@ static ssize_t xenbus_file_read(struct file *filp, ...@@ -128,7 +128,7 @@ static ssize_t xenbus_file_read(struct file *filp,
{ {
struct xenbus_file_priv *u = filp->private_data; struct xenbus_file_priv *u = filp->private_data;
struct read_buffer *rb; struct read_buffer *rb;
unsigned i; ssize_t i;
int ret; int ret;
mutex_lock(&u->reply_mutex); mutex_lock(&u->reply_mutex);
...@@ -148,7 +148,7 @@ static ssize_t xenbus_file_read(struct file *filp, ...@@ -148,7 +148,7 @@ static ssize_t xenbus_file_read(struct file *filp,
rb = list_entry(u->read_buffers.next, struct read_buffer, list); rb = list_entry(u->read_buffers.next, struct read_buffer, list);
i = 0; i = 0;
while (i < len) { while (i < len) {
unsigned sz = min((unsigned)len - i, rb->len - rb->cons); size_t sz = min_t(size_t, len - i, rb->len - rb->cons);
ret = copy_to_user(ubuf + i, &rb->msg[rb->cons], sz); ret = copy_to_user(ubuf + i, &rb->msg[rb->cons], sz);
......
...@@ -60,4 +60,6 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) ...@@ -60,4 +60,6 @@ static inline int hvm_get_parameter(int idx, uint64_t *value)
void xen_setup_callback_vector(void); void xen_setup_callback_vector(void);
int xen_set_upcall_vector(unsigned int cpu);
#endif /* XEN_HVM_H__ */ #endif /* XEN_HVM_H__ */
...@@ -46,4 +46,23 @@ struct xen_hvm_get_mem_type { ...@@ -46,4 +46,23 @@ struct xen_hvm_get_mem_type {
}; };
DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_get_mem_type); DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_get_mem_type);
#if defined(__i386__) || defined(__x86_64__)
/*
* HVMOP_set_evtchn_upcall_vector: Set a <vector> that should be used for event
* channel upcalls on the specified <vcpu>. If set,
* this vector will be used in preference to the
* domain global callback via (see
* HVM_PARAM_CALLBACK_IRQ).
*/
#define HVMOP_set_evtchn_upcall_vector 23
struct xen_hvm_evtchn_upcall_vector {
uint32_t vcpu;
uint8_t vector;
};
typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t;
DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_evtchn_upcall_vector_t);
#endif /* defined(__i386__) || defined(__x86_64__) */
#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
...@@ -34,7 +34,6 @@ CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m ...@@ -34,7 +34,6 @@ CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
CONFIG_XEN_SCSI_FRONTEND=m CONFIG_XEN_SCSI_FRONTEND=m
# others # others
CONFIG_XEN_BALLOON=y CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DEV_EVTCHN=m CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m CONFIG_XEN_NETDEV_FRONTEND=m
......
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