PERFORCE change 89545 for review

Kip Macy kmacy at FreeBSD.org
Wed Jan 11 23:17:17 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=89545

Change 89545 by kmacy at kmacy:freebsd7_xen3 on 2006/01/12 07:16:57

	general summary: import routine for contiguous memory allocation, clean up defines slightly,
	and enable more hardware support 
	
	add in balloon driver
	only probe video card if we're dom0
	ifdef out most of balloon driver for the moment for the sake of clean compilation
	enable PCI in XENCONF
	suck in functions into clock.c to satisfy link requirements
	import functions from xenlinux for allocating contiguous extents
	legacy bus should only probe child busses if we're running privileged
	shuffle some defines off into headers	

Affected files ...

.. //depot/projects/xen3/src/sys/conf/files.i386-xen#3 edit
.. //depot/projects/xen3/src/sys/dev/syscons/syscons.c#2 edit
.. //depot/projects/xen3/src/sys/dev/xen/balloon/balloon.c#3 edit
.. //depot/projects/xen3/src/sys/i386-xen/conf/XENCONF#3 edit
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#9 edit
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/evtchn.c#3 edit
.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#7 edit
.. //depot/projects/xen3/src/sys/i386-xen/include/pmap.h#3 edit
.. //depot/projects/xen3/src/sys/i386-xen/include/xenfunc.h#2 edit
.. //depot/projects/xen3/src/sys/i386-xen/include/xenpmap.h#2 edit
.. //depot/projects/xen3/src/sys/i386-xen/include/xenvar.h#4 edit
.. //depot/projects/xen3/src/sys/i386/i386/legacy.c#2 edit

Differences ...

==== //depot/projects/xen3/src/sys/conf/files.i386-xen#3 (text+ko) ====

@@ -455,3 +455,4 @@
 dev/xen/xenbus/xenbus_xs.c	standard
 dev/xen/blkfront/blkfront.c	standard
 dev/xen/netfront/netfront.c	standard
+dev/xen/balloon/balloon.c	standard

==== //depot/projects/xen3/src/sys/dev/syscons/syscons.c#2 (text+ko) ====

@@ -1390,6 +1390,10 @@
     int unit;
     int flags;
 
+#ifdef XEN
+    if (!(xen_start_info->flags & SIF_INITDOMAIN))
+	return;
+#endif
     cp->cn_pri = sc_get_cons_priority(&unit, &flags);
 
     /* a video card is always required */

==== //depot/projects/xen3/src/sys/dev/xen/balloon/balloon.c#3 (text+ko) ====

@@ -42,7 +42,8 @@
  * Also protects non-atomic updates of current_pages and driver_pages, and
  * balloon lists.
  */
-struct mtx_lock balloon_lock;
+struct mtx balloon_lock;
+#ifdef notyet
 
 /* We aim for 'current allocation' == 'target allocation'. */
 static unsigned long current_pages;
@@ -439,3 +440,4 @@
 	wakeup(balloon_process);
 }
 
+#endif

==== //depot/projects/xen3/src/sys/i386-xen/conf/XENCONF#3 (text+ko) ====

@@ -65,6 +65,9 @@
 #options 	SMP		# Symmetric MultiProcessor Kernel
 device		apic		# I/O APIC
 
+# Bus support
+device          pci
+
 # SCSI peripherals
 device		scbus		# SCSI bus (required for SCSI)
 #device		ch		# SCSI media changers

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#9 (text+ko) ====

@@ -70,6 +70,7 @@
 #include <machine/smp.h>
 #endif
 #include <machine/specialreg.h>
+#include <machine/timerreg.h>
 
 #include <i386/isa/icu.h>
 #include <i386/isa/isa.h>
@@ -104,8 +105,9 @@
 int     independent_wallclock;
 u_int	timer_freq = TIMER_FREQ;
 struct mtx clock_lock;
+#define	RTC_LOCK	mtx_lock_spin(&clock_lock)
+#define	RTC_UNLOCK	mtx_unlock_spin(&clock_lock)
 
-
 static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
 
 /* Values for timerX_state: */
@@ -114,6 +116,8 @@
 #define	ACQUIRED	2
 #define	ACQUIRE_PENDING	3
 
