Skip to contentSkip to conversation

More Xen updates

PATCH In review Jeremy Fitzhardinge 3 participants 29 messages Apr 2, 2008 – Apr 7, 2008

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 More Xen updates

Hi Ingo,

More patches. There are three groups:

- some code movements to make common code available to other architectures (namely, ia64)
- Xen device driver updates, including a new xen paravirt framebuffer driver,
- The Xen balloon driver (shrink only, so no dependency on memory hotplug yet)
- some "using smp_processor_id while preemptable" warning fixes, mostly as a result of the core kernel's tendency to do tlb flushes and update init_mm while preemptable,
- other little Xen cleanups

Thanks,
J

#1 lore raw

PATCH 1/1 x86: fix build problem in pud_populate without CONFIG_PARAVIRT

asm/paravirt.h ends up including linux/sched.h, which pud_populate needs for its reference to current. Specifically include linux/sched.h for it.

In file included from /home/jeremy/hg/xen/paravirt/linux/arch/x86/mm/pgtable.c:3:
include2/asm/pgalloc.h: In function ‘pud_populate’:
include2/asm/pgalloc.h:93: error: dereferencing pointer to incomplete type make[3]: *** [arch/x86/mm/pgtable.o] Error 1
make[2]: *** [arch/x86/mm/] Error 2
make[1]: *** [sub-make] Error 2
make: *** [all] Error 2

---
 include/asm-x86/pgalloc.h |    1 +
 1 file changed, 1 insertion(+)
include/asm-x86/pgalloc.h +1 -0
@@ -4,6 +4,7 @@
 #include <linux/threads.h>
 #include <linux/mm.h>		/* for struct page */
 #include <linux/pagemap.h>
+#include <linux/sched.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
#2 lore raw

PATCH 1/1 xen: fold xen_sysexit into xen_iret

In reply to Jeremy Fitzhardinge

xen_sysexit and xen_iret were doing essentially the same thing. Rather than having a separate implementation for xen_sysexit, we can just strip the stack back to an iret frame and jump into xen_iret. This removes a lot of code and complexity - specifically, another critical region.

---
 arch/x86/kernel/entry_32.S |    9 -----
 arch/x86/xen/xen-asm.S     |   70 ++++++++------------------------------------
 2 files changed, 15 insertions(+), 64 deletions(-)
arch/x86/kernel/entry_32.S +1 -8
@@ -1044,15 +1044,8 @@
 
 	jmp  xen_iret_crit_fixup
 
-1:	cmpl $xen_sysexit_start_crit,%eax
-	jb   2f
-	cmpl $xen_sysexit_end_crit,%eax
-	jae  2f
-
-	jmp xen_sysexit_crit_fixup
-
 ENTRY(xen_do_upcall)
-2:	mov %esp, %eax
+1:	mov %esp, %eax
 	call xen_evtchn_do_upcall
 	jmp  ret_from_intr
 	CFI_ENDPROC
arch/x86/xen/xen-asm.S +14 -56

82 lines not on this page · raw message

#3 lore raw

PATCH 1/1 xen: add balloon driver

In reply to Jeremy Fitzhardinge

The balloon driver allows memory to be dynamically added or removed from the domain, in order to allow host memory to be balanced between multiple domains.

This patch introduces the Xen balloon driver, though it currently only allows a domain to be shrunk from its initial size (and re-grown back to that size). A later patch will add the ability to grow a domain beyond its initial size.

---
 drivers/Kconfig                |    2
 drivers/xen/Kconfig            |   19 +
 drivers/xen/Makefile           |    1
 drivers/xen/balloon.c          |  712 ++++++++++++++++++++++++++++++++++++++++
 include/xen/balloon.h          |   61 +++
 include/xen/interface/memory.h |   12
 6 files changed, 799 insertions(+), 8 deletions(-)
drivers/Kconfig +2 -0
@@ -97,4 +97,6 @@
 source "drivers/auxdisplay/Kconfig"
 
 source "drivers/uio/Kconfig"
+
+source "drivers/xen/Kconfig"
 endmenu
drivers/xen/Kconfig new file +19 -0
new file mode 100644
@@ -0,0 +1,19 @@
+config XEN_BALLOON
+	bool "Xen memory balloon driver"
+	depends on XEN
+	default y
+	help
+	  The balloon driver allows the Xen domain to request more memory from
+	  the system to expand the domain's memory allocation, or alternatively
+	  return unneeded memory to the system.
+
+config XEN_SCRUB_PAGES
+	bool "Scrub pages before returning them to system"
+	depends on XEN_BALLOON
+	default y
+	help
+	  Scrub pages before returning them to the system for reuse by
+	  other domains.  This makes sure that any confidential data
+	  is not accidentally visible to other domains.  Is it more
+	  secure, but slightly less efficient.
+	  If in doubt, say yes.
drivers/xen/Makefile +1 -0
@@ -1,3 +1,4 @@
 obj-y	+= grant-table.o features.o events.o
 obj-y	+= xenbus/
 obj-$(CONFIG_XEN_XENCOMM)	+= xencomm.o
+obj-$(CONFIG_XEN_BALLOON)	+= balloon.o
drivers/xen/balloon.c new file +712 -0

712 lines not on this page · raw message

include/xen/balloon.h new file +61 -0

61 lines not on this page · raw message

include/xen/interface/memory.h +4 -8
@@ -29,7 +29,7 @@
      *   OUT: GMFN bases of extents that were allocated
      *   (NB. This command also updates the mach_to_phys translation table)
      */
-    GUEST_HANDLE(ulong) extent_start;
+    ulong extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
     unsigned long  nr_extents;
@@ -50,7 +50,6 @@
     domid_t        domid;
 
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation);
 
 /*
  * Returns the maximum machine frame number of mapped RAM in this system.
@@ -86,7 +85,7 @@
      * any large discontiguities in the machine address space, 2MB gaps in
      * the machphys table will be represented by an MFN base of zero.
      */
-    GUEST_HANDLE(ulong) extent_start;
+    ulong extent_start;
 
     /*
      * Number of extents written to the above array. This will be smaller
@@ -94,7 +93,6 @@
      */
     unsigned int nr_extents;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);
 
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
@@ -117,7 +115,6 @@
     /* GPFN where the source mapping page should appear. */
     unsigned long gpfn;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
 
 /*
  * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
@@ -132,14 +129,13 @@
     unsigned long nr_gpfns;
 
     /* List of GPFNs to translate. */
-    GUEST_HANDLE(ulong) gpfn_list;
+    ulong gpfn_list;
 
     /*
      * Output list to contain MFN translations. May be the same as the input
      * list (in which case each input GPFN is overwritten with the output MFN).
      */
-    GUEST_HANDLE(ulong) mfn_list;
+    ulong mfn_list;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
 
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
#4 lore raw

Re: [PATCH 24 of 24] xen: add balloon driver

The following modification to include/xen/interface/memory.h removes handles related definitions.
It breaks ia64/xen compilation because ia64/xen uses memory interface not only for balloon, but also for xen_alloc_vm_area/xen_free_vm_area().

Can it be added again?

thanks,

Quoted 65 lines · Jeremy Fitzhardinge
include/xen/interface/memory.h +4 -8
@@ -29,7 +29,7 @@
      *   OUT: GMFN bases of extents that were allocated
      *   (NB. This command also updates the mach_to_phys translation table)
      */
-    GUEST_HANDLE(ulong) extent_start;
+    ulong extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
     unsigned long  nr_extents;
