]> Git Repo - linux.git/commitdiff
Merge tag 'for-linus-5.18-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Mon, 28 Mar 2022 21:32:39 +0000 (14:32 -0700)
committerLinus Torvalds <[email protected]>
Mon, 28 Mar 2022 21:32:39 +0000 (14:32 -0700)
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

1  2 
drivers/block/xen-blkfront.c
drivers/char/tpm/xen-tpmfront.c
drivers/usb/host/xen-hcd.c

index 85fc550508cce34111ff5c717ec97de62320d935,aa996b637d0b84b587c93343c85d2d4837ac8ae2..378262ec47aeb590f745d6ada698d28eb285e4d2
@@@ -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)
                       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);
  
                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);
  
                        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);
        }
  }
index f53e0cf1ec7e9d9fb50675a36f205c86eb75fddb,ad0675f23e6e4b9eefda030e2af8445b282d8876..69df04ae2401b8f6ebaaa8e7bb17fdb52fdf5e5d
@@@ -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);
index 210f91bf661c8890df755b390c44a37f98d5e815,5f4a00df4f1c60217d38db6154dc9a32398716a5..3e487baf84224bacea4cc57cf1eeb960262c20ed
@@@ -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;
  
                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;
                        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;
  
        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;
                                       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)
  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;
  
This page took 0.131684 seconds and 4 git commands to generate.