]> Git Repo - J-linux.git/commitdiff
Merge tag 'for-linus-6.9-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Tue, 19 Mar 2024 15:48:09 +0000 (08:48 -0700)
committerLinus Torvalds <[email protected]>
Tue, 19 Mar 2024 15:48:09 +0000 (08:48 -0700)
Pull xen updates from Juergen Gross:

 - Xen event channel handling fix for a regression with a rare kernel
   config and some added hardening

 - better support of running Xen dom0 in PVH mode

 - a cleanup for the xen grant-dma-iommu driver

* tag 'for-linus-6.9-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/events: increment refcnt only if event channel is refcounted
  xen/evtchn: avoid WARN() when unbinding an event channel
  x86/xen: attempt to inflate the memory balloon on PVH
  xen/grant-dma-iommu: Convert to platform remove callback returning void

1  2 
arch/x86/platform/pvh/enlighten.c
arch/x86/xen/enlighten_pvh.c
drivers/xen/events/events_base.c

index 944e0290f2c001810a16a2eee3c2e87a31ba48e0,a12117f3d4de72c33fae675c0ddb2c37efcb5ad6..8c2d4b8de25d482694101264674f5886758b00ed
@@@ -3,7 -3,6 +3,7 @@@
  
  #include <xen/hvc-console.h>
  
 +#include <asm/bootparam.h>
  #include <asm/io_apic.h>
  #include <asm/hypervisor.h>
  #include <asm/e820/api.h>
@@@ -75,6 -74,9 +75,9 @@@ static void __init init_pvh_bootparams(
        } else
                xen_raw_printk("Warning: Can fit ISA range into e820\n");
  
+       if (xen_guest)
+               xen_reserve_extra_memory(&pvh_bootparams);
        pvh_bootparams.hdr.cmd_line_ptr =
                pvh_start_info.cmdline_paddr;
  
index 9e9db601bd52a9bf48a2e5ec4c936c0b7db93b39,c28f073c1df52426ddefff3a42433e539a8dcd4f..27a2a02ef8fb1402657754ad5f1ae8c91c6a9d0e
@@@ -1,10 -1,10 +1,11 @@@
  // SPDX-License-Identifier: GPL-2.0
  #include <linux/acpi.h>
  #include <linux/export.h>
+ #include <linux/mm.h>
  
  #include <xen/hvc-console.h>
  
 +#include <asm/bootparam.h>
  #include <asm/io_apic.h>
  #include <asm/hypervisor.h>
  #include <asm/e820/api.h>
@@@ -73,3 -73,70 +74,70 @@@ void __init mem_map_via_hcall(struct bo
        }
        boot_params_p->e820_entries = memmap.nr_entries;
  }