@@ -50,7 +50,6 @@
     domid_t        domid;
 
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation);
 
 /*
  * Returns the maximum machine frame number of mapped RAM in this system.
@@ -86,7 +85,7 @@
      * any large discontiguities in the machine address space, 2MB gaps in
      * the machphys table will be represented by an MFN base of zero.
      */
-    GUEST_HANDLE(ulong) extent_start;
+    ulong extent_start;
 
     /*
      * Number of extents written to the above array. This will be smaller
@@ -94,7 +93,6 @@
      */
     unsigned int nr_extents;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list);
 
 /*
  * Sets the GPFN at which a particular page appears in the specified guest's
@@ -117,7 +115,6 @@
     /* GPFN where the source mapping page should appear. */
     unsigned long gpfn;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
 
 /*
  * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
@@ -132,14 +129,13 @@
     unsigned long nr_gpfns;
 
     /* List of GPFNs to translate. */
-    GUEST_HANDLE(ulong) gpfn_list;
+    ulong gpfn_list;
 
     /*
      * Output list to contain MFN translations. May be the same as the input
      * list (in which case each input GPFN is overwritten with the output MFN).
      */
-    GUEST_HANDLE(ulong) mfn_list;
+    ulong mfn_list;
 };
-DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
 
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
Signature · 1 line
yamahata
#5 lore raw

Re: [PATCH 24 of 24] xen: add balloon driver

Quoted 6 lines · Isaku Yamahata

The following modification to include/xen/interface/memory.h removes handles related definitions. It breaks ia64/xen compilation because ia64/xen uses memory interface
not only for balloon, but also for xen_alloc_vm_area/xen_free_vm_area().

Can it be added again?

Yes, sure. We're going to hit that a bit because we needed to remove them to make the initial upstreaming smooth.

J

#6 lore raw

PATCH 1/1 xen: make grant table arch portable

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

split out x86 specific part from grant-table.c and allow ia64/xen specific initialization.
ia64/xen grant table is based on pseudo physical address (guest physical address) unlike x86/xen. On ia64 init_mm doesn't map identity straight mapped area. ia64/xen specific grant table initialization is necessary.

---
 arch/x86/xen/Makefile      |    2
 arch/x86/xen/grant-table.c |   91 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/xen/grant-table.c  |   35 +---------------
 include/xen/grant_table.h  |    7 ++-
 4 files changed, 101 insertions(+), 34 deletions(-)
arch/x86/xen/Makefile +1 -1
@@ -1,4 +1,4 @@
 obj-y		:= enlighten.o setup.o multicalls.o mmu.o \
-			time.o manage.o xen-asm.o
+			time.o manage.o xen-asm.o grant-table.o
 
 obj-$(CONFIG_SMP)	+= smp.o
arch/x86/xen/grant-table.c new file +91 -0

91 lines not on this page · raw message

drivers/xen/grant-table.c +3 -32
@@ -435,24 +435,6 @@
 	return xen_max;
 }
 
-static int map_pte_fn(pte_t *pte, struct page *pmd_page,
-		      unsigned long addr, void *data)
-{
-	unsigned long **frames = (unsigned long **)data;
-
-	set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
-	(*frames)++;
-	return 0;
-}
-
-static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
-			unsigned long addr, void *data)
-{
-
-	set_pte_at(&init_mm, addr, pte, __pte(0));
-	return 0;
-}
-
 static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 {
 	struct gnttab_setup_table setup;
@@ -476,17 +458,9 @@
 
 	BUG_ON(rc || setup.status);
 
-	if (shared == NULL) {
-		struct vm_struct *area;
-		area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
-		BUG_ON(area == NULL);
-		shared = area->addr;
-	}
-	rc = apply_to_page_range(&init_mm, (unsigned long)shared,
-				 PAGE_SIZE * nr_gframes,
-				 map_pte_fn, &frames);
+	rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(),
+				    &shared);
 	BUG_ON(rc);
-	frames -= nr_gframes; /* adjust after map_pte_fn() */
 
 	kfree(frames);
 
@@ -502,10 +476,7 @@
 
 static int gnttab_suspend(void)
 {
-	apply_to_page_range(&init_mm, (unsigned long)shared,
-			    PAGE_SIZE * nr_grant_frames,
-			    unmap_pte_fn, NULL);
-
+	arch_gnttab_unmap_shared(shared, nr_grant_frames);
 	return 0;
 }
 
include/xen/grant_table.h +6 -0
@@ -103,6 +103,12 @@
 void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
 				       unsigned long pfn);
 
+int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
+			   unsigned long max_nr_gframes,
+			   struct grant_entry **__shared);
+void arch_gnttab_unmap_shared(struct grant_entry *shared,
+			      unsigned long nr_gframes);
+
 #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
 
 #endif /* __ASM_GNTTAB_H__ */
#7 lore raw

PATCH 1/1 xen: allow compilation with non-flat memory

In reply to Jeremy Fitzhardinge

There's no real reason we can't support sparsemem/discontigmem, so do so. This is mostly useful to support hotplug memory.

---
 arch/x86/xen/Kconfig     |    2 +-
 arch/x86/xen/enlighten.c |    2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
arch/x86/xen/Kconfig +1 -1
@@ -6,7 +6,7 @@
 	bool "Xen guest support"
 	select PARAVIRT
 	depends on X86_32
-	depends on X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES && !(X86_VISWS || X86_VOYAGER)
+	depends on X86_CMPXCHG && X86_TSC && !(X86_VISWS || X86_VOYAGER)
 	help
 	  This is the Linux Xen port.  Enabling this will allow the
 	  kernel to boot in a paravirtualized environment under the
arch/x86/xen/enlighten.c +2 -0
@@ -669,7 +669,9 @@
    everything is pinned. */
 static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
 {
+#ifdef CONFIG_FLATMEM
 	BUG_ON(mem_map);	/* should only be used early */
+#endif
 	make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
 }
 
#8 lore raw

PATCH 1/1 xen blkfront: Delay wait for block devices until after the disk is added

In reply to Jeremy Fitzhardinge

From: Christian Limpach <[email protected]>

When the xen block frontend driver is built as a module the module load is only synchronous up to the point where the frontend and the backend become connected rather than when the disk is added.

This means that there can be a race on boot between loading the module and loading the dm-* modules and doing the scan for LVM physical volumes (all in the initrd). In the failure case the disk is not present until after the scan for physical volumes is complete.

Taken from:

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/11483a00c017

---
 drivers/block/xen-blkfront.c      |   11 +++++++++++
 drivers/xen/xenbus/xenbus_probe.c |    5 ++++-
 include/xen/xenbus.h              |    2 +-
 3 files changed, 16 insertions(+), 2 deletions(-)
drivers/block/xen-blkfront.c +11 -0
@@ -88,6 +88,7 @@
 	struct blk_shadow shadow[BLK_RING_SIZE];
 	unsigned long shadow_free;
 	int feature_barrier;