+static	u_char	timer2_state;
+
 /* Cached *multiplier* to convert TSC counts to microseconds.
  * (see the equation below).
  * Equal to 2^32 * (1 / (clocks per usec) ).
@@ -718,6 +722,76 @@
 }
 #endif
 
+
+/*
+ * RTC support routines
+ */
+
+int
+rtcin(reg)
+	int reg;
+{
+	u_char val;
+
+	RTC_LOCK;
+	outb(IO_RTC, reg);
+	inb(0x84);
+	val = inb(IO_RTC + 1);
+	inb(0x84);
+	RTC_UNLOCK;
+	return (val);
+}
+
+static __inline void
+writertc(u_char reg, u_char val)
+{
+
+	RTC_LOCK;
+	inb(0x84);
+	outb(IO_RTC, reg);
+	inb(0x84);
+	outb(IO_RTC + 1, val);
+	inb(0x84);		/* XXX work around wrong order in rtcin() */
+	RTC_UNLOCK;
+}
+
+static __inline int
+readrtc(int port)
+{
+	return(bcd2bin(rtcin(port)));
+}
+
+int
+acquire_timer2(int mode)
+{
+
+	if (timer2_state != RELEASED)
+		return (-1);
+	timer2_state = ACQUIRED;
+
+	/*
+	 * This access to the timer registers is as atomic as possible
+	 * because it is a single instruction.  We could do better if we
+	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
+	 * and this is probably good enough for timer2, so we aren't as
+	 * careful with it as with timer0.
+	 */
+	outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
+
+	return (0);
+}
+
+int
+release_timer2()
+{
+
+	if (timer2_state != ACQUIRED)
+		return (-1);
+	timer2_state = RELEASED;
+	outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
+	return (0);
+}
+
 /*
  * Start clocks running.
  */

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/evtchn.c#3 (text+ko) ====

@@ -30,14 +30,6 @@
  */
 
 
-#define BITS_PER_LONG 32
-#define NR_CPUS      MAX_VIRT_CPUS
-
-#define BITS_TO_LONGS(bits) \
-	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define DECLARE_BITMAP(name,bits) \
-	unsigned long name[BITS_TO_LONGS(bits)]
-typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } xen_cpumask_t;
 static inline int find_first_bit(const unsigned long *addr, unsigned size)
 {
 	int d0, d1;

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#7 (text+ko) ====

@@ -54,6 +54,8 @@
 #include <machine/md_var.h>
 #include <machine/asmacros.h>
 #include <machine/xenbus.h>
+#include <machine/xenfunc.h>
+#include <machine/xen-public/memory.h>
 
 #define	IDTVEC(name)	__CONCAT(X,name)
 
@@ -334,6 +336,186 @@
 }
 
 