+ /*
+  * Reserve e820 UNUSABLE regions to inflate the memory balloon.
+  *
+  * On PVH dom0 the host memory map is used, RAM regions available to dom0 are
+  * located as the same place as in the native memory map, but since dom0 gets
+  * less memory than the total amount of host RAM the ranges that can't be
+  * populated are converted from RAM -> UNUSABLE.  Use such regions (up to the
+  * ratio signaled in EXTRA_MEM_RATIO) in order to inflate the balloon driver at
+  * boot.  Doing so prevents the guest (even if just temporary) from using holes
+  * in the memory map in order to map grants or foreign addresses, and
+  * hopefully limits the risk of a clash with a device MMIO region.  Ideally the
+  * hypervisor should notify us which memory ranges are suitable for creating
+  * foreign mappings, but that's not yet implemented.
+  */
+ void __init xen_reserve_extra_memory(struct boot_params *bootp)
+ {
+       unsigned int i, ram_pages = 0, extra_pages;
+       for (i = 0; i < bootp->e820_entries; i++) {
+               struct boot_e820_entry *e = &bootp->e820_table[i];
+               if (e->type != E820_TYPE_RAM)
+                       continue;
+               ram_pages += PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr);
+       }
+       /* Max amount of extra memory. */
+       extra_pages = EXTRA_MEM_RATIO * ram_pages;
+       /*
+        * Convert UNUSABLE ranges to RAM and reserve them for foreign mapping
+        * purposes.
+        */
+       for (i = 0; i < bootp->e820_entries && extra_pages; i++) {
+               struct boot_e820_entry *e = &bootp->e820_table[i];
+               unsigned long pages;
+               if (e->type != E820_TYPE_UNUSABLE)
+                       continue;
+               pages = min(extra_pages,
+                       PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr));
+               if (pages != (PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr))) {
+                       struct boot_e820_entry *next;
+                       if (bootp->e820_entries ==
+                           ARRAY_SIZE(bootp->e820_table))
+                               /* No space left to split - skip region. */
+                               continue;
+                       /* Split entry. */
+                       next = e + 1;
+                       memmove(next, e,
+                               (bootp->e820_entries - i) * sizeof(*e));
+                       bootp->e820_entries++;
+                       next->addr = PAGE_ALIGN(e->addr) + PFN_PHYS(pages);
+                       e->size = next->addr - e->addr;
+                       next->size -= e->size;
+               }
+               e->type = E820_TYPE_RAM;
+               extra_pages -= pages;
+               xen_add_extra_mem(PFN_UP(e->addr), pages);
+       }
+ }
index 2faa4bf78c7a9d87a0cbfe76358c2ad7538f6b48,27553673e46bccb796ef6998122c463e1bc64db6..81effbd53dc52b58daa51fc4ea7f906e8cc1ca81
@@@ -1190,7 -1190,7 +1190,7 @@@ int xen_pirq_from_irq(unsigned irq
  EXPORT_SYMBOL_GPL(xen_pirq_from_irq);
  
  static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip,
-                                  struct xenbus_device *dev)
+                                  struct xenbus_device *dev, bool shared)
  {
        int ret = -ENOMEM;
        struct irq_info *info;
                 */
                bind_evtchn_to_cpu(info, 0, false);
        } else if (!WARN_ON(info->type != IRQT_EVTCHN)) {
-               info->refcnt++;
+               if (shared && !WARN_ON(info->refcnt < 0))
+                       info->refcnt++;
        }
  
        ret = info->irq;
  
  int bind_evtchn_to_irq(evtchn_port_t evtchn)
  {
-       return bind_evtchn_to_irq_chip(evtchn, &xen_dynamic_chip, NULL);
+       return bind_evtchn_to_irq_chip(evtchn, &xen_dynamic_chip, NULL, false);
  }
  EXPORT_SYMBOL_GPL(bind_evtchn_to_irq);
  
  int bind_evtchn_to_irq_lateeoi(evtchn_port_t evtchn)
  {
-       return bind_evtchn_to_irq_chip(evtchn, &xen_lateeoi_chip, NULL);
+       return bind_evtchn_to_irq_chip(evtchn, &xen_lateeoi_chip, NULL, false);
  }
  EXPORT_SYMBOL_GPL(bind_evtchn_to_irq_lateeoi);
  
@@@ -1295,7 -1296,8 +1296,8 @@@ static int bind_ipi_to_irq(unsigned in
  
  static int bind_interdomain_evtchn_to_irq_chip(struct xenbus_device *dev,
                                               evtchn_port_t remote_port,
-                                              struct irq_chip *chip)
+                                              struct irq_chip *chip,
+                                              bool shared)
  {
        struct evtchn_bind_interdomain bind_interdomain;
        int err;
                                          &bind_interdomain);
  
        return err ? : bind_evtchn_to_irq_chip(bind_interdomain.local_port,
-                                              chip, dev);
+                                              chip, dev, shared);
  }
  
  int bind_interdomain_evtchn_to_irq_lateeoi(struct xenbus_device *dev,
                                           evtchn_port_t remote_port)
  {
        return bind_interdomain_evtchn_to_irq_chip(dev, remote_port,
-                                                  &xen_lateeoi_chip);
+                                                  &xen_lateeoi_chip, false);
  }
  EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq_lateeoi);
  
@@@ -1430,7 -1432,8 +1432,8 @@@ static int bind_evtchn_to_irqhandler_ch
  {
        int irq, retval;
  
-       irq = bind_evtchn_to_irq_chip(evtchn, chip, NULL);
+       irq = bind_evtchn_to_irq_chip(evtchn, chip, NULL,
+                                     irqflags & IRQF_SHARED);
        if (irq < 0)
                return irq;
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
@@@ -1471,7 -1474,8 +1474,8 @@@ static int bind_interdomain_evtchn_to_i
  {
        int irq, retval;
  
-       irq = bind_interdomain_evtchn_to_irq_chip(dev, remote_port, chip);
+       irq = bind_interdomain_evtchn_to_irq_chip(dev, remote_port, chip,
+                                                 irqflags & IRQF_SHARED);
        if (irq < 0)
                return irq;
  
@@@ -2220,7 -2224,7 +2224,7 @@@ static __init void xen_alloc_callback_v
                return;
  
        pr_info("Xen HVM callback vector for event delivery is enabled\n");
 -      alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
 +      sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback);
  }
  #else
  void xen_setup_callback_vector(void) {}
This page took 0.051985 seconds and 4 git commands to generate.