+	int is_ready;
 
 	/**
 	 * The number of people holding this device open.  We won't allow a
@@ -839,6 +840,8 @@
 	spin_unlock_irq(&blkif_io_lock);
 
 	add_disk(info->gd);
+
+	info->is_ready = 1;
 }
 
 /**
@@ -931,6 +934,13 @@
 	return 0;
 }
 
+static int blkfront_is_ready(struct xenbus_device *dev)
+{
+	struct blkfront_info *info = dev->dev.driver_data;
+
+	return info->is_ready;
+}
+
 static int blkif_open(struct inode *inode, struct file *filep)
 {
 	struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
@@ -977,6 +987,7 @@
 	.remove = blkfront_remove,
 	.resume = blkfront_resume,
 	.otherend_changed = backend_changed,
+	.is_ready = blkfront_is_ready,
 };
 
 static int __init xlblk_init(void)
drivers/xen/xenbus/xenbus_probe.c +4 -1
@@ -846,6 +846,7 @@
 {
 	struct xenbus_device *xendev = to_xenbus_device(dev);
 	struct device_driver *drv = data;
+	struct xenbus_driver *xendrv;
 
 	/*
 	 * A device with no driver will never connect. We care only about
@@ -858,7 +859,9 @@
 	if (drv && (dev->driver != drv))
 		return 0;
 
-	return (xendev->state != XenbusStateConnected);
+	xendrv = to_xenbus_driver(dev->driver);
+	return (xendev->state != XenbusStateConnected ||
+		(xendrv->is_ready && !xendrv->is_ready(xendev)));
 }
 
 static int exists_disconnected_device(struct device_driver *drv)
include/xen/xenbus.h +1 -0
@@ -97,6 +97,7 @@
 	int (*uevent)(struct xenbus_device *, char **, int, char *, int);
 	struct device_driver driver;
 	int (*read_otherend_details)(struct xenbus_device *dev);
+	int (*is_ready)(struct xenbus_device *dev);
 };
 
 static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
#9 lore raw

PATCH 1/1 xen: Module autoprobing support for frontend drivers

In reply to Jeremy Fitzhardinge

From: Mark McLoughlin <[email protected]>

Add module aliases to support autoprobing modules
for xen frontend devices.

---
 drivers/block/xen-blkfront.c      |    1 +
 drivers/net/xen-netfront.c        |    1 +
 drivers/xen/xenbus/xenbus_probe.c |   28 +++++++++++++++++++++++++---
 3 files changed, 27 insertions(+), 3 deletions(-)
drivers/block/xen-blkfront.c +1 -0
@@ -1015,3 +1015,4 @@
 MODULE_DESCRIPTION("Xen virtual block device frontend");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR);
+MODULE_ALIAS("xen:vbd");
drivers/net/xen-netfront.c +1 -0
@@ -1809,3 +1809,4 @@
 
 MODULE_DESCRIPTION("Xen virtual network device frontend");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:vif");
drivers/xen/xenbus/xenbus_probe.c +25 -2
@@ -88,6 +88,16 @@
 	return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
 }
 
+static int xenbus_uevent(struct device *_dev, struct kobj_uevent_env *env)
+{
+	struct xenbus_device *dev = to_xenbus_device(_dev);
+
+	if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype))
+		return -ENOMEM;
+
+	return 0;
+}
+
 /* device/<type>/<id> => <type>-<id> */
 static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
 {
@@ -166,6 +176,7 @@
 	.bus = {
 		.name     = "xen",
 		.match    = xenbus_match,
+		.uevent   = xenbus_uevent,
 		.probe    = xenbus_dev_probe,
 		.remove   = xenbus_dev_remove,
 		.shutdown = xenbus_dev_shutdown,
@@ -438,6 +449,12 @@
 }
 DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
 
+static ssize_t xendev_show_modalias(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
+}
+DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
 
 int xenbus_probe_node(struct xen_bus_type *bus,
 		      const char *type,
@@ -492,10 +509,16 @@
 
 	err = device_create_file(&xendev->dev, &dev_attr_devtype);
 	if (err)
-		goto fail_remove_file;
+		goto fail_remove_nodename;
+
+	err = device_create_file(&xendev->dev, &dev_attr_modalias);
+	if (err)
+		goto fail_remove_devtype;
 
 	return 0;
-fail_remove_file:
+fail_remove_devtype:
+	device_remove_file(&xendev->dev, &dev_attr_devtype);
+fail_remove_nodename:
 	device_remove_file(&xendev->dev, &dev_attr_nodename);
 fail_unregister:
 	device_unregister(&xendev->dev);
#10 lore raw

PATCH 1/1 xen: add missing definitions for xen grant table which ia64/xen needs

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Add xen handles realted definitions for grant table which ia64/xen needs.
Pointer argumsnts for ia64/xen hypercall are passed in pseudo physical address (guest physical address) so that it is required to convert guest kernel virtual address into pseudo physical address right before issuing hypercall.
The xen guest handle represents such arguments.
Define necessary handles and helper functions.

---
 drivers/xen/grant-table.c           |    2 +-
 include/asm-x86/xen/interface.h     |   24 ++++++++++++++++++++++++
 include/xen/interface/grant_table.h |   12 ++++++++----
 3 files changed, 33 insertions(+), 5 deletions(-)
drivers/xen/grant-table.c +1 -1
@@ -466,7 +466,7 @@
 
 	setup.dom        = DOMID_SELF;
 	setup.nr_frames  = nr_gframes;
-	setup.frame_list = frames;
+	set_xen_guest_handle(setup.frame_list, frames);
 
 	rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
 	if (rc == -ENOSYS) {
include/asm-x86/xen/interface.h +24 -0
@@ -21,6 +21,30 @@
 	__DEFINE_GUEST_HANDLE(name, struct name)
 #define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
 #define GUEST_HANDLE(name)        __guest_handle_ ## name
+
+#ifdef __XEN__
+#if defined(__i386__)
+#define set_xen_guest_handle(hnd, val)			\
+	do {						\
+		if (sizeof(hnd) == 8)			\
+			*(uint64_t *)&(hnd) = 0;	\
+		(hnd).p = val;				\
+	} while (0)
+#elif defined(__x86_64__)
+#define set_xen_guest_handle(hnd, val)	do { (hnd).p = val; } while (0)
+#endif
+#else
+#if defined(__i386__)
+#define set_xen_guest_handle(hnd, val)			\
+	do {						\
+		if (sizeof(hnd) == 8)			\
+			*(uint64_t *)&(hnd) = 0;	\
+		(hnd) = val;				\
+	} while (0)
+#elif defined(__x86_64__)
+#define set_xen_guest_handle(hnd, val)	do { (hnd) = val; } while (0)
+#endif
+#endif
 
 #ifndef __ASSEMBLY__
 /* Guest handles for primitive C types. */
include/xen/interface/grant_table.h +8 -3
@@ -185,6 +185,7 @@
     grant_handle_t handle;
     uint64_t dev_bus_addr;
 };
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_map_grant_ref);
 
 /*
  * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
@@ -206,6 +207,7 @@
     /* OUT parameters. */
     int16_t  status;              /* GNTST_* */
 };
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_grant_ref);
 
 /*
  * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least
@@ -223,8 +225,9 @@
     uint32_t nr_frames;
     /* OUT parameters. */
     int16_t  status;              /* GNTST_* */
-    ulong *frame_list;
+    GUEST_HANDLE(ulong) frame_list;
 };
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_setup_table);
 
 /*
  * GNTTABOP_dump_table: Dump the contents of the grant table to the
@@ -237,6 +240,7 @@
     /* OUT parameters. */
     int16_t status;               /* GNTST_* */
 };
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);
 
 /*
  * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
@@ -255,7 +259,7 @@
     /* OUT parameters. */
     int16_t       status;
 };