+/*
+ * Bitmap is indexed by page number. If bit is set, the page is part of a
+ * xen_create_contiguous_region() area of memory.
+ */
+unsigned long *contiguous_bitmap;
+
+static void 
+contiguous_bitmap_set(unsigned long first_page, unsigned long nr_pages)
+{
+	unsigned long start_off, end_off, curr_idx, end_idx;
+
+	curr_idx  = first_page / BITS_PER_LONG;
+	start_off = first_page & (BITS_PER_LONG-1);
+	end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
+	end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+	if (curr_idx == end_idx) {
+		contiguous_bitmap[curr_idx] |=
+			((1UL<<end_off)-1) & -(1UL<<start_off);
+	} else {
+		contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
+		while ( ++curr_idx < end_idx )
+			contiguous_bitmap[curr_idx] = ~0UL;
+		contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
+	}
+}
+
+static void 
+contiguous_bitmap_clear(unsigned long first_page, unsigned long nr_pages)
+{
+	unsigned long start_off, end_off, curr_idx, end_idx;
+
+	curr_idx  = first_page / BITS_PER_LONG;
+	start_off = first_page & (BITS_PER_LONG-1);
+	end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
+	end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+	if (curr_idx == end_idx) {
+		contiguous_bitmap[curr_idx] &=
+			-(1UL<<end_off) | ((1UL<<start_off)-1);
+	} else {
+		contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
+		while ( ++curr_idx != end_idx )
+			contiguous_bitmap[curr_idx] = 0;
+		contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
+	}
+}
+
+/* Ensure multi-page extents are contiguous in machine memory. */
+int 
+xen_create_contiguous_region(vm_page_t pages, int npages)
+{
+	unsigned long  mfn, i, flags;
+	int order;
+	struct xen_memory_reservation reservation = {
+		.extent_start = &mfn,
+		.nr_extents   = 1,
+		.extent_order = 0,
+		.domid        = DOMID_SELF
+	};
+
+	balloon_lock(flags);
+
+	/* can currently only handle power of two allocation */
+	PANIC_IF(ffs(npages) != fls(npages));
+
+	/* 0. determine order */
+	order = (ffs(npages) == fls(npages)) ? fls(npages) : (ffs(npages) + 1);
+	
+	/* 1. give away machine pages. */
+	for (i = 0; i < (1 << order); i++) {
+		int pfn;
+		pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
+		mfn = PFNTOMFN(pfn);
+		PFNTOMFN(pfn) = INVALID_P2M_ENTRY;
+		PANIC_IF(HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) != 1);
+	}
+
+
+	/* 2. Get a new contiguous memory extent. */
+	reservation.extent_order = order;
+	/* xenlinux hardcodes this because of aacraid - maybe set to 0 if we're not 
+	 * running with a broxen driver XXXEN
+	 */
+	reservation.address_bits = 31; 
+	if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &reservation) != 1)
+		goto fail;
+
+	/* 3. Map the new extent in place of old pages. */
+	for (i = 0; i < (1 << order); i++) {
+		int pfn;
+		pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
+		xen_machphys_update(mfn+i, pfn);
+		PFNTOMFN(pfn) = mfn+i;
+	}
+
+	xen_tlb_flush();
+
+	contiguous_bitmap_set(VM_PAGE_TO_PHYS(&pages[0]) >> PAGE_SHIFT, 1UL << order);
+
+	balloon_unlock(flags);
+
+	return 0;
+
+ fail:
+	reservation.extent_order = 0;
+	reservation.address_bits = 0;
+
+	for (i = 0; i < (1 << order); i++) {
+		int pfn;
+		pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
+		PANIC_IF(HYPERVISOR_memory_op(
+			XENMEM_increase_reservation, &reservation) != 1);
+		xen_machphys_update(mfn, pfn);
+		PFNTOMFN(pfn) = mfn;
+	}
+
+	xen_tlb_flush();
+
+	balloon_unlock(flags);
+
+	return ENOMEM;
+}
+
+void 
+xen_destroy_contiguous_region(void *addr, int npages)
+{
+	unsigned long  mfn, i, flags, order, pfn0;
+	struct xen_memory_reservation reservation = {
+		.extent_start = &mfn,
+		.nr_extents   = 1,
+		.extent_order = 0,
+		.domid        = DOMID_SELF
+	};
+
+	pfn0 = vtophys(addr) >> PAGE_SHIFT;
+#if 0
+	scrub_pages(vstart, 1 << order);
+#endif
+	/* can currently only handle power of two allocation */
+	PANIC_IF(ffs(npages) != fls(npages));
+
+	/* 0. determine order */
+	order = (ffs(npages) == fls(npages)) ? fls(npages) : (ffs(npages) + 1);
+
+	balloon_lock(flags);
+
+	contiguous_bitmap_clear(vtophys(addr) >> PAGE_SHIFT, 1UL << order);
+
+	/* 1. Zap current PTEs, giving away the underlying pages. */
+	for (i = 0; i < (1 << order); i++) {
+		int pfn;
+		pte_t new_val = {0};
+		pfn = vtomach((char *)addr + i*PAGE_SIZE) >> PAGE_SHIFT;
+
+		PANIC_IF(HYPERVISOR_update_va_mapping((vm_offset_t)((char *)addr + (i * PAGE_SIZE)), new_val, 0));
+		PFNTOMFN(pfn) = INVALID_P2M_ENTRY;
+		PANIC_IF(HYPERVISOR_memory_op(
+			XENMEM_decrease_reservation, &reservation) != 1);
+	}
+
+	/* 2. Map new pages in place of old pages. */
+	for (i = 0; i < (1 << order); i++) {
+		int pfn;
+		pte_t new_val;
+		pfn = pfn0 + i;
+		PANIC_IF(HYPERVISOR_memory_op(XENMEM_increase_reservation, &reservation) != 1);
+		
+		new_val.pte_low = mfn << PAGE_SHIFT;
+		PANIC_IF(HYPERVISOR_update_va_mapping((vm_offset_t)addr + (i * PAGE_SIZE), 
+						      new_val, PG_KERNEL));
+		xen_machphys_update(mfn, pfn);
+		PFNTOMFN(pfn) = mfn;
+	}
+
+	xen_tlb_flush();
+
+	balloon_unlock(flags);
+}
+
 extern unsigned long cpu0prvpage;
 extern unsigned long *SMPpt;
 extern  struct user	*proc0uarea;
@@ -346,12 +528,6 @@
 struct ringbuf_head *xen_store; /* XXX move me */
 char *console_page;
 
-#define PFN_UP(x)    (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define VTOP(x) ((unsigned long)(x) - KERNBASE)
-#define VTOPFN(x) (((unsigned long)(x) - KERNBASE) >> PAGE_SHIFT)
-#define PFNTOV(x) (((unsigned long)(x)  << PAGE_SHIFT) + KERNBASE)
-#define PG_KERNEL  (PG_V | PG_A | PG_RW | PG_M)
-
 void *
 bootmem_alloc(unsigned int size) 
 {
@@ -560,8 +736,9 @@
 };
 
 
