The following commit has been merged in the master branch: commit a701f370b521b2ed0654a9da7cf424b3ff8fa73d Merge: 7203062171db6669f746d14148c4af76af619e74 de2ae403b4c0e79a3410e63bc448542fbb9f9bfc Author: Linus Torvalds torvalds@linux-foundation.org Date: Mon Mar 28 14:32:39 2022 -0700
Merge tag 'for-linus-5.18-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from Juergen Gross:
- A bunch of minor cleanups
- A fix for kexec in Xen dom0 when executed on a high cpu number
- A fix for resuming after suspend of a Xen guest with assigned PCI devices
- A fix for a crash due to not disabled preemption when resuming as Xen dom0
* tag 'for-linus-5.18-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen: fix is_xen_pmu() xen: don't hang when resuming PCI device arch:x86:xen: Remove unnecessary assignment in xen_apic_read() xen/grant-table: remove readonly parameter from functions xen/grant-table: remove gnttab_*transfer*() functions drivers/xen: use helper macro __ATTR_RW x86/xen: Fix kerneldoc warning xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32 xen: use time_is_before_eq_jiffies() instead of open coding it
diff --combined drivers/block/xen-blkfront.c index 85fc550508cc,aa996b637d0b..378262ec47ae --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@@ -1223,7 -1223,7 +1223,7 @@@ static void blkif_free_ring(struct blkf list_del(&persistent_gnt->node); if (persistent_gnt->gref != GRANT_INVALID_REF) { gnttab_end_foreign_access(persistent_gnt->gref, - 0, 0UL); + 0UL); rinfo->persistent_gnts_c--; } if (info->feature_persistent) @@@ -1246,7 -1246,7 +1246,7 @@@ rinfo->shadow[i].req.u.rw.nr_segments; for (j = 0; j < segs; j++) { persistent_gnt = rinfo->shadow[i].grants_used[j]; - gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); + gnttab_end_foreign_access(persistent_gnt->gref, 0UL); if (info->feature_persistent) __free_page(persistent_gnt->page); kfree(persistent_gnt); @@@ -1261,7 -1261,7 +1261,7 @@@
for (j = 0; j < INDIRECT_GREFS(segs); j++) { persistent_gnt = rinfo->shadow[i].indirect_grants[j]; - gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); + gnttab_end_foreign_access(persistent_gnt->gref, 0UL); __free_page(persistent_gnt->page); kfree(persistent_gnt); } @@@ -1284,7 -1284,7 +1284,7 @@@ free_shadow /* Free resources associated with old device channel. */ for (i = 0; i < info->nr_ring_pages; i++) { if (rinfo->ring_ref[i] != GRANT_INVALID_REF) { - gnttab_end_foreign_access(rinfo->ring_ref[i], 0, 0); + gnttab_end_foreign_access(rinfo->ring_ref[i], 0); rinfo->ring_ref[i] = GRANT_INVALID_REF; } } @@@ -2533,7 -2533,6 +2533,7 @@@ static void purge_persistent_grants(str
for_each_rinfo(info, rinfo, i) { struct grant *gnt_list_entry, *tmp; + LIST_HEAD(grants);
spin_lock_irqsave(&rinfo->ring_lock, flags);
@@@ -2551,11 -2550,9 +2551,11 @@@ list_del(&gnt_list_entry->node); rinfo->persistent_gnts_c--; gnt_list_entry->gref = GRANT_INVALID_REF; - list_add_tail(&gnt_list_entry->node, &rinfo->grants); + list_add_tail(&gnt_list_entry->node, &grants); }
+ list_splice_tail(&grants, &rinfo->grants); + spin_unlock_irqrestore(&rinfo->ring_lock, flags); } } diff --combined drivers/char/tpm/xen-tpmfront.c index f53e0cf1ec7e,ad0675f23e6e..69df04ae2401 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@@ -126,16 -126,16 +126,16 @@@ static void vtpm_cancel(struct tpm_chi notify_remote_via_evtchn(priv->evtchn); }
-static unsigned int shr_data_offset(struct vtpm_shared_page *shr) +static size_t shr_data_offset(struct vtpm_shared_page *shr) { - return sizeof(*shr) + sizeof(u32) * shr->nr_extra_pages; + return struct_size(shr, extra_pages, shr->nr_extra_pages); }
static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct tpm_private *priv = dev_get_drvdata(&chip->dev); struct vtpm_shared_page *shr = priv->shr; - unsigned int offset = shr_data_offset(shr); + size_t offset = shr_data_offset(shr);
u32 ordinal; unsigned long duration; @@@ -177,7 -177,7 +177,7 @@@ static int vtpm_recv(struct tpm_chip *c { struct tpm_private *priv = dev_get_drvdata(&chip->dev); struct vtpm_shared_page *shr = priv->shr; - unsigned int offset = shr_data_offset(shr); + size_t offset = shr_data_offset(shr); size_t length = shr->length;
if (shr->state == VTPM_STATE_IDLE) @@@ -332,7 -332,7 +332,7 @@@ static void ring_free(struct tpm_privat return;
if (priv->ring_ref) - gnttab_end_foreign_access(priv->ring_ref, 0, + gnttab_end_foreign_access(priv->ring_ref, (unsigned long)priv->shr); else free_page((unsigned long)priv->shr); diff --combined drivers/usb/host/xen-hcd.c index 210f91bf661c,5f4a00df4f1c..3e487baf8422 --- a/drivers/usb/host/xen-hcd.c +++ b/drivers/usb/host/xen-hcd.c @@@ -51,7 -51,6 +51,7 @@@ struct vdevice_status struct usb_shadow { struct xenusb_urb_request req; struct urb *urb; + bool in_flight; };
struct xenhcd_info { @@@ -590,12 -589,14 +590,12 @@@ static void xenhcd_gnttab_map(struct xe int nr_pages, int flags) { grant_ref_t ref; - unsigned long buffer_mfn; unsigned int offset; unsigned int len = length; unsigned int bytes; int i;
for (i = 0; i < nr_pages; i++) { - buffer_mfn = PFN_DOWN(arbitrary_virt_to_machine(addr).maddr); offset = offset_in_page(addr);
bytes = PAGE_SIZE - offset; @@@ -604,7 -605,7 +604,7 @@@
ref = gnttab_claim_grant_reference(gref_head); gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, - buffer_mfn, flags); + virt_to_gfn(addr), flags); seg[i].gref = ref; seg[i].offset = (__u16)offset; seg[i].length = (__u16)bytes; @@@ -721,12 -722,6 +721,12 @@@ static void xenhcd_gnttab_done(struct x int nr_segs = 0; int i;
+ if (!shadow->in_flight) { + xenhcd_set_error(info, "Illegal request id"); + return; + } + shadow->in_flight = false; + nr_segs = shadow->req.nr_buffer_segs;
if (xenusb_pipeisoc(shadow->req.pipe)) @@@ -810,7 -805,6 +810,7 @@@ static int xenhcd_do_request(struct xen
info->urb_ring.req_prod_pvt++; info->shadow[id].urb = urb; + info->shadow[id].in_flight = true;
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->urb_ring, notify); if (notify) @@@ -939,27 -933,10 +939,27 @@@ static int xenhcd_unlink_urb(struct xen return ret; }
-static int xenhcd_urb_request_done(struct xenhcd_info *info) +static void xenhcd_res_to_urb(struct xenhcd_info *info, + struct xenusb_urb_response *res, struct urb *urb) +{ + if (unlikely(!urb)) + return; + + if (res->actual_length > urb->transfer_buffer_length) + urb->actual_length = urb->transfer_buffer_length; + else if (res->actual_length < 0) + urb->actual_length = 0; + else + urb->actual_length = res->actual_length; + urb->error_count = res->error_count; + urb->start_frame = res->start_frame; + xenhcd_giveback_urb(info, urb, res->status); +} + +static int xenhcd_urb_request_done(struct xenhcd_info *info, + unsigned int *eoiflag) { struct xenusb_urb_response res; - struct urb *urb; RING_IDX i, rp; __u16 id; int more_to_do = 0; @@@ -986,12 -963,16 +986,12 @@@ xenhcd_gnttab_done(info, id); if (info->error) goto err; - urb = info->shadow[id].urb; - if (likely(urb)) { - urb->actual_length = res.actual_length; - urb->error_count = res.error_count; - urb->start_frame = res.start_frame; - xenhcd_giveback_urb(info, urb, res.status); - } + xenhcd_res_to_urb(info, &res, info->shadow[id].urb); }
xenhcd_add_id_to_freelist(info, id); + + *eoiflag = 0; } info->urb_ring.rsp_cons = i;
@@@ -1009,7 -990,7 +1009,7 @@@ return 0; }
-static int xenhcd_conn_notify(struct xenhcd_info *info) +static int xenhcd_conn_notify(struct xenhcd_info *info, unsigned int *eoiflag) { struct xenusb_conn_response res; struct xenusb_conn_request *req; @@@ -1054,8 -1035,6 +1054,8 @@@ info->conn_ring.req_prod_pvt); req->id = id; info->conn_ring.req_prod_pvt++; + + *eoiflag = 0; }
if (rc != info->conn_ring.req_prod_pvt) @@@ -1078,19 -1057,14 +1078,19 @@@ static irqreturn_t xenhcd_int(int irq, void *dev_id) { struct xenhcd_info *info = (struct xenhcd_info *)dev_id; + unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
- if (unlikely(info->error)) + if (unlikely(info->error)) { + xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); return IRQ_HANDLED; + }
- while (xenhcd_urb_request_done(info) | xenhcd_conn_notify(info)) + while (xenhcd_urb_request_done(info, &eoiflag) | + xenhcd_conn_notify(info, &eoiflag)) /* Yield point for this unbounded loop. */ cond_resched();
+ xen_irq_lateeoi(irq, eoiflag); return IRQ_HANDLED; }
@@@ -1101,14 -1075,14 +1101,14 @@@ static void xenhcd_destroy_rings(struc info->irq = 0;
if (info->urb_ring_ref != GRANT_INVALID_REF) { - gnttab_end_foreign_access(info->urb_ring_ref, 0, + gnttab_end_foreign_access(info->urb_ring_ref, (unsigned long)info->urb_ring.sring); info->urb_ring_ref = GRANT_INVALID_REF; } info->urb_ring.sring = NULL;
if (info->conn_ring_ref != GRANT_INVALID_REF) { - gnttab_end_foreign_access(info->conn_ring_ref, 0, + gnttab_end_foreign_access(info->conn_ring_ref, (unsigned long)info->conn_ring.sring); info->conn_ring_ref = GRANT_INVALID_REF; } @@@ -1167,9 -1141,9 +1167,9 @@@ static int xenhcd_setup_rings(struct xe goto fail; }
- err = bind_evtchn_to_irq(info->evtchn); + err = bind_evtchn_to_irq_lateeoi(info->evtchn); if (err <= 0) { - xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq"); + xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq_lateeoi"); goto fail; }
@@@ -1522,7 -1496,6 +1522,7 @@@ static struct usb_hcd *xenhcd_create_hc for (i = 0; i < XENUSB_URB_RING_SIZE; i++) { info->shadow[i].req.id = i + 1; info->shadow[i].urb = NULL; + info->shadow[i].in_flight = false; } info->shadow[XENUSB_URB_RING_SIZE - 1].req.id = 0x0fff;
linux-merge@lists.open-mesh.org