-
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_transfer);
 
 /*
  * GNTTABOP_copy: Hypervisor based copy
@@ -296,6 +300,7 @@
 	/* OUT parameters. */
 	int16_t       status;
 };
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_copy);
 
 /*
  * GNTTABOP_query_size: Query the current and maximum sizes of the shared
@@ -313,7 +318,7 @@
     uint32_t max_nr_frames;
     int16_t  status;              /* GNTST_* */
 };
-
+DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);
 
 /*
  * Bitfield values for update_pin_status.flags.
#11 lore raw

PATCH 1/1 xen: add missing __HYPERVISOR_arch_[0-7] definisions which ia64 needs

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Add xen hypercall numbers defined for arch specific use. ia64/xen domU uses __HYPERVISOR_arch_1 to manipulate paravirtualized IOSAPIC. Although all those constants aren't used yet by IA64 at this moment, add all arch specific hypercall numbers.

---
 include/xen/interface/xen.h |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
include/xen/interface/xen.h +10 -0
@@ -57,6 +57,16 @@
 #define __HYPERVISOR_event_channel_op     32
 #define __HYPERVISOR_physdev_op           33
 #define __HYPERVISOR_hvm_op               34
+
+/* Architecture-specific hypercall definitions. */
+#define __HYPERVISOR_arch_0               48
+#define __HYPERVISOR_arch_1               49
+#define __HYPERVISOR_arch_2               50
+#define __HYPERVISOR_arch_3               51
+#define __HYPERVISOR_arch_4               52
+#define __HYPERVISOR_arch_5               53
+#define __HYPERVISOR_arch_6               54
+#define __HYPERVISOR_arch_7               55
 
 /*
  * VIRTUAL INTERRUPTS
#12 lore raw

PATCH 1/1 xen: add missing VIRQ_ARCH_[0-7] definitions which ia64/xen needs

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Add xen VIRQ numbers defined for arch specific use. ia64/xen domU uses VIRQ_ARCH_0 for virtual itc timer. Although all those constants aren't used yet by ia64 at this moment, add all arch specific VIRQ numbers.

---
 include/xen/interface/xen.h |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
include/xen/interface/xen.h +11 -1
@@ -78,8 +78,18 @@
 #define VIRQ_CONSOLE    2  /* (DOM0) Bytes received on emergency console. */
 #define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
 #define VIRQ_DEBUGGER   6  /* (DOM0) A domain has paused for debugging.   */
-#define NR_VIRQS        8
 
+/* Architecture-specific VIRQ definitions. */
+#define VIRQ_ARCH_0    16
+#define VIRQ_ARCH_1    17
+#define VIRQ_ARCH_2    18
+#define VIRQ_ARCH_3    19
+#define VIRQ_ARCH_4    20
+#define VIRQ_ARCH_5    21
+#define VIRQ_ARCH_6    22
+#define VIRQ_ARCH_7    23
+
+#define NR_VIRQS       24
 /*
  * MMU-UPDATE REQUESTS
  *
#13 lore raw

PATCH 1/1 xen: move features.c from arch/x86/xen/features.c to drivers/xen

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

ia64/xen also uses it too. Move it into common place so that ia64/xen can share the code.

---
 arch/x86/xen/Makefile  |    2 +-
 drivers/xen/Makefile   |    2 +-
 drivers/xen/features.c |    1 -
 3 files changed, 2 insertions(+), 3 deletions(-)
arch/x86/xen/Makefile +1 -1
@@ -1,4 +1,4 @@
-obj-y		:= enlighten.o setup.o features.o multicalls.o mmu.o \
+obj-y		:= enlighten.o setup.o multicalls.o mmu.o \
 			events.o time.o manage.o xen-asm.o
 
 obj-$(CONFIG_SMP)	+= smp.o
drivers/xen/Makefile +1 -1
@@ -1,2 +1,2 @@
-obj-y	+= grant-table.o
+obj-y	+= grant-table.o features.o
 obj-y	+= xenbus/
drivers/xen/features.c renamed from arch/x86/xen/features.c +0 -0
rename from arch/x86/xen/features.c
rename to drivers/xen/features.c
#14 lore raw

PATCH 1/1 xen: Move events.c to drivers/xen for IA64/Xen support

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

move arch/x86/xen/events.c undedr drivers/xen to share codes with x86 and ia64. And minor adjustment to compile. ia64/xen also uses events.c

---
 arch/x86/xen/Makefile  |    2 +-
 arch/x86/xen/xen-ops.h |    2 +-
 drivers/xen/Makefile   |    2 +-
 drivers/xen/events.c   |    3 +--
 include/xen/xen-ops.h  |    9 ++++++++-
 5 files changed, 12 insertions(+), 6 deletions(-)
arch/x86/xen/Makefile +1 -1
@@ -1,4 +1,4 @@
 obj-y		:= enlighten.o setup.o multicalls.o mmu.o \
-			events.o time.o manage.o xen-asm.o
+			time.o manage.o xen-asm.o
 
 obj-$(CONFIG_SMP)	+= smp.o
arch/x86/xen/xen-ops.h +1 -1
@@ -3,6 +3,7 @@
 
 #include <linux/init.h>
 #include <linux/irqreturn.h>
+#include <xen/xen-ops.h>
 
 /* These are code, but not functions.  Defined in entry.S */
 extern const char xen_hypervisor_callback[];
@@ -10,7 +11,6 @@
 
 void xen_copy_trap_info(struct trap_info *traps);
 
-DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
 DECLARE_PER_CPU(unsigned long, xen_cr3);
 DECLARE_PER_CPU(unsigned long, xen_current_cr3);
 
drivers/xen/Makefile +1 -1
@@ -1,2 +1,2 @@
-obj-y	+= grant-table.o features.o
+obj-y	+= grant-table.o features.o events.o
 obj-y	+= xenbus/
drivers/xen/events.c renamed from arch/x86/xen/events.c +1 -2
rename from arch/x86/xen/events.c
rename to drivers/xen/events.c
@@ -33,11 +33,10 @@
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 
+#include <xen/xen-ops.h>
 #include <xen/events.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/event_channel.h>
-
-#include "xen-ops.h"
 
 /*
  * This lock protects updates to the following mapping and reference-count
include/xen/xen-ops.h new file +8 -0
new file mode 100644
@@ -0,0 +1,8 @@
+#ifndef INCLUDE_XEN_OPS_H
+#define INCLUDE_XEN_OPS_H
+
+#include <linux/percpu.h>
+
+DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
+
+#endif /* INCLUDE_XEN_OPS_H */
#15 lore raw

PATCH 1/1 xen: import arch generic part of xencomm

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

On xen/ia64 and xen/powerpc hypercall arguments are passed by pseudo physical address (guest physical address) so that it's necessary to convert from virtual address into pseudo physical address. The frame work is called xencomm.
Import arch generic part of xencomm.

---
 drivers/xen/Makefile            |    1
 drivers/xen/xencomm.c           |  232 +++++++++++++++++++++++++++++++++++++++
 include/xen/interface/xencomm.h |   41 ++++++
 include/xen/xencomm.h           |   78 ++++++++++++-
 4 files changed, 351 insertions(+), 1 deletion(-)
drivers/xen/Makefile +1 -0
@@ -1,2 +1,3 @@
 obj-y	+= grant-table.o features.o events.o
 obj-y	+= xenbus/
+obj-$(CONFIG_XEN_XENCOMM)	+= xencomm.o
drivers/xen/xencomm.c new file +232 -0

232 lines not on this page · raw message

include/xen/interface/xencomm.h new file +41 -0

41 lines not on this page · raw message

include/xen/xencomm.h new file +77 -0

77 lines not on this page · raw message

#16 lore raw

PATCH 1/1 xen: allow set_pte_at on init_mm to be lockless

In reply to Jeremy Fitzhardinge

The usual pagetable locking protocol doesn't seem to apply to updates to init_mm, so don't rely on preemption being disabled in xen_set_pte_at on init_mm.

---
 arch/x86/xen/mmu.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
arch/x86/xen/mmu.c +10 -2
@@ -156,6 +156,10 @@
 void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
 		    pte_t *ptep, pte_t pteval)
 {
+	/* updates to init_mm may be done without lock */
+	if (mm == &init_mm)
+		preempt_disable();
+
 	if (mm == current->mm || mm == &init_mm) {
 		if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
 			struct multicall_space mcs;
@@ -163,12 +167,16 @@
 
 			MULTI_update_va_mapping(mcs.mc, addr, pteval, 0);
 			xen_mc_issue(PARAVIRT_LAZY_MMU);
-			return;
+			goto out;
 		} else
 			if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0)
-				return;
+				goto out;
 	}
 	xen_set_pte(ptep, pteval);
+
+out:
+	if (mm == &init_mm)
+		preempt_enable();
 }
 
 pteval_t xen_pte_val(pte_t pte)
#17 lore raw

PATCH 1/1 xen: disable preemption during tlb flush

In reply to Jeremy Fitzhardinge

Various places in the kernel flush the tlb even though preemption doens't guarantee the tlb flush is happening on any particular CPU. In many cases this doesn't seem to matter, so don't make a fuss about it.

---
 arch/x86/xen/enlighten.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
arch/x86/xen/enlighten.c +13 -2
@@ -532,26 +532,37 @@
 static void xen_flush_tlb(void)
 {
 	struct mmuext_op *op;
-	struct multicall_space mcs = xen_mc_entry(sizeof(*op));
+	struct multicall_space mcs;
+
+	preempt_disable();
+
+	mcs = xen_mc_entry(sizeof(*op));
 
 	op = mcs.args;
 	op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
 	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	preempt_enable();
 }
 
 static void xen_flush_tlb_single(unsigned long addr)
 {
 	struct mmuext_op *op;
-	struct multicall_space mcs = xen_mc_entry(sizeof(*op));
+	struct multicall_space mcs;
 
+	preempt_disable();
+
+	mcs = xen_mc_entry(sizeof(*op));
 	op = mcs.args;
 	op->cmd = MMUEXT_INVLPG_LOCAL;
 	op->arg1.linear_addr = addr & PAGE_MASK;
 	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	preempt_enable();
 }
 
 static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
#18 lore raw

PATCH 1/1 xen: add missing definitions in include/xen/interface/vcpu.h which ia64/xen needs

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Add xen handles realted definitions for xen vcpu which ia64/xen needs. Pointer argumsnts for ia64/xen hypercall are passed in pseudo physical address (guest physical address) so that it is required to convert guest kernel virtual address into pseudo physical address. The xen guest handle represents such arguments.

---
 include/xen/interface/vcpu.h |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
include/xen/interface/vcpu.h +5 -0
@@ -85,6 +85,7 @@
 		 */
 		uint64_t time[4];
 };
+DEFINE_GUEST_HANDLE_STRUCT(vcpu_runstate_info);
 
 /* VCPU is currently running on a physical CPU. */
 #define RUNSTATE_running  0
@@ -119,6 +120,7 @@
 #define VCPUOP_register_runstate_memory_area 5
 struct vcpu_register_runstate_memory_area {
 		union {
+				GUEST_HANDLE(vcpu_runstate_info) h;
 				struct vcpu_runstate_info *v;
 				uint64_t p;
 		} addr;
@@ -134,6 +136,7 @@
 struct vcpu_set_periodic_timer {
 		uint64_t period_ns;
 };
+DEFINE_GUEST_HANDLE_STRUCT(vcpu_set_periodic_timer);
 
 /*
  * Set or stop a VCPU's single-shot timer. Every VCPU has one single-shot
@@ -145,6 +148,7 @@
 		uint64_t timeout_abs_ns;
 		uint32_t flags;			   /* VCPU_SSHOTTMR_??? */
 };
+DEFINE_GUEST_HANDLE_STRUCT(vcpu_set_singleshot_timer);
 
 /* Flags to VCPUOP_set_singleshot_timer. */
  /* Require the timeout to be in the future (return -ETIME if it's passed). */
@@ -164,5 +168,6 @@
     uint32_t offset; /* offset within page */
     uint32_t rsvd;   /* unused */
 };
+DEFINE_GUEST_HANDLE_STRUCT(vcpu_register_vcpu_info);
 
 #endif /* __XEN_PUBLIC_VCPU_H__ */
#19 lore raw

PATCH 1/1 xen/blkfront: use bdget_disk

In reply to Jeremy Fitzhardinge

info->dev is never initialized to anything, so bdget(info->dev) is meaningless. Get rid of info->dev, and use bdget_disk on the gendisk.

---
 drivers/block/xen-blkfront.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/block/xen-blkfront.c +1 -2