-static void shutdown_handler(struct xenbus_watch *watch,
-			     const char **vec, unsigned int len)
+static void 
+shutdown_handler(struct xenbus_watch *watch,
+		 const char **vec, unsigned int len)
 {
 	char *str;
 	struct xenbus_transaction *xbt;

==== //depot/projects/xen3/src/sys/i386-xen/include/pmap.h#3 (text+ko) ====

@@ -70,6 +70,8 @@
 #define	PG_PROT		(PG_RW|PG_U)	/* all protection bits . */
 #define PG_N		(PG_NC_PWT|PG_NC_PCD)	/* Non-cacheable */
 
+#define PG_KERNEL  (PG_V | PG_A | PG_RW | PG_M)
+
 /*
  * Page Protection Exception bits
  */
@@ -430,6 +432,8 @@
 void	pmap_kenter_ma(vm_offset_t va, vm_paddr_t pa);
 void    pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len);
 void    pmap_map_readwrite(pmap_t pmap, vm_offset_t va, int len);
+
+
 #endif /* _KERNEL */
 
 #endif /* !LOCORE */

==== //depot/projects/xen3/src/sys/i386-xen/include/xenfunc.h#2 (text+ko) ====

@@ -1,6 +1,5 @@
 /*
  *
- * Copyright (c) 2004 Christian Limpach.
  * Copyright (c) 2004,2005 Kip Macy
  * All rights reserved.
  *
@@ -12,9 +11,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Christian Limpach.
  * 4. The name of the author may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
@@ -56,10 +52,19 @@
 #endif
 
 char *xen_setbootenv(char *cmd_line);
-int xen_boothowto(char *envp);
+
+int  xen_boothowto(char *envp);
+
 void xen_machphys_update(unsigned long, unsigned long);
+
 void xen_update_descriptor(union descriptor *, union descriptor *);
+
 void ap_cpu_initclocks(void);
 
+extern struct mtx balloon_lock;
+#define balloon_lock(__flags)   mtx_lock_irqsave(&balloon_lock, __flags)
+#define balloon_unlock(__flags) mtx_unlock_irqrestore(&balloon_lock, __flags)
+
+
 
 #endif /* _XEN_XENFUNC_H_ */

==== //depot/projects/xen3/src/sys/i386-xen/include/xenpmap.h#2 (text+ko) ====

@@ -71,6 +71,8 @@
 #define PT_LOG()
 #endif
 
+#define INVALID_P2M_ENTRY	(~0UL)
+
 #define pmap_valid_entry(E)           ((E) & PG_V) /* is PDE or PTE valid? */
 
 #define SH_PD_SET_VA        1

==== //depot/projects/xen3/src/sys/i386-xen/include/xenvar.h#4 (text+ko) ====

@@ -19,14 +19,26 @@
 #define PFNTOMFN(i) (((unsigned long *)xen_phys_machine)[i])
 #define MFNTOPFN(i) (xen_machine_phys[i])
 #define VTOMFN(va) (vtomach(va) >> PAGE_SHIFT)
+#define PFN_UP(x)    (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define VTOP(x) ((unsigned long)(x) - KERNBASE)
+#define VTOPFN(x) (((unsigned long)(x) - KERNBASE) >> PAGE_SHIFT)
+#define PFNTOV(x) (((unsigned long)(x)  << PAGE_SHIFT) + KERNBASE)
+
 #define phystomach(pa) ((((unsigned long *)xen_phys_machine)[(pa >> PAGE_SHIFT)]) << PAGE_SHIFT)
 void xpq_init(void);
 
-struct sockaddr_in;
- 
-int xen_setnfshandle(void);
-int setinaddr(struct sockaddr_in *addr,  char *ipstr);
+#define BITS_PER_LONG 32
+#define NR_CPUS      MAX_VIRT_CPUS
+
+#define BITS_TO_LONGS(bits) \
+	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
+#define DECLARE_BITMAP(name,bits) \
+	unsigned long name[BITS_TO_LONGS(bits)]
+typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } xen_cpumask_t;
+
+int  xen_create_contiguous_region(vm_page_t pages, int npages);
+
+void  xen_destroy_contiguous_region(void * addr, int npages);
 
-#define RB_GDB_PAUSE RB_RESERVED1 
 
 #endif

==== //depot/projects/xen3/src/sys/i386/i386/legacy.c#2 (text+ko) ====

@@ -147,6 +147,11 @@
 				panic("legacy_attach cpu");
 			device_probe_and_attach(child);
 		}
+	
+#ifdef XEN
+	if (!(xen_start_info->flags & SIF_PRIVILEGED))
+		return 0;
+#endif
 
 	/*
 	 * Second, let our child driver's identify any child devices that


More information about the p4-projects mailing list