aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse
diff options
context:
space:
mode:
authorach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2003-03-05 20:14:40 +0000
committerach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2003-03-05 20:14:40 +0000
commitf3c8dfc6270a0d4ac5f81d64b59a42623e45f82e (patch)
tree1f240422ead5b60bafe8126e850d92338ba6e40e /xenolinux-2.4.21-pre4-sparse
parenta474d07ad6848eb61c591d57ff64400d66cd9007 (diff)
parentdfca2c82d597482bab554fd1256cdb13154efba7 (diff)
downloadxen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.tar.gz
xen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.tar.bz2
xen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.zip
bitkeeper revision 1.107 (3e665ab0XNZynD-498WHLN1g1IPRrw)
Merge labyrinth.cl.cam.ac.uk:/usr/groups/xeno/BK/xeno.bk into labyrinth.cl.cam.ac.uk:/anfs/scratch/boulderdash/ach61/xeno/xeno.bk
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/Makefile5
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile5
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile3
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c275
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h32
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c2
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c57
-rw-r--r--xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h11
-rw-r--r--xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h4
9 files changed, 375 insertions, 19 deletions
diff --git a/xenolinux-2.4.21-pre4-sparse/Makefile b/xenolinux-2.4.21-pre4-sparse/Makefile
index d7a36f6fe0..29cdd72d2a 100644
--- a/xenolinux-2.4.21-pre4-sparse/Makefile
+++ b/xenolinux-2.4.21-pre4-sparse/Makefile
@@ -8,7 +8,8 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
# Xeno hack XXX
-ARCH=xeno
+ARCH := xeno
+SUBARCH := i386
KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
@@ -361,7 +362,7 @@ include/linux/version.h: ./Makefile
comma := ,
init/version.o: init/version.c include/linux/compile.h include/config/MARKER
- $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c
+ $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(SUBARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c
init/main.o: init/main.c include/config/MARKER
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $@ $<
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile b/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile
index 544af84605..557fe98217 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile
@@ -47,12 +47,14 @@ HEAD := arch/xeno/kernel/head.o arch/xeno/kernel/init_task.o
SUBDIRS += arch/xeno/kernel arch/xeno/mm arch/xeno/lib
SUBDIRS += arch/xeno/drivers/console arch/xeno/drivers/network
SUBDIRS += arch/xeno/drivers/dom0 arch/xeno/drivers/block
+SUBDIRS += arch/xeno/drivers/balloon
CORE_FILES += arch/xeno/kernel/kernel.o arch/xeno/mm/mm.o
CORE_FILES += arch/xeno/drivers/console/con.o
CORE_FILES += arch/xeno/drivers/block/blk.o
CORE_FILES += arch/xeno/drivers/network/net.o
CORE_FILES += arch/xeno/drivers/dom0/dom0.o
+CORE_FILES += arch/xeno/drivers/balloon/balloon_driver.o
LIBS := $(TOPDIR)/arch/xeno/lib/lib.a $(LIBS) $(TOPDIR)/arch/xeno/lib/lib.a
arch/xeno/kernel: dummy
@@ -73,6 +75,9 @@ arch/xeno/drivers/block: dummy
arch/xeno/drivers/dom0: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/dom0
+arch/xeno/drivers/balloon: dummy
+ $(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/balloon
+
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/xeno/vmlinux.lds
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile
new file mode 100644
index 0000000000..f780a515e0
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile
@@ -0,0 +1,3 @@
+O_TARGET := balloon_driver.o
+obj-y := balloon.o
+include $(TOPDIR)/Rules.make
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c
new file mode 100644
index 0000000000..abe5884800
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c
@@ -0,0 +1,275 @@
+/******************************************************************************
+ * balloon.c
+ *
+ * Xeno balloon driver - enables returning/claiming memory to/from xen
+ *
+ * Copyright (c) 2003, B Dragovic
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/smp_lock.h>
+#include <linux/pagemap.h>
+
+#include <asm/hypervisor.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+
+#include "dom_mem_ops.h"
+
+/* USER DEFINES -- THESE SHOULD BE COPIED TO USER-SPACE TOOLS */
+#define USER_INFLATE_BALLOON 1 /* return mem to hypervisor */
+#define USER_DEFLATE_BALLOON 2 /* claim mem from hypervisor */
+typedef struct user_balloon_op {
+ unsigned int op;
+ unsigned long size;
+} user_balloon_op_t;
+/* END OF USER DEFINE */
+
+/* Dead entry written into ballon-owned entries in the PMT. */
+#define DEAD 0xdeadbeef
+
+#define BALLOON_ENTRY "balloon"
+extern struct proc_dir_entry *xeno_base;
+
+static struct proc_dir_entry *balloon_pde;
+unsigned long credit;
+
+static inline unsigned long get_ppte(unsigned long addr)
+{
+ unsigned long ppte;
+ pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
+ pgd = pgd_offset_k(addr);
+
+ if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG();
+
+ pmd = pmd_offset(pgd, addr);
+ if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG();
+
+ ptep = pte_offset(pmd, addr);
+ ppte = (unsigned long)__pa(ptep);
+
+ return ppte;
+}
+
+/* main function for relinquishing bit of memory */
+static unsigned long inflate_balloon(unsigned long num_pages)
+{
+ dom_mem_op_t dom_mem_op;
+ unsigned long *parray;
+ unsigned long *currp;
+ unsigned long ret = 0;
+ unsigned long vaddr;
+ unsigned long i, j;
+
+ parray = (unsigned long *)kmalloc(num_pages *
+ sizeof(unsigned long), GFP_KERNEL);
+ currp = parray;
+
+ for ( i = 0; i < num_pages; i++ )
+ {
+ /* try to obtain a free page, has to be done with GFP_ATOMIC
+ * as we do not want to sleep indefinately.
+ */
+ vaddr = __get_free_page(GFP_ATOMIC);
+
+ /* if allocation fails, free all reserved pages */
+ if(!vaddr){
+ printk("Unable to inflate balloon by %ld, only %ld pages free.",
+ num_pages, i);
+ currp = parray;
+ for(j = 0; j < i; j++){
+ free_page(*currp++);
+ }
+ goto cleanup;
+ }
+
+ *currp++ = vaddr;
+ }
+
+
+ currp = parray;
+ for ( i = 0; i < num_pages; i++ )
+ {
+ queue_l1_entry_update(get_ppte(*currp) | PGREQ_NORMAL, 0);
+ phys_to_machine_mapping[__pa(*currp) >> PAGE_SHIFT] = DEAD;
+ currp++;
+ }
+
+ XENO_flush_page_update_queue();
+
+ dom_mem_op.op = BALLOON_INFLATE_OP;
+ dom_mem_op.u.balloon_inflate.size = num_pages;
+ dom_mem_op.u.balloon_inflate.pages = parray;
+ if ( (ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages )
+ {
+ printk("Unable to deflate balloon, error %lx\n", ret);
+ goto cleanup;
+ }
+
+ credit += num_pages;
+ ret = num_pages;
+
+ cleanup:
+ kfree(parray);
+
+ return ret;
+}
+
+/* install new mem pages obtained by deflate_balloon. function walks
+ * phys->machine mapping table looking for DEAD entries and populates
+ * them.
+ */
+static unsigned long process_new_pages(unsigned long * parray,
+ unsigned long num)
+{
+ /* currently, this function is rather simplistic as
+ * it is assumed that domain reclaims only number of
+ * pages previously released. this is to change soon
+ * and the code to extend page tables etc. will be
+ * incorporated here.
+ */
+
+ unsigned long tot_pages = start_info.nr_pages;
+ unsigned long * curr = parray;
+ unsigned long num_installed;
+ unsigned long i;
+
+ num_installed = 0;
+ for ( i = 0; i < tot_pages; i++ )
+ {
+ if ( phys_to_machine_mapping[i] == DEAD )
+ {
+ phys_to_machine_mapping[i] = *curr;
+ queue_l1_entry_update((i << PAGE_SHIFT) | PGREQ_MPT_UPDATE, i);
+ queue_l1_entry_update(
+ get_ppte((unsigned long)__va(i << PAGE_SHIFT)) | PGREQ_NORMAL,
+ ((*curr) << PAGE_SHIFT) | L1_PROT);
+
+ *curr = (unsigned long)__va(i << PAGE_SHIFT);
+ curr++;
+ num_installed++;
+ }
+ }
+
+ /* now, this is tricky (and will also change for machine addrs that
+ * are mapped to not previously released addresses). we free pages
+ * that were allocated by get_free_page (the mappings are different
+ * now, of course).
+ */
+ curr = parray;
+ for ( i = 0; i < num_installed; i++ )
+ {
+ free_page(*curr);
+ curr++;
+ }
+
+ return num_installed;
+}
+
+static unsigned long deflate_balloon(unsigned long num_pages)
+{
+ dom_mem_op_t dom_mem_op;
+ unsigned long ret;
+ unsigned long * parray;
+
+ if ( num_pages > credit )
+ {
+ printk("Can not allocate more pages than previously released.\n");
+ return -EAGAIN;
+ }
+
+ parray = (unsigned long *)kmalloc(num_pages * sizeof(unsigned long),
+ GFP_KERNEL);
+
+ dom_mem_op.op = BALLOON_DEFLATE_OP;
+ dom_mem_op.u.balloon_deflate.size = num_pages;
+ dom_mem_op.u.balloon_deflate.pages = parray;
+ if((ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages){
+ printk("Unable to deflate balloon, error %lx\n", ret);
+ goto cleanup;
+ }
+
+ if((ret = process_new_pages(parray, num_pages)) < num_pages){
+ printk("Unable to deflate balloon by specified %lx pages, only %lx.\n",
+ num_pages, ret);
+ goto cleanup;
+ }
+
+ ret = num_pages;
+
+ cleanup:
+ kfree(parray);
+
+ return ret;
+}
+
+static int balloon_write(struct file *file, const char *buffer,
+ u_long count, void *data)
+{
+ user_balloon_op_t bop;
+
+ /* Only admin can play with the balloon :) */
+ if ( !capable(CAP_SYS_ADMIN) )
+ return -EPERM;
+
+ if ( copy_from_user(&bop, buffer, sizeof(bop)) )
+ return -EFAULT;
+
+ switch ( bop.op )
+ {
+ case USER_INFLATE_BALLOON:
+ if ( inflate_balloon(bop.size) < bop.size )
+ return -EAGAIN;
+ break;
+
+ case USER_DEFLATE_BALLOON:
+ deflate_balloon(bop.size);
+ break;
+
+ default:
+ printk("Unknown command to balloon driver.");
+ return -EFAULT;
+ }
+
+ return sizeof(bop);
+}
+
+/*
+ * main balloon driver initialization function.
+ */
+static int __init init_module(void)
+{
+ printk(KERN_ALERT "Starting Xeno Balloon driver\n");
+
+ credit = 0;
+
+ balloon_pde = create_proc_entry(BALLOON_ENTRY, 0600, xeno_base);
+ if ( balloon_pde == NULL )
+ {
+ printk(KERN_ALERT "Unable to create balloon driver proc entry!");
+ return -1;
+ }
+
+ balloon_pde->write_proc = balloon_write;
+
+ return 0;
+}
+
+static void __exit cleanup_module(void)
+{
+}
+
+module_init(init_module);
+module_exit(cleanup_module);
+
+
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h
new file mode 100644
index 0000000000..c473f193e7
--- /dev/null
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * dom_mem_ops.h
+ *
+ * Header file supporting domain related memory operations. N.B. keep in sync
+ * with xen version.
+ *
+ * Copyright (c) 2003, B Dragovic
+ */
+
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
+#define BALLOON_DEFLATE_OP 0
+#define BALLOON_INFLATE_OP 1
+
+typedef struct balloon_deflate_op {
+ unsigned long size;
+ unsigned long * pages;
+} balloon_def_op_t;
+
+typedef struct balloon_inflate_op {
+ unsigned long size;
+ unsigned long * pages;
+} balloon_inf_op_t;
+
+typedef struct dom_mem_ops
+{
+ unsigned int op;
+ union
+ {
+ balloon_def_op_t balloon_deflate;
+ balloon_inf_op_t balloon_inflate;
+ }u;
+} dom_mem_op_t;
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
index f8af85358b..c36ab02e96 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c
@@ -53,7 +53,7 @@ typedef struct proc_mem_data {
#define MAP_DISCONT 1
-static struct proc_dir_entry *xeno_base;
+struct proc_dir_entry *xeno_base;
static struct proc_dir_entry *dom0_cmd_intf;
static struct proc_dir_entry *proc_ft;
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
index c9acaf43ee..7ef9ce4ef8 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
@@ -23,6 +23,7 @@
#include <asm/io.h>
#include <net/sock.h>
+#include <net/pkt_sched.h>
#define NET_TX_IRQ _EVENT_NET_TX
#define NET_RX_IRQ _EVENT_NET_RX
@@ -65,7 +66,20 @@ struct net_private
spinlock_t tx_lock;
};
-
+
+static void dbg_network_int(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct net_private *np = dev->priv;
+ printk(KERN_ALERT "tx_full = %d, tx_entries = %d, tx_idx = %d,"
+ " tx_cons = %d, tx_prod = %d, tx_event = %d, state=%d\n",
+ np->tx_full, atomic_read(&np->tx_entries), np->tx_idx,
+ np->net_ring->tx_cons, np->net_ring->tx_prod,
+ np->net_ring->tx_event,
+ test_bit(__LINK_STATE_XOFF, &dev->state));
+}
+
+
static int network_open(struct net_device *dev)
{
struct net_private *np = dev->priv;
@@ -123,6 +137,14 @@ static int network_open(struct net_device *dev)
goto fail;
}
+ error = request_irq(_EVENT_DEBUG, dbg_network_int, SA_SHIRQ,
+ "debug", dev);
+ if ( error )
+ {
+ printk(KERN_WARNING "%s: Non-fatal error -- no debug interrupt\n",
+ dev->name);
+ }
+
printk("XenoLinux Virtual Network Driver installed as %s\n", dev->name);
netif_start_queue(dev);
@@ -147,17 +169,28 @@ static void network_tx_buf_gc(struct net_device *dev)
struct net_private *np = dev->priv;
struct sk_buff *skb;
unsigned long flags;
+ unsigned int cons;
spin_lock_irqsave(&np->tx_lock, flags);
- for ( i = np->tx_idx; i != np->net_ring->tx_cons; i = TX_RING_INC(i) )
- {
- skb = np->tx_skb_ring[i];
- dev_kfree_skb_any(skb);
- atomic_dec(&np->tx_entries);
- }
+ do {
+ cons = np->net_ring->tx_cons;
- np->tx_idx = i;
+ for ( i = np->tx_idx; i != cons; i = TX_RING_INC(i) )
+ {
+ skb = np->tx_skb_ring[i];
+ dev_kfree_skb_any(skb);
+ atomic_dec(&np->tx_entries);
+ }
+
+ np->tx_idx = i;
+
+ /* Set a new event, then check for race with update of tx_cons. */
+ np->net_ring->tx_event =
+ TX_RING_ADD(cons, (atomic_read(&np->tx_entries)>>1) + 1);
+ smp_mb();
+ }
+ while ( cons != np->net_ring->tx_cons );
if ( np->tx_full && (atomic_read(&np->tx_entries) < TX_MAX_ENTRIES) )
{
@@ -262,17 +295,9 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
np->tx_full = 1;
netif_stop_queue(dev);
- np->net_ring->tx_event =
- TX_RING_ADD(np->tx_idx, atomic_read(&np->tx_entries) >> 1);
- }
- else
- {
- /* Avoid unnecessary tx interrupts. */
- np->net_ring->tx_event = TX_RING_INC(np->net_ring->tx_prod);
}
spin_unlock_irq(&np->tx_lock);
- /* Must do this after setting tx_event: race with updates of tx_cons. */
network_tx_buf_gc(dev);
HYPERVISOR_net_update();
diff --git a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h
index df25598730..16f37cfe65 100644
--- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h
+++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h
@@ -313,4 +313,15 @@ static inline int HYPERVISOR_set_fast_trap(int idx)
return ret;
}
+static inline int HYPERVISOR_dom_mem_op(void *dom_mem_op)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
+ "b" (dom_mem_op) : "memory" );
+
+ return ret;
+}
+
#endif /* __HYPERVISOR_H__ */
diff --git a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h
index e157a31a36..aad36820b7 100644
--- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h
+++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h
@@ -173,6 +173,10 @@ static __inline__ int get_order(unsigned long size)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+/* VIRT <-> MACHINE conversion */
+#define virt_to_machine(_a) (phys_to_machine(__pa(_a)))
+#define machine_to_virt(_m) (__va(machine_to_phys(_m)))
+
#endif /* __KERNEL__ */
#endif /* _I386_PAGE_H */