@@ -75,7 +75,6 @@
 struct blkfront_info
 {
 	struct xenbus_device *xbdev;
-	dev_t dev;
 	struct gendisk *gd;
 	int vdevice;
 	blkif_vdev_t handle;
@@ -903,7 +902,7 @@
 		break;
 
 	case XenbusStateClosing:
-		bd = bdget(info->dev);
+		bd = bdget_disk(info->gd, 0);
 		if (bd == NULL)
 			xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
#20 lore raw

PATCH 1/1 xen: make include/xen/page.h portable moving those definitions under asm dir

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

The definitions in include/asm/xen/page.h are arch specific. ia64/xen wants to define its own version. So move them to arch specific directory and keep include/xen/page.h in order not to break compilation.

---
 include/asm-x86/xen/page.h |  168 +++++++++++++++++++++++++++++++++++++++++++
 include/xen/page.h         |  169 --------------------------------------------
 2 files changed, 169 insertions(+), 168 deletions(-)
include/asm-x86/xen/page.h new file +168 -0
new file mode 100644
@@ -0,0 +1,168 @@
+#ifndef __XEN_PAGE_H
+#define __XEN_PAGE_H
+
+#include <linux/pfn.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#include <xen/features.h>
+
+/* Xen machine address */
+typedef struct xmaddr {
+	phys_addr_t maddr;
+} xmaddr_t;
+
+/* Xen pseudo-physical address */
+typedef struct xpaddr {
+	phys_addr_t paddr;
+} xpaddr_t;
+
+#define XMADDR(x)	((xmaddr_t) { .maddr = (x) })
+#define XPADDR(x)	((xpaddr_t) { .paddr = (x) })
+
+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+#define INVALID_P2M_ENTRY	(~0UL)
+#define FOREIGN_FRAME_BIT	(1UL<<31)
+#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
+
+extern unsigned long *phys_to_machine_mapping;
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return pfn;
+
+	return phys_to_machine_mapping[(unsigned int)(pfn)] &
+		~FOREIGN_FRAME_BIT;
+}
+
+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return 1;
+
+	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+}
+
+static inline unsigned long mfn_to_pfn(unsigned long mfn)
+{
+	unsigned long pfn;
+
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return mfn;
+
+#if 0
+	if (unlikely((mfn >> machine_to_phys_order) != 0))
+		return max_mapnr;
+#endif
+
+	pfn = 0;
+	/*
+	 * The array access can fail (e.g., device space beyond end of RAM).
+	 * In such cases it doesn't matter what we return (we return garbage),
+	 * but we must handle the fault without crashing!
+	 */
+	__get_user(pfn, &machine_to_phys_mapping[mfn]);
+
+	return pfn;
+}
+
+static inline xmaddr_t phys_to_machine(xpaddr_t phys)
+{
+	unsigned offset = phys.paddr & ~PAGE_MASK;
+	return XMADDR(PFN_PHYS((u64)pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
+}
+
+static inline xpaddr_t machine_to_phys(xmaddr_t machine)
+{
+	unsigned offset = machine.maddr & ~PAGE_MASK;
+	return XPADDR(PFN_PHYS((u64)mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
+}
+
+/*
+ * We detect special mappings in one of two ways:
+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
+ *     to be outside our maximum possible pseudophys range.
+ *  2. If the MFN belongs to a different domain then we will certainly
+ *     not have MFN in our p2m table. Conversely, if the page is ours,
+ *     then we'll have p2m(m2p(MFN))==MFN.
+ * If we detect a special mapping then it doesn't have a 'struct page'.
+ * We force !pfn_valid() by returning an out-of-range pointer.
+ *
+ * NB. These checks require that, for any MFN that is not in our reservation,
+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+ *
+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+{
+	extern unsigned long max_mapnr;
+	unsigned long pfn = mfn_to_pfn(mfn);
+	if ((pfn < max_mapnr)
+	    && !xen_feature(XENFEAT_auto_translated_physmap)
+	    && (phys_to_machine_mapping[pfn] != mfn))
+		return max_mapnr; /* force !pfn_valid() */
+	return pfn;
+}
+
+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap)) {
+		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+		return;
+	}
+	phys_to_machine_mapping[pfn] = mfn;
+}
+
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
+#define virt_to_mfn(v)		(pfn_to_mfn(PFN_DOWN(__pa(v))))
+#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+
+static inline unsigned long pte_mfn(pte_t pte)
+{
+	return (pte.pte & ~_PAGE_NX) >> PAGE_SHIFT;
+}
+
+static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot)
+{
+	pte_t pte;
+
+	pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) |
+		(pgprot_val(pgprot) & __supported_pte_mask);
+
+	return pte;
+}
+
+static inline pteval_t pte_val_ma(pte_t pte)
+{
+	return pte.pte;
+}
+
+static inline pte_t __pte_ma(pteval_t x)
+{
+	return (pte_t) { .pte = x };
+}
+
+#ifdef CONFIG_X86_PAE
+#define pmd_val_ma(v) ((v).pmd)
+#define pud_val_ma(v) ((v).pgd.pgd)
+#define __pmd_ma(x)	((pmd_t) { (x) } )
+#else  /* !X86_PAE */
+#define pmd_val_ma(v)	((v).pud.pgd.pgd)
+#endif	/* CONFIG_X86_PAE */
+
+#define pgd_val_ma(x)	((x).pgd)
+
+
+xmaddr_t arbitrary_virt_to_machine(unsigned long address);
+void make_lowmem_page_readonly(void *vaddr);
+void make_lowmem_page_readwrite(void *vaddr);
+
+#endif /* __XEN_PAGE_H */
include/xen/page.h +1 -168

169 lines not on this page · raw message

#21 lore raw

PATCH 1/1 Xen: Make events.c portable for ia64/xen support

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Remove x86 dependency in drivers/xen/events.c for ia64/xen support introducing include/asm/xen/events.h.
Introduce xen_irqs_disabled() to hide regs->flags
Introduce xen_do_IRQ() to hide regs->orig_ax.
make enum ipi_vector definition arch specific. ia64/xen needs four vectors. Add one rmb() because on ia64 xchg() isn't barrier.

---
 drivers/xen/events.c         |   13 +++++++------
 include/asm-x86/xen/events.h |   22 ++++++++++++++++++++++
 include/xen/events.h         |   10 +---------
 3 files changed, 30 insertions(+), 15 deletions(-)
drivers/xen/events.c +7 -6
@@ -469,7 +469,7 @@
 	for_each_online_cpu(i) {
 		struct vcpu_info *v = per_cpu(xen_vcpu, i);
 		printk("%d: masked=%d pending=%d event_sel %08lx\n  ", i,
-			(get_irq_regs() && i == cpu) ? !(get_irq_regs()->flags & X86_EFLAGS_IF) : v->evtchn_upcall_mask,
+			(get_irq_regs() && i == cpu) ? xen_irqs_disabled(get_irq_regs()) : v->evtchn_upcall_mask,
 			v->evtchn_upcall_pending,
 			v->evtchn_pending_sel);
 	}
@@ -527,7 +527,10 @@
 		if (__get_cpu_var(nesting_count)++)
 			goto out;
 
-		/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
+		/* Clear master flag /before/ clearing selector flag. */
+		rmb();
+#endif
 		pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
 		while (pending_words != 0) {
 			unsigned long pending_bits;
@@ -539,10 +542,8 @@
 				int port = (word_idx * BITS_PER_LONG) + bit_idx;
 				int irq = evtchn_to_irq[port];
 
-				if (irq != -1) {
-					regs->orig_ax = ~irq;
-					do_IRQ(regs);
-				}
+				if (irq != -1)
+					xen_do_IRQ(irq, regs);
 			}
 		}
 
include/asm-x86/xen/events.h new file +22 -0
new file mode 100644
@@ -0,0 +1,22 @@
+#ifndef __XEN_EVENTS_H
+#define __XEN_EVENTS_H
+
+enum ipi_vector {
+	XEN_RESCHEDULE_VECTOR,
+	XEN_CALL_FUNCTION_VECTOR,
+
+	XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+	return raw_irqs_disabled_flags(regs->flags);
+}
+
+static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
+{
+	regs->orig_ax = ~irq;
+	do_IRQ(regs);
+}
+
+#endif /* __XEN_EVENTS_H */
include/xen/events.h +1 -7
@@ -5,13 +5,7 @@
 
 #include <xen/interface/event_channel.h>
 #include <asm/xen/hypercall.h>
-
-enum ipi_vector {
-	XEN_RESCHEDULE_VECTOR,
-	XEN_CALL_FUNCTION_VECTOR,
-
-	XEN_NR_IPIS,
-};
+#include <asm/xen/events.h>
 
 int bind_evtchn_to_irq(unsigned int evtchn);
 int bind_evtchn_to_irqhandler(unsigned int evtchn,
#22 lore raw

[PATCH 08 of 24] Re: [PATCH 08/12] xen: add resend_irq_on_evtchn() definition into events.c

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Define resend_irq_on_evtchn() which ia64/xen uses. Although it isn't used by current x86/xen code, it's arch generic so that put it into common code.

---
 drivers/xen/events.c |   16 ++++++++++++++++
 include/xen/events.h |    3 +--
 2 files changed, 17 insertions(+), 2 deletions(-)
drivers/xen/events.c +16 -0
@@ -586,6 +586,22 @@
 	rebind_irq_to_cpu(irq, tcpu);
 }
 
+int resend_irq_on_evtchn(unsigned int irq)
+{
+	int masked, evtchn = evtchn_from_irq(irq);
+	struct shared_info *s = HYPERVISOR_shared_info;
+
+	if (!VALID_EVTCHN(evtchn))
+		return 1;
+
+	masked = sync_test_and_set_bit(evtchn, s->evtchn_mask);
+	sync_set_bit(evtchn, s->evtchn_pending);
+	if (!masked)
+		unmask_evtchn(evtchn);
+
+	return 1;
+}
+
 static void enable_dynirq(unsigned int irq)
 {
 	int evtchn = evtchn_from_irq(irq);
include/xen/events.h +1 -0
@@ -31,6 +31,7 @@
 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
 
 void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector);
+int resend_irq_on_evtchn(unsigned int irq);
 
 static inline void notify_remote_via_evtchn(int port)
 {
#23 lore raw

PATCH 1/1 xen: replace callers of alloc_vm_area()/free_vm_area() with xen_ prefixed one

In reply to Jeremy Fitzhardinge

From: Isaku Yamahata <[email protected]>

Don't use alloc_vm_area()/free_vm_area() directly, instead define xen_alloc_vm_area()/xen_free_vm_area() and use them.

alloc_vm_area()/free_vm_area() are used to allocate/free area which are for grant table mapping. Xen/x86 grant table is based on virtual address so that alloc_vm_area()/free_vm_area() are suitable. On the other hand Xen/ia64 (and Xen/powerpc) grant table is based on pseudo physical address (guest physical address) so that allocation should be done differently.
The original version of xenified Linux/IA64 have its own allocate_vm_area()/free_vm_area() definitions which don't allocate vm area contradictory to those names.
Now vanilla Linux already has its definitions so that it's impossible to have IA64 definitions of allocate_vm_area()/free_vm_area(). Instead introduce xen_allocate_vm_area()/xen_free_vm_area() and use them.

---
 drivers/xen/grant-table.c          |    2 +-
 drivers/xen/xenbus/xenbus_client.c |    6 +++---
 include/asm-x86/xen/grant_table.h  |    7 +++++++
 include/xen/grant_table.h          |    3 +--
 4 files changed, 12 insertions(+), 6 deletions(-)
drivers/xen/grant-table.c +1 -1
@@ -478,7 +478,7 @@
 
 	if (shared == NULL) {
 		struct vm_struct *area;
-		area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
+		area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
 		BUG_ON(area == NULL);
 		shared = area->addr;
 	}
drivers/xen/xenbus/xenbus_client.c +3 -3
@@ -399,7 +399,7 @@
 
 	*vaddr = NULL;
 
-	area = alloc_vm_area(PAGE_SIZE);
+	area = xen_alloc_vm_area(PAGE_SIZE);
 	if (!area)
 		return -ENOMEM;
 
@@ -409,7 +409,7 @@
 		BUG();
 
 	if (op.status != GNTST_okay) {
-		free_vm_area(area);
+		xen_free_vm_area(area);
 		xenbus_dev_fatal(dev, op.status,
 				 "mapping in shared page %d from domain %d",
 				 gnt_ref, dev->otherend_id);
@@ -508,7 +508,7 @@
 		BUG();
 
 	if (op.status == GNTST_okay)
-		free_vm_area(area);
+		xen_free_vm_area(area);
 	else
 		xenbus_dev_error(dev, op.status,
 				 "unmapping page at handle %d error %d",
include/asm-x86/xen/grant_table.h new file +7 -0
new file mode 100644
@@ -0,0 +1,7 @@
+#ifndef __XEN_GRANT_TABLE_H
+#define __XEN_GRANT_TABLE_H
+
+#define xen_alloc_vm_area(size)	alloc_vm_area(size)
+#define xen_free_vm_area(area)	free_vm_area(area)
+
+#endif /* __XEN_GRANT_TABLE_H */
include/xen/grant_table.h +1 -0
@@ -39,6 +39,7 @@
 
 #include <asm/xen/hypervisor.h>
 #include <xen/interface/grant_table.h>
+#include <asm/xen/grant_table.h>
 
 /* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
 #define NR_GRANT_FRAMES 4
#24 lore raw

PATCH 1/1 xen: Make xen-blkfront write its protocol ABI to xenstore

In reply to Jeremy Fitzhardinge

From: Markus Armbruster <[email protected]>

Frontends are expected to write their protocol ABI to xenstore. Since the protocol ABI defaults to the backend's native ABI, things work fine without that as long as the frontend's native ABI is identical to the backend's native ABI. This is not the case for xen-blkfront running 32-on-64, because its ABI differs between 32 and 64 bit, and thus needs this fix.

Based on http://xenbits.xensource.com/xen-unstable.hg?rev/c545932a18f3
and http://xenbits.xensource.com/xen-unstable.hg?rev/ffe52263b430 by Gerd Hoffmann <[email protected]>

---
 drivers/block/xen-blkfront.c         |    7 +++++++
 include/xen/interface/io/protocols.h |   22 +++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)
drivers/block/xen-blkfront.c +7 -0
@@ -47,6 +47,7 @@
 
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/blkif.h>
+#include <xen/interface/io/protocols.h>
 
 #include <asm/xen/hypervisor.h>
 
@@ -614,6 +615,12 @@
 		message = "writing event-channel";
 		goto abort_transaction;
 	}
+	err = xenbus_printf(xbt, dev->nodename, "protocol", "%s",
+			    XEN_IO_PROTO_ABI_NATIVE);
+	if (err) {
+		message = "writing protocol";
+		goto abort_transaction;
+	}
 
 	err = xenbus_transaction_end(xbt, 0);
 	if (err) {
include/xen/interface/io/protocols.h new file +21 -0
new file mode 100644
@@ -0,0 +1,21 @@
+#ifndef __XEN_PROTOCOLS_H__
+#define __XEN_PROTOCOLS_H__
+
+#define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
+#define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
+#define XEN_IO_PROTO_ABI_IA64       "ia64-abi"
+#define XEN_IO_PROTO_ABI_POWERPC64  "powerpc64-abi"
+
+#if defined(__i386__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
+#elif defined(__x86_64__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
+#elif defined(__ia64__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
+#elif defined(__powerpc64__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
+#else
+# error arch fixup needed here
+#endif
+
+#endif
#25 lore raw

PATCH 1/1 xen: Add compatibility aliases for frontend drivers

In reply to Jeremy Fitzhardinge

From: Mark McLoughlin <[email protected]>

Before getting merged, xen-blkfront was xenblk and xen-netfront was xennet.

Temporarily adding compatibility module aliases eases upgrades from older versions by e.g. allowing mkinitrd to find the new version of the module.

---
 drivers/block/xen-blkfront.c |    1 +
 drivers/net/xen-netfront.c   |    2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/block/xen-blkfront.c +1 -0
@@ -1016,3 +1016,4 @@
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR);
 MODULE_ALIAS("xen:vbd");
+MODULE_ALIAS("xenblk");
drivers/net/xen-netfront.c +1 -0
@@ -1810,3 +1810,4 @@
 MODULE_DESCRIPTION("Xen virtual network device frontend");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("xen:vif");
+MODULE_ALIAS("xennet");
#26 lore raw

PATCH 1/1 xen pvfb: Para-virtual framebuffer, keyboard and pointer driver

In reply to Jeremy Fitzhardinge

From: Markus Armbruster <[email protected]>

This is a pair of Xen para-virtual frontend device drivers:
drivers/video/xen-fbfront.c provides a framebuffer, and drivers/input/xen-kbdfront provides keyboard and mouse.

The backends run in dom0 user space.

The two drivers are not in two separate patches, because the intermediate step (one driver, not the other) is somewhat problematic:
the backend in dom0 needs both drivers, and will refuse to complete device initialization unless they're both present.

---
 drivers/input/Kconfig            |    9
 drivers/input/Makefile           |    2
 drivers/input/xen-kbdfront.c     |  340 +++++++++++++++++++++++
 drivers/video/Kconfig            |   14
 drivers/video/Makefile           |    1
 drivers/video/xen-fbfront.c      |  550 ++++++++++++++++++++++++++++++++++++++
 include/xen/interface/io/fbif.h  |  124 ++++++++
 include/xen/interface/io/kbdif.h |  114 +++++++
 8 files changed, 1154 insertions(+)
drivers/input/Kconfig +9 -0
@@ -149,6 +149,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called apm-power.
 
+config XEN_KBDDEV_FRONTEND
+	tristate "Xen virtual keyboard and mouse support"
+	depends on XEN_FBDEV_FRONTEND
+	default y
+	help
+	  This driver implements the front-end of the Xen virtual
+	  keyboard and mouse device driver.  It communicates with a back-end
+	  in another domain.
+
 comment "Input Device Drivers"
 
 source "drivers/input/keyboard/Kconfig"
drivers/input/Makefile +2 -0
@@ -23,3 +23,5 @@
 obj-$(CONFIG_INPUT_MISC)	+= misc/
 
 obj-$(CONFIG_INPUT_APMPOWER)	+= apm-power.o
+
+obj-$(CONFIG_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
drivers/input/xen-kbdfront.c new file +340 -0

340 lines not on this page · raw message

drivers/video/Kconfig +14 -0
@@ -1930,6 +1930,20 @@
 
 	  If unsure, say N.
 
+config XEN_FBDEV_FRONTEND
+	tristate "Xen virtual frame buffer support"
+	depends on FB && XEN
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	default y
+	help
+	  This driver implements the front-end of the Xen virtual
+	  frame buffer driver.  It communicates with a back-end
+	  in another domain.
+
 source "drivers/video/omap/Kconfig"
 
 source "drivers/video/backlight/Kconfig"
drivers/video/Makefile +1 -0
@@ -114,6 +114,7 @@
 obj-$(CONFIG_FB_SM501)            += sm501fb.o
 obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
 obj-$(CONFIG_FB_OMAP)             += omap/
+obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_UVESA)            += uvesafb.o
drivers/video/xen-fbfront.c new file +550 -0

550 lines not on this page · raw message

include/xen/interface/io/fbif.h new file +124 -0

124 lines not on this page · raw message

include/xen/interface/io/kbdif.h new file +114 -0

114 lines not on this page · raw message

#27 lore raw
In reply to Jeremy Fitzhardinge
Quoted 4 lines · Jeremy Fitzhardinge

Hi Ingo,

More patches. There are three groups:

Quoted 8 lines

- some code movements to make common code available to other architectures (namely, ia64)
- Xen device driver updates, including a new xen paravirt framebuffer driver,
- The Xen balloon driver (shrink only, so no dependency on memory hotplug yet)
- some "using smp_processor_id while preemptable" warning fixes, mostly as a result of the core kernel's tendency to do tlb flushes and update init_mm while preemptable,
- other little Xen cleanups

thanks, applied for testing. The .25 Xen items we've got queued up are:

Subject: xen: refactor xen_{alloc,release}_{pte,pmd}()
Subject: xen: do not pin/unpin PMD pages
Subject: xen: clear PG_pinned in release_{pte,pmd}()

anything missing?

Ingo

#28 lore raw
Quoted 17 lines · Ingo Molnar
Quoted 4 lines · Jeremy Fitzhardinge

Hi Ingo,

More patches. There are three groups:

Quoted 9 lines

- some code movements to make common code available to other architectures (namely, ia64)
- Xen device driver updates, including a new xen paravirt framebuffer driver,
- The Xen balloon driver (shrink only, so no dependency on memory hotplug yet)
- some "using smp_processor_id while preemptable" warning fixes, mostly as a result of the core kernel's tendency to do tlb flushes and update init_mm while preemptable,
- other little Xen cleanups

Quoted 6 lines

thanks, applied for testing. The .25 Xen items we've got queued up are:

Subject: xen: refactor xen_{alloc,release}_{pte,pmd}()
Subject: xen: do not pin/unpin PMD pages
Subject: xen: clear PG_pinned in release_{pte,pmd}()

Mark just posted another bugfix patch - attached.

J

Subject: xen: Fix grant table bug

From: Michael Abd-El-Malek <[email protected]>

A PV OS has two grant table data structures: the grant table itself and a free list. The free list is composed of an array of pages, which grow dynamically as the guest OS requires more grants. While the grant table contains 8-byte entries, the free list contains 4-byte entries. So we have half as many pages in the free list than in the grant table.

There was a bug in the free list allocation code. The free list was indexed as if it was the same size as the grant table. But it's only half as large. So memory got corrupted, and I was seeing crashes in the slab allocator later on.

Taken from:

http://xenbits.xensource.com/linux-2.6.18-xen.hg?rev/4018c0da3360

---
 drivers/xen/grant-table.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

===================================================================

drivers/xen/grant-table.c +10 -6
@@ -381,11 +381,15 @@ EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback);
 static int grow_gnttab_list(unsigned int more_frames)
 {
 	unsigned int new_nr_grant_frames, extra_entries, i;
+	unsigned int nr_glist_frames, new_nr_glist_frames;
 
 	new_nr_grant_frames = nr_grant_frames + more_frames;
 	extra_entries       = more_frames * GREFS_PER_GRANT_FRAME;
 
-	for (i = nr_grant_frames; i < new_nr_grant_frames; i++) {
+	nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
+	new_nr_glist_frames =
+		(new_nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
+	for (i = nr_glist_frames; i < new_nr_glist_frames; i++) {
 		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC);
 		if (!gnttab_list[i])
 			goto grow_nomem;
@@ -407,7 +411,7 @@ static int grow_gnttab_list(unsigned int more_frames)
 	return 0;
 
 grow_nomem:
-	for ( ; i >= nr_grant_frames; i--)
+	for ( ; i >= nr_glist_frames; i--)
 		free_page((unsigned long) gnttab_list[i]);
 	return -ENOMEM;
 }
@@ -530,7 +534,7 @@ static int gnttab_expand(unsigned int req_entries)
 static int __devinit gnttab_init(void)
 {
 	int i;
-	unsigned int max_nr_glist_frames;
+	unsigned int max_nr_glist_frames, nr_glist_frames;
 	unsigned int nr_init_grefs;
 
 	if (!is_running_on_xen())
@@ -543,15 +547,15 @@ static int __devinit gnttab_init(void)
 	 * grant reference free list on the current hypervisor.
 	 */
 	max_nr_glist_frames = (boot_max_nr_grant_frames *
-			       GREFS_PER_GRANT_FRAME /
-			       (PAGE_SIZE / sizeof(grant_ref_t)));
+			       GREFS_PER_GRANT_FRAME / RPP);
 
 	gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
 			      GFP_KERNEL);
 	if (gnttab_list == NULL)
 		return -ENOMEM;
 
-	for (i = 0; i < nr_grant_frames; i++) {
+	nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP;
+	for (i = 0; i < nr_glist_frames; i++) {
 		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
 		if (gnttab_list[i] == NULL)
 			goto ini_nomem;
Signature · 4 lines
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel