From aa24d38a469b59abf1b95b732b6ea9ed86e511cf Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 1 Sep 2005 15:31:12 +0000 Subject: [PATCH 01/12] Better Xen backtraces in debug builds (follow the stack frame pointer). Signed-off-by: Keir Fraser --- xen/Rules.mk | 1 - xen/arch/x86/Rules.mk | 4 +- xen/arch/x86/boot/x86_32.S | 5 +- xen/arch/x86/boot/x86_64.S | 4 +- xen/arch/x86/traps.c | 98 +++++++++++++++++++++----- xen/arch/x86/x86_32/traps.c | 7 +- xen/arch/x86/x86_64/traps.c | 5 +- xen/include/asm-x86/processor.h | 4 +- xen/include/asm-x86/x86_32/asm_defns.h | 10 +++ xen/include/asm-x86/x86_64/asm_defns.h | 10 +++ 10 files changed, 111 insertions(+), 37 deletions(-) diff --git a/xen/Rules.mk b/xen/Rules.mk index 511184b08e..4c3cb8db4e 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -7,7 +7,6 @@ debug ?= n perfc ?= n perfc_arrays?= n trace ?= n -optimize ?= y domu_debug ?= n crash_debug ?= n diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index 0675d763cd..e73be57bbc 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -13,10 +13,8 @@ CFLAGS += -I$(BASEDIR)/include CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default -ifeq ($(optimize),y) +ifneq ($(debug),y) CFLAGS += -O3 -fomit-frame-pointer -else -x86_32/usercopy.o: CFLAGS += -O1 endif # Prevent floating-point variables from creeping into Xen. diff --git a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S index fafc707bea..ca0c43555a 100644 --- a/xen/arch/x86/boot/x86_32.S +++ b/xen/arch/x86/boot/x86_32.S @@ -9,6 +9,8 @@ .text ENTRY(start) +ENTRY(stext) +ENTRY(_stext) jmp __start .align 4 @@ -260,6 +262,3 @@ ENTRY(idle_pg_table_l2) # Initial page directory is 4kB .org 0x2000 + STACK_SIZE + PAGE_SIZE #endif /* CONFIG_X86_PAE */ - -ENTRY(stext) -ENTRY(_stext) diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 85c599f536..fbe5311124 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -10,6 +10,8 @@ .code32 ENTRY(start) +ENTRY(stext) +ENTRY(_stext) jmp __start .org 0x004 @@ -267,5 +269,3 @@ ENTRY(idle_pg_table_l2) .org 0x4000 + STACK_SIZE + PAGE_SIZE .code64 -ENTRY(stext) -ENTRY(_stext) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 107485a5d9..865204a72d 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -100,7 +100,14 @@ unsigned long do_get_debugreg(int reg); static int debug_stack_lines = 20; integer_param("debug_stack_lines", debug_stack_lines); -#define stack_words_per_line (32 / BYTES_PER_LONG) + +#ifdef CONFIG_X86_32 +#define stack_words_per_line 8 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)®s->esp) +#else +#define stack_words_per_line 4 +#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp) +#endif int is_kernel_text(unsigned long addr) { @@ -118,17 +125,16 @@ unsigned long kernel_text_end(void) return (unsigned long) &_etext; } -void show_guest_stack(void) +static void show_guest_stack(struct cpu_user_regs *regs) { int i; - struct cpu_user_regs *regs = guest_cpu_user_regs(); unsigned long *stack = (unsigned long *)regs->esp, addr; printk("Guest stack trace from "__OP"sp=%p:\n ", stack); for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ ) { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) + if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 ) break; if ( get_user(addr, stack) ) { @@ -148,38 +154,98 @@ void show_guest_stack(void) printk("\n"); } -void show_trace(unsigned long *esp) +#ifdef NDEBUG + +static void show_trace(struct cpu_user_regs *regs) { - unsigned long *stack = esp, addr; - int i = 0; + unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr; - printk("Xen call trace from "__OP"sp=%p:\n ", stack); + printk("Xen call trace:\n "); - while ( ((long) stack & (STACK_SIZE-1)) != 0 ) + printk("[<%p>]", _p(regs->eip)); + print_symbol(" %s\n ", regs->eip); + + while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 ) { addr = *stack++; if ( is_kernel_text(addr) ) { printk("[<%p>]", _p(addr)); print_symbol(" %s\n ", addr); - i++; } } - if ( i == 0 ) - printk("Trace empty."); + printk("\n"); } -void show_stack(unsigned long *esp) +#else + +static void show_trace(struct cpu_user_regs *regs) { - unsigned long *stack = esp, addr; + unsigned long *frame, next, addr, low, high; + + printk("Xen call trace:\n "); + + printk("[<%p>]", _p(regs->eip)); + print_symbol(" %s\n ", regs->eip); + + /* Bounds for range of valid frame pointer. */ + low = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2); + high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info)); + + /* The initial frame pointer. */ + next = regs->ebp; + + for ( ; ; ) + { + /* Valid frame pointer? */ + if ( (next < low) || (next > high) ) + { + /* + * Exception stack frames have a different layout, denoted by an + * inverted frame pointer. + */ + next = ~next; + if ( (next < low) || (next > high) ) + break; + frame = (unsigned long *)next; + next = frame[0]; + addr = frame[(offsetof(struct cpu_user_regs, eip) - + offsetof(struct cpu_user_regs, ebp)) + / BYTES_PER_LONG]; + } + else + { + /* Ordinary stack frame. */ + frame = (unsigned long *)next; + next = frame[0]; + addr = frame[1]; + } + + printk("[<%p>]", _p(addr)); + print_symbol(" %s\n ", addr); + + low = (unsigned long)&frame[2]; + } + + printk("\n"); +} + +#endif + +void show_stack(struct cpu_user_regs *regs) +{ + unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr; int i; + if ( GUEST_MODE(regs) ) + return show_guest_stack(regs); + printk("Xen stack trace from "__OP"sp=%p:\n ", stack); for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ ) { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) + if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 ) break; if ( (i != 0) && ((i % stack_words_per_line) == 0) ) printk("\n "); @@ -190,7 +256,7 @@ void show_stack(unsigned long *esp) printk("Stack empty."); printk("\n"); - show_trace(esp); + show_trace(regs); } /* diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index 34c7871a2c..091b4e11de 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -79,11 +79,8 @@ void show_registers(struct cpu_user_regs *regs) "ss: %04lx cs: %04lx\n", ds, es, fs, gs, ss, cs); - if ( GUEST_MODE(regs) ) - show_guest_stack(); - else - show_stack((unsigned long *)®s->esp); -} + show_stack(regs); +} void show_page_walk(unsigned long addr) { diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 5e9701a1f6..7fee601699 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -32,10 +32,7 @@ void show_registers(struct cpu_user_regs *regs) regs->r12, regs->r13, regs->r14); printk("r15: %016lx\n", regs->r15); - if ( GUEST_MODE(regs) ) - show_guest_stack(); - else - show_stack((unsigned long *)regs->rsp); + show_stack(regs); } void show_page_walk(unsigned long addr) diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 82b8cbce62..b312175e8c 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -496,9 +496,7 @@ extern inline void prefetchw(const void *x) #endif -void show_guest_stack(); -void show_trace(unsigned long *esp); -void show_stack(unsigned long *esp); +void show_stack(struct cpu_user_regs *regs); void show_registers(struct cpu_user_regs *regs); void show_page_walk(unsigned long addr); asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs); diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h index d0243d4a52..c3772c6b1c 100644 --- a/xen/include/asm-x86/x86_32/asm_defns.h +++ b/xen/include/asm-x86/x86_32/asm_defns.h @@ -1,10 +1,20 @@ #ifndef __X86_32_ASM_DEFNS_H__ #define __X86_32_ASM_DEFNS_H__ +#ifndef NDEBUG +/* Indicate special exception stack frame by inverting the frame pointer. */ +#define SETUP_EXCEPTION_FRAME_POINTER \ + movl %esp,%ebp; \ + notl %ebp +#else +#define SETUP_EXCEPTION_FRAME_POINTER +#endif + #define __SAVE_ALL_PRE \ cld; \ pushl %eax; \ pushl %ebp; \ + SETUP_EXCEPTION_FRAME_POINTER; \ pushl %edi; \ pushl %esi; \ pushl %edx; \ diff --git a/xen/include/asm-x86/x86_64/asm_defns.h b/xen/include/asm-x86/x86_64/asm_defns.h index ff1d4927e0..d11af7228a 100644 --- a/xen/include/asm-x86/x86_64/asm_defns.h +++ b/xen/include/asm-x86/x86_64/asm_defns.h @@ -1,6 +1,15 @@ #ifndef __X86_64_ASM_DEFNS_H__ #define __X86_64_ASM_DEFNS_H__ +#ifndef NDEBUG +/* Indicate special exception stack frame by inverting the frame pointer. */ +#define SETUP_EXCEPTION_FRAME_POINTER \ + movq %rsp,%rbp; \ + notq %rbp +#else +#define SETUP_EXCEPTION_FRAME_POINTER +#endif + #define SAVE_ALL \ cld; \ pushq %rdi; \ @@ -14,6 +23,7 @@ pushq %r11; \ pushq %rbx; \ pushq %rbp; \ + SETUP_EXCEPTION_FRAME_POINTER; \ pushq %r12; \ pushq %r13; \ pushq %r14; \ From 16d22664319d2f39f7678799780bb76ccbd38e98 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Thu, 1 Sep 2005 11:09:16 -0800 Subject: [PATCH 02/12] Fix build dependency for the XEN tpm driver. Signed-off-by: Stefan Berger --- linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU index 835b2606e2..18992dedc3 100644 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU @@ -19,7 +19,7 @@ config TCG_TPM config TCG_XEN tristate "XEN TPM Interface" - depends on TCG_TPM && ARCH_XEN + depends on TCG_TPM && ARCH_XEN && XEN_TPMDEV_FRONTEND ---help--- If you want to make TPM support available to a Xen user domain, say Yes and it will From b6e27d0a1eee7865f4c1fa3a5cda247fabe88218 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Thu, 1 Sep 2005 20:19:34 -0800 Subject: [PATCH 03/12] Fix save/restore when using grant tables in network, robust-ify netback against bogus front-end drivers, plus various small cleanups. Note that there is now only /one/ config option controlling the use of grant tables with networking (not separate ones for rx and tx). An outstanding issue is that console reconnect after a restore causes badness. Signed-off-by: Steven Hand --- linux-2.6-xen-sparse/arch/xen/Kconfig | 11 +- .../arch/xen/configs/xen0_defconfig_x86_32 | 3 +- .../arch/xen/configs/xen0_defconfig_x86_64 | 3 +- .../arch/xen/configs/xenU_defconfig_x86_32 | 3 +- .../arch/xen/configs/xenU_defconfig_x86_64 | 3 +- .../arch/xen/configs/xen_defconfig_x86_32 | 3 +- .../arch/xen/configs/xen_defconfig_x86_64 | 3 +- .../drivers/xen/console/xencons_ring.c | 2 +- .../drivers/xen/netback/common.h | 16 +- .../drivers/xen/netback/interface.c | 110 +++++------ .../drivers/xen/netback/netback.c | 102 +++++----- .../drivers/xen/netfront/netfront.c | 179 ++++++++++-------- .../drivers/xen/xenbus/xenbus_comms.c | 2 +- tools/console/daemon/utils.c | 2 +- xen/common/domain.c | 3 + xen/common/grant_table.c | 13 +- xen/include/public/io/netif.h | 4 +- 17 files changed, 235 insertions(+), 227 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/Kconfig b/linux-2.6-xen-sparse/arch/xen/Kconfig index b5088f87a8..07b5e85cee 100644 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig @@ -109,15 +109,8 @@ config XEN_NETDEV_FRONTEND dedicated device-driver domain, or your master control domain (domain 0), then you almost certainly want to say Y here. -config XEN_NETDEV_GRANT_TX - bool "Grant table substrate for net drivers tx path (DANGEROUS)" - default n - help - This introduces the use of grant tables as a data exhange mechanism - between the frontend and backend network drivers. - -config XEN_NETDEV_GRANT_RX - bool "Grant table substrate for net drivers rx path (DANGEROUS)" +config XEN_NETDEV_GRANT + bool "Grant table substrate for network drivers (DANGEROUS)" default n help This introduces the use of grant tables as a data exhange mechanism diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 index a6c238b134..5b61cd071a 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 @@ -19,8 +19,7 @@ CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 index 47d1ea9218..0d945215c9 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 @@ -19,8 +19,7 @@ CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 index 492b6d6cea..f12aa510f2 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 @@ -16,8 +16,7 @@ CONFIG_NO_IDLE_HZ=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 index 2e4ddbcba8..1f231c5ffe 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 @@ -16,8 +16,7 @@ CONFIG_NO_IDLE_HZ=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 56fa2258de..05e8e88361 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -19,8 +19,7 @@ CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 index 420365ef0b..47f613aa81 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 @@ -19,8 +19,7 @@ CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_NETDEV_GRANT_TX=y -CONFIG_XEN_NETDEV_GRANT_RX=y +CONFIG_XEN_NETDEV_GRANT=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c index 2499d80352..6987d1a258 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c @@ -105,7 +105,7 @@ int xencons_ring_init(void) xen_start_info.console_evtchn, handle_input, 0, "xencons", inring()); if (err) { - xprintk(KERN_ERR "XEN console request irq failed %i\n", err); + xprintk("XEN console request irq failed %i\n", err); unbind_evtchn_from_irq(xen_start_info.console_evtchn); return err; } diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/common.h b/linux-2.6-xen-sparse/drivers/xen/netback/common.h index 29306ec77f..bef03435b8 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h @@ -20,9 +20,12 @@ #include #include -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) +#ifdef CONFIG_XEN_NETDEV_GRANT #include #include + +#define GRANT_INVALID_REF (0xFFFF) + #endif @@ -37,6 +40,11 @@ #define ASSERT(_p) ((void)0) #define DPRINTK(_f, _a...) ((void)0) #endif +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "xen_net: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_net: " fmt, ##args) + typedef struct netif_st { /* Unique identifier for this interface. */ @@ -47,13 +55,13 @@ typedef struct netif_st { /* Physical parameters of the comms window. */ unsigned long tx_shmem_frame; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT u16 tx_shmem_handle; unsigned long tx_shmem_vaddr; grant_ref_t tx_shmem_ref; #endif unsigned long rx_shmem_frame; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT u16 rx_shmem_handle; unsigned long rx_shmem_vaddr; grant_ref_t rx_shmem_ref; @@ -68,7 +76,7 @@ typedef struct netif_st { /* Private indexes into shared ring. */ NETIF_RING_IDX rx_req_cons; NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */ -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */ #endif NETIF_RING_IDX tx_req_cons; diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index eddb04d36f..c1694fe7bb 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -111,65 +111,57 @@ netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) return netif; } -static int map_frontend_page(netif_t *netif, unsigned long localaddr, - unsigned long tx_ring_ref, unsigned long rx_ring_ref) +static int map_frontend_pages(netif_t *netif, unsigned long localaddr, + unsigned long tx_ring_ref, + unsigned long rx_ring_ref) { -#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) +#ifdef CONFIG_XEN_NETDEV_GRANT + struct gnttab_map_grant_ref op; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr; + op.flags = GNTMAP_host_map; + op.ref = tx_ring_ref; + op.dom = netif->domid; + + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n"); + return op.handle; + } + + netif->tx_shmem_ref = tx_ring_ref; + netif->tx_shmem_handle = op.handle; + netif->tx_shmem_vaddr = localaddr; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr + PAGE_SIZE; + op.flags = GNTMAP_host_map; + op.ref = rx_ring_ref; + op.dom = netif->domid; + + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n"); + return op.handle; + } + + netif->rx_shmem_ref = rx_ring_ref; + netif->rx_shmem_handle = op.handle; + netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; + +#else pgprot_t prot = __pgprot(_KERNPG_TABLE); int err; -#endif -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) - { - struct gnttab_map_grant_ref op; - /* Map: Use the Grant table reference */ - op.host_addr = localaddr; - op.flags = GNTMAP_host_map; - op.ref = tx_ring_ref; - op.dom = netif->domid; - - BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); - if (op.handle < 0) { - DPRINTK(" Grant table operation failure !\n"); - return op.handle; - } - - netif->tx_shmem_ref = tx_ring_ref; - netif->tx_shmem_handle = op.handle; - netif->tx_shmem_vaddr = localaddr; - } -#else err = direct_remap_area_pages(&init_mm, localaddr, tx_ring_ref<domid); - if (err) - return err; -#endif - -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) - { - struct gnttab_map_grant_ref op; - - /* Map: Use the Grant table reference */ - op.host_addr = localaddr + PAGE_SIZE; - op.flags = GNTMAP_host_map; - op.ref = rx_ring_ref; - op.dom = netif->domid; - - BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); - if (op.handle < 0) { - DPRINTK(" Grant table operation failure !\n"); - return op.handle; - } - - netif->rx_shmem_ref = rx_ring_ref; - netif->rx_shmem_handle = op.handle; - netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; - } -#else - err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE, + + err |= direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE, rx_ring_ref<domid); + if (err) return err; #endif @@ -177,25 +169,23 @@ static int map_frontend_page(netif_t *netif, unsigned long localaddr, return 0; } -static void unmap_frontend_page(netif_t *netif) +static void unmap_frontend_pages(netif_t *netif) { -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) +#ifdef CONFIG_XEN_NETDEV_GRANT struct gnttab_unmap_grant_ref op; -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_TX op.host_addr = netif->tx_shmem_vaddr; op.handle = netif->tx_shmem_handle; op.dev_bus_addr = 0; BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX op.host_addr = netif->rx_shmem_vaddr; op.handle = netif->rx_shmem_handle; op.dev_bus_addr = 0; BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); #endif + + return; } int netif_map(netif_t *netif, unsigned long tx_ring_ref, @@ -209,8 +199,8 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref, if (vma == NULL) return -ENOMEM; - err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref, - rx_ring_ref); + err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref, + rx_ring_ref); if (err) { vfree(vma->addr); return err; @@ -222,7 +212,7 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref, op.u.bind_interdomain.port2 = evtchn; err = HYPERVISOR_event_channel_op(&op); if (err) { - unmap_frontend_page(netif); + unmap_frontend_pages(netif); vfree(vma->addr); return err; } @@ -267,7 +257,7 @@ static void free_netif(void *arg) unregister_netdev(netif->dev); if (netif->tx) { - unmap_frontend_page(netif); + unmap_frontend_pages(netif); vfree(netif->tx); /* Frees netif->rx as well. */ } diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index f82df74662..f90d6f3572 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -14,23 +14,6 @@ #include #include -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) -#include -#include -#ifdef GRANT_DEBUG -static void -dump_packet(int tag, u32 addr, unsigned char *p) -{ - int i; - - printk(KERN_ALERT "#### rx_action %c %08x ", tag & 0xff, addr); - for (i = 0; i < 20; i++) { - printk("%02x", p[i]); - } - printk("\n"); -} -#endif -#endif static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); @@ -57,7 +40,8 @@ static struct timer_list net_timer; static struct sk_buff_head rx_queue; static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1]; static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX + +#ifdef CONFIG_XEN_NETDEV_GRANT static gnttab_donate_t grant_rx_op[MAX_PENDING_REQS]; #else static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE]; @@ -88,18 +72,15 @@ static PEND_RING_IDX dealloc_prod, dealloc_cons; static struct sk_buff_head tx_queue; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT static u16 grant_tx_ref[MAX_PENDING_REQS]; static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS]; static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS]; + #else static multicall_entry_t tx_mcl[MAX_PENDING_REQS]; #endif -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) -#define GRANT_INVALID_REF (0xFFFF) -#endif - static struct list_head net_schedule_list; static spinlock_t net_schedule_list_lock; @@ -127,7 +108,7 @@ static unsigned long alloc_mfn(void) return mfn; } -#ifndef CONFIG_XEN_NETDEV_GRANT_RX +#ifndef CONFIG_XEN_NETDEV_GRANT static void free_mfn(unsigned long mfn) { unsigned long flags; @@ -200,7 +181,7 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); skb = nskb; } -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT #ifdef DEBUG_GRANT printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x gr=%04x\n", netif->rx->req_prod, @@ -246,12 +227,12 @@ int xen_network_done(void) static void net_rx_action(unsigned long unused) { - netif_t *netif; + netif_t *netif = NULL; s8 status; u16 size, id, evtchn; multicall_entry_t *mcl; mmu_update_t *mmu; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT gnttab_donate_t *gop; #else struct mmuext_op *mmuext; @@ -266,7 +247,7 @@ static void net_rx_action(unsigned long unused) mcl = rx_mcl; mmu = rx_mmu; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT gop = grant_rx_op; #else mmuext = rx_mmuext; @@ -282,7 +263,7 @@ static void net_rx_action(unsigned long unused) if ( (new_mfn = alloc_mfn()) == 0 ) { if ( net_ratelimit() ) - printk(KERN_WARNING "Memory squeeze in netback driver.\n"); + WPRINTK("Memory squeeze in netback driver.\n"); mod_timer(&net_timer, jiffies + HZ); skb_queue_head(&rx_queue, skb); break; @@ -297,7 +278,7 @@ static void net_rx_action(unsigned long unused) pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); mcl++; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT gop->mfn = old_mfn; gop->domid = netif->domid; gop->handle = netif->rx->ring[ @@ -340,7 +321,7 @@ static void net_rx_action(unsigned long unused) mcl->args[3] = DOMID_SELF; mcl++; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; #else mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; @@ -349,9 +330,17 @@ static void net_rx_action(unsigned long unused) BUG(); mcl = rx_mcl; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_donate, grant_rx_op, gop - grant_rx_op)); +#ifdef CONFIG_XEN_NETDEV_GRANT + if(HYPERVISOR_grant_table_op(GNTTABOP_donate, grant_rx_op, + gop - grant_rx_op)) { + /* + ** The other side has given us a bad grant ref, or has no headroom, + ** or has gone away. Unfortunately the current grant table code + ** doesn't inform us which is the case, so not much we can do. + */ + DPRINTK("net_rx: donate to DOM%u failed; dropping (up to) %d " + "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op); + } gop = grant_rx_op; #else mmuext = rx_mmuext; @@ -363,7 +352,7 @@ static void net_rx_action(unsigned long unused) /* Rederive the machine addresses. */ new_mfn = mcl[0].args[1] >> PAGE_SHIFT; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */ #else old_mfn = mmuext[0].mfn; @@ -380,8 +369,13 @@ static void net_rx_action(unsigned long unused) /* Check the reassignment error code. */ status = NETIF_RSP_OKAY; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - BUG_ON(gop->status != 0); /* XXX */ +#ifdef CONFIG_XEN_NETDEV_GRANT + if(gop->status != 0) { + DPRINTK("Bad status %d from grant donate to DOM%u\n", + gop->status, netif->domid); + /* XXX SMH: should free 'old_mfn' here */ + status = NETIF_RSP_ERROR; + } #else if ( unlikely(mcl[1].result != 0) ) { @@ -404,7 +398,7 @@ static void net_rx_action(unsigned long unused) netif_put(netif); dev_kfree_skb(skb); -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT mcl++; gop++; #else @@ -420,6 +414,7 @@ static void net_rx_action(unsigned long unused) notify_via_evtchn(evtchn); } + out: /* More work to do? */ if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) ) tasklet_schedule(&net_rx_tasklet); @@ -496,7 +491,7 @@ static void tx_credit_callback(unsigned long data) inline static void net_tx_action_dealloc(void) { -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT gnttab_unmap_grant_ref_t *gop; #else multicall_entry_t *mcl; @@ -508,7 +503,7 @@ inline static void net_tx_action_dealloc(void) dc = dealloc_cons; dp = dealloc_prod; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT /* * Free up any grants we have finished using */ @@ -542,7 +537,7 @@ inline static void net_tx_action_dealloc(void) #endif while ( dealloc_cons != dp ) { -#ifndef CONFIG_XEN_NETDEV_GRANT_TX +#ifndef CONFIG_XEN_NETDEV_GRANT /* The update_va_mapping() must not fail. */ BUG_ON(mcl[0].result != 0); #endif @@ -569,7 +564,7 @@ inline static void net_tx_action_dealloc(void) netif_put(netif); -#ifndef CONFIG_XEN_NETDEV_GRANT_TX +#ifndef CONFIG_XEN_NETDEV_GRANT mcl++; #endif } @@ -585,7 +580,7 @@ static void net_tx_action(unsigned long unused) netif_tx_request_t txreq; u16 pending_idx; NETIF_RING_IDX i; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT gnttab_map_grant_ref_t *mop; #else multicall_entry_t *mcl; @@ -595,7 +590,7 @@ static void net_tx_action(unsigned long unused) if ( dealloc_cons != dealloc_prod ) net_tx_action_dealloc(); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT mop = tx_map_ops; #else mcl = tx_mcl; @@ -696,7 +691,7 @@ static void net_tx_action(unsigned long unused) /* Packets passed to netif_rx() must have some headroom. */ skb_reserve(skb, 16); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT mop->host_addr = MMAP_VADDR(pending_idx); mop->dom = netif->domid; mop->ref = txreq.addr >> PAGE_SHIFT; @@ -719,7 +714,7 @@ static void net_tx_action(unsigned long unused) pending_cons++; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) ) break; #else @@ -729,7 +724,7 @@ static void net_tx_action(unsigned long unused) #endif } -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT if ( mop == tx_map_ops ) return; @@ -752,7 +747,7 @@ static void net_tx_action(unsigned long unused) memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq)); /* Check the remap error code. */ -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT /* XXX SMH: error returns from grant operations are pretty poorly specified/thought out, but the below at least conforms with @@ -826,7 +821,7 @@ static void net_tx_action(unsigned long unused) netif_rx(skb); netif->dev->last_rx = jiffies; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT mop++; #else mcl++; @@ -949,12 +944,9 @@ static int __init netback_init(void) !(xen_start_info.flags & SIF_INITDOMAIN) ) return 0; - printk("Initialising Xen netif backend\n"); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - printk("#### netback tx using grant tables\n"); -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - printk("#### netback rx using grant tables\n"); + IPRINTK("Initialising Xen netif backend.\n"); +#ifdef CONFIG_XEN_NETDEV_GRANT + IPRINTK("Using grant tables.\n"); #endif /* We can increase reservation by this much in net_rx_action(). */ diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index ecb3fae056..08db931a4a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -55,9 +55,18 @@ #include #include -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) +#ifdef CONFIG_XEN_NETDEV_GRANT #include #include + +static grant_ref_t gref_tx_head; +static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; + +static grant_ref_t gref_rx_head; +static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1]; + +#define GRANT_INVALID_REF (0xFFFF) + #ifdef GRANT_DEBUG static void dump_packet(int tag, void *addr, u32 ap) @@ -71,9 +80,18 @@ dump_packet(int tag, void *addr, u32 ap) } printk("\n"); } + +#define GDPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) +#else +#define dump_packet(x,y,z) ((void)0) +#define GDPRINTK(_f, _a...) ((void)0) #endif + #endif + + #ifndef __GFP_NOWARN #define __GFP_NOWARN 0 #endif @@ -102,23 +120,11 @@ dump_packet(int tag, void *addr, u32 ap) #define TX_TEST_IDX req_cons /* conservative: not seen all our requests? */ #endif -#ifdef CONFIG_XEN_NETDEV_GRANT_TX -static grant_ref_t gref_tx_head; -static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1]; -#endif - -#ifdef CONFIG_XEN_NETDEV_GRANT_RX -static grant_ref_t gref_rx_head; -static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1]; -#endif - -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) -#define GRANT_INVALID_REF (0xFFFF) -#endif #define NETIF_STATE_DISCONNECTED 0 #define NETIF_STATE_CONNECTED 1 + static unsigned int netif_state = NETIF_STATE_DISCONNECTED; static void network_tx_buf_gc(struct net_device *dev); @@ -279,7 +285,7 @@ static void network_tx_buf_gc(struct net_device *dev) for (i = np->tx_resp_cons; i != prod; i++) { id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; skb = np->tx_skbs[id]; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) { /* other domain is still using this grant - shouldn't happen but if it does, we'll try to reclaim the grant later */ @@ -310,7 +316,7 @@ static void network_tx_buf_gc(struct net_device *dev) mb(); } while (prod != np->tx->resp_prod); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT out: #endif @@ -330,8 +336,8 @@ static void network_alloc_rx_buffers(struct net_device *dev) int i, batch_target; NETIF_RING_IDX req_prod = np->rx->req_prod; struct xen_memory_reservation reservation; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - int ref; +#ifdef CONFIG_XEN_NETDEV_GRANT + grant_ref_t ref; #endif if (unlikely(np->backend_state != BEST_CONNECTED)) @@ -365,9 +371,9 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->rx_skbs[id] = skb; np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT ref = gnttab_claim_grant_reference(&gref_rx_head); - if (unlikely(ref < 0)) { + if (unlikely((signed short)ref < 0)) { printk(KERN_ALERT "#### netfront can't claim rx reference\n"); BUG(); } @@ -426,8 +432,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) struct net_private *np = netdev_priv(dev); netif_tx_request_t *tx; NETIF_RING_IDX i; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - unsigned int ref; +#ifdef CONFIG_XEN_NETDEV_GRANT + grant_ref_t ref; unsigned long mfn; #endif @@ -464,9 +470,9 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req; tx->id = id; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT ref = gnttab_claim_grant_reference(&gref_tx_head); - if (unlikely(ref < 0)) { + if (unlikely((signed short)ref < 0)) { printk(KERN_ALERT "#### netfront can't claim tx grant reference\n"); BUG(); } @@ -519,7 +525,7 @@ static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) network_tx_buf_gc(dev); spin_unlock_irqrestore(&np->tx_lock, flags); - if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN)) + if((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN)) netif_rx_schedule(dev); return IRQ_HANDLED; @@ -537,7 +543,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) int work_done, budget, more_to_do = 1; struct sk_buff_head rxq; unsigned long flags; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT unsigned long mfn; grant_ref_t ref; #endif @@ -574,8 +580,19 @@ static int netif_poll(struct net_device *dev, int *pbudget) continue; } -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - ref = grant_rx_ref[rx->id]; +#ifdef CONFIG_XEN_NETDEV_GRANT + ref = grant_rx_ref[rx->id]; + + if(ref == GRANT_INVALID_REF) { + printk(KERN_WARNING "Bad rx grant reference %d from dom %d.\n", + ref, np->backend_id); + np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; + wmb(); + np->rx->req_prod++; + work_done--; + continue; + } + grant_rx_ref[rx->id] = GRANT_INVALID_REF; mfn = gnttab_end_foreign_transfer_ref(ref); gnttab_release_grant_reference(&gref_rx_head, ref); @@ -585,7 +602,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); /* NB. We handle skb overflow later. */ -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT skb->data = skb->head + rx->addr; #else skb->data = skb->head + (rx->addr & ~PAGE_MASK); @@ -600,14 +617,14 @@ static int netif_poll(struct net_device *dev, int *pbudget) np->stats.rx_bytes += rx->status; /* Remap the page. */ -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT mmu->ptr = mfn << PAGE_SHIFT | MMU_MACHPHYS_UPDATE; #else mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE; #endif mmu->val = __pa(skb->head) >> PAGE_SHIFT; mmu++; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT MULTI_update_va_mapping(mcl, (unsigned long)skb->head, pfn_pte_ma(mfn, PAGE_KERNEL), 0); #else @@ -617,20 +634,20 @@ static int netif_poll(struct net_device *dev, int *pbudget) #endif mcl++; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn; + GDPRINTK("#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n", + skb->data, mfn, ref); #else phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = rx->addr >> PAGE_SHIFT; -#endif +#endif + -#ifdef GRANT_DEBUG - printk(KERN_ALERT "#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n", - skb->data, mfn, ref); -#endif __skb_queue_tail(&rxq, skb); } + /* Some pages are no longer absent... */ balloon_update_driver_allowance(-work_done); @@ -646,9 +663,9 @@ static int netif_poll(struct net_device *dev, int *pbudget) } while ((skb = __skb_dequeue(&rxq)) != NULL) { -#ifdef GRANT_DEBUG - printk(KERN_ALERT "#### rx_poll dequeue vdata=%p mfn=%lu\n", - skb->data, virt_to_mfn(skb->data)); +#ifdef CONFIG_XEN_NETDEV_GRANT + GDPRINTK("#### rx_poll dequeue vdata=%p mfn=%lu\n", + skb->data, virt_to_mfn(skb->data)); dump_packet('d', skb->data, (unsigned long)skb->data); #endif /* @@ -747,7 +764,6 @@ static struct net_device_stats *network_get_stats(struct net_device *dev) return &np->stats; } - static void network_connect(struct net_device *dev) { struct net_private *np; @@ -787,8 +803,11 @@ static void network_connect(struct net_device *dev) tx = &np->tx->ring[requeue_idx++].req; tx->id = i; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - tx->addr = 0; /*(ref << PAGE_SHIFT) |*/ +#ifdef CONFIG_XEN_NETDEV_GRANT + gnttab_grant_foreign_access_ref(grant_tx_ref[i], np->backend_id, + virt_to_mfn(np->tx_skbs[i]->data), + GNTMAP_readonly); + tx->addr = grant_tx_ref[i] << PAGE_SHIFT; #else tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT; #endif @@ -803,9 +822,20 @@ static void network_connect(struct net_device *dev) np->tx->req_prod = requeue_idx; /* Rebuild the RX buffer freelist and the RX ring itself. */ - for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) - if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) - np->rx->ring[requeue_idx++].req.id = i; + for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) { + if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) { +#ifdef CONFIG_XEN_NETDEV_GRANT + /* Reinstate the grant ref so backend can 'donate' mfn to us. */ + gnttab_grant_foreign_transfer_ref(grant_rx_ref[i], np->backend_id, + virt_to_mfn(np->rx_skbs[i]->head) + ); + np->rx->ring[requeue_idx].req.gref = grant_rx_ref[i]; +#endif + np->rx->ring[requeue_idx].req.id = i; + requeue_idx++; + } + } + wmb(); np->rx->req_prod = requeue_idx; @@ -901,13 +931,14 @@ static int create_netdev(int handle, struct xenbus_device *dev, /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ for (i = 0; i <= NETIF_TX_RING_SIZE; i++) { np->tx_skbs[i] = (void *)((unsigned long) i+1); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT grant_tx_ref[i] = GRANT_INVALID_REF; #endif } + for (i = 0; i <= NETIF_RX_RING_SIZE; i++) { np->rx_skbs[i] = (void *)((unsigned long) i+1); -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT grant_rx_ref[i] = GRANT_INVALID_REF; #endif } @@ -991,10 +1022,8 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; int err; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT info->tx_ring_ref = GRANT_INVALID_REF; -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX info->rx_ring_ref = GRANT_INVALID_REF; #endif @@ -1014,7 +1043,7 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) memset(info->rx, 0, PAGE_SIZE); info->backend_state = BEST_DISCONNECTED; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT err = gnttab_grant_foreign_access(info->backend_id, virt_to_mfn(info->tx), 0); if (err < 0) { @@ -1022,11 +1051,7 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) goto out; } info->tx_ring_ref = err; -#else - info->tx_ring_ref = virt_to_mfn(info->tx); -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX err = gnttab_grant_foreign_access(info->backend_id, virt_to_mfn(info->rx), 0); if (err < 0) { @@ -1034,7 +1059,9 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) goto out; } info->rx_ring_ref = err; + #else + info->tx_ring_ref = virt_to_mfn(info->tx); info->rx_ring_ref = virt_to_mfn(info->rx); #endif @@ -1054,16 +1081,17 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) if (info->rx) free_page((unsigned long)info->rx); info->rx = 0; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX + +#ifdef CONFIG_XEN_NETDEV_GRANT if (info->tx_ring_ref != GRANT_INVALID_REF) gnttab_end_foreign_access(info->tx_ring_ref, 0); info->tx_ring_ref = GRANT_INVALID_REF; -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX + if (info->rx_ring_ref != GRANT_INVALID_REF) gnttab_end_foreign_access(info->rx_ring_ref, 0); info->rx_ring_ref = GRANT_INVALID_REF; #endif + return err; } @@ -1075,16 +1103,17 @@ static void netif_free(struct netfront_info *info) if (info->rx) free_page((unsigned long)info->rx); info->rx = 0; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX + +#ifdef CONFIG_XEN_NETDEV_GRANT if (info->tx_ring_ref != GRANT_INVALID_REF) gnttab_end_foreign_access(info->tx_ring_ref, 0); info->tx_ring_ref = GRANT_INVALID_REF; -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX + if (info->rx_ring_ref != GRANT_INVALID_REF) gnttab_end_foreign_access(info->rx_ring_ref, 0); info->rx_ring_ref = GRANT_INVALID_REF; #endif + unbind_evtchn_from_irqhandler(info->evtchn, info->netdev); info->evtchn = 0; } @@ -1294,6 +1323,7 @@ static int netfront_resume(struct xenbus_device *dev) int err; err = talk_to_backend(dev, np); + return err; } @@ -1342,29 +1372,28 @@ static int __init netif_init(void) if (xen_start_info.flags & SIF_INITDOMAIN) return 0; -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - /* A grant for every ring slot */ + if ((err = xennet_proc_init()) != 0) + return err; + + IPRINTK("Initialising virtual ethernet driver.\n"); + +#ifdef CONFIG_XEN_NETDEV_GRANT + IPRINTK("Using grant tables.\n"); + + /* A grant for every tx ring slot */ if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, &gref_tx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); return 1; } - printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - /* A grant for every ring slot */ + /* A grant for every rx ring slot */ if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE, &gref_rx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); return 1; } - printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); #endif - if ((err = xennet_proc_init()) != 0) - return err; - - IPRINTK("Initialising virtual ethernet driver.\n"); (void)register_inetaddr_notifier(¬ifier_inetdev); @@ -1377,10 +1406,8 @@ static int __init netif_init(void) static void netif_exit(void) { -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT gnttab_free_grant_references(gref_tx_head); -#endif -#ifdef CONFIG_XEN_NETDEV_GRANT_RX gnttab_free_grant_references(gref_rx_head); #endif } diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c index 6ea32b5394..d4bf9ed818 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c @@ -212,7 +212,7 @@ int xb_init_comms(void) xen_start_info.store_evtchn, wake_waiting, 0, "xenbus", &xb_waitq); if (err) { - printk(KERN_ERR "XENBUS request irq failed %i\n", err); + xprintk("XENBUS request irq failed %i\n", err); unbind_evtchn_from_irq(xen_start_info.store_evtchn); return err; } diff --git a/tools/console/daemon/utils.c b/tools/console/daemon/utils.c index c368c23017..e29fc11ead 100644 --- a/tools/console/daemon/utils.c +++ b/tools/console/daemon/utils.c @@ -234,7 +234,7 @@ bool xen_setup(void) } if (!xs_watch(xs, "/console", "console")) { - dolog(LOG_ERR, "xenstore watch on /console failes."); + dolog(LOG_ERR, "xenstore watch on /console fails."); goto out_close_data; } diff --git a/xen/common/domain.c b/xen/common/domain.c index 8405fff7b0..a5460759d6 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -178,6 +178,9 @@ void domain_shutdown(u8 reason) struct domain *d = current->domain; struct vcpu *v; + if(reason == SHUTDOWN_crash) + printk("Domain %d crash detected.\n", d->domain_id); + if ( d->domain_id == 0 ) { extern void machine_restart(char *); diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 7f3c5b4a62..69ab0580b5 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -887,21 +887,21 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) e->tot_pages, e->max_pages); spin_unlock(&e->page_alloc_lock); put_domain(e); - result = GNTST_general_error; + gop->status = result = GNTST_general_error; break; } if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) { printk("gnttab_donate: target domain is dying\n"); spin_unlock(&e->page_alloc_lock); put_domain(e); - result = GNTST_general_error; + gop->status = result = GNTST_general_error; break; } if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { - printk("gnttab_donate: gnttab_prepare_for_transfer fails\n"); + printk("gnttab_donate: gnttab_prepare_for_transfer fails.\n"); spin_unlock(&e->page_alloc_lock); put_domain(e); - result = GNTST_general_error; + gop->status = result = GNTST_general_error; break; } #else @@ -914,7 +914,8 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) e->tot_pages, e->max_pages, gop->handle, e->d_flags); spin_unlock(&e->page_alloc_lock); put_domain(e); - result = GNTST_general_error; + /* XXX SMH: better error return here would be useful */ + gop->status = result = GNTST_general_error; break; } #endif @@ -1020,7 +1021,7 @@ gnttab_check_unmap( lgt = ld->grant_table; #if GRANT_DEBUG_VERBOSE - if ( ld->domain_ id != 0 ) { + if ( ld->domain_id != 0 ) { DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", rd->domain_id, ld->domain_id, frame, readonly); } diff --git a/xen/include/public/io/netif.h b/xen/include/public/io/netif.h index 3ec38d0fda..528a5b0202 100644 --- a/xen/include/public/io/netif.h +++ b/xen/include/public/io/netif.h @@ -23,13 +23,13 @@ typedef struct netif_tx_response { typedef struct { u16 id; /* Echoed in response message. */ -#ifdef CONFIG_XEN_NETDEV_GRANT_RX +#ifdef CONFIG_XEN_NETDEV_GRANT grant_ref_t gref; /* 2: Reference to incoming granted frame */ #endif } netif_rx_request_t; typedef struct { -#ifdef CONFIG_XEN_NETDEV_GRANT_TX +#ifdef CONFIG_XEN_NETDEV_GRANT u32 addr; /* 0: Offset in page of start of received packet */ #else unsigned long addr; /* Machine address of packet. */ From 607314f72589f9b6e77ecf797ce5de97fcd943e1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 07:53:46 +0000 Subject: [PATCH 04/12] The attached patch makes xend clear the reboot request from the store when rebooting a domain. This prevents the lingering request from being re-fulfilled, such as when executing a subsequent sysrq request. Signed-off-by: Dan Smith --- tools/python/xen/xend/XendDomainInfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index ee8edd566f..abb692f051 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1006,6 +1006,7 @@ class XendDomainInfo: """ try: + self.clear_shutdown() self.state = STATE_VM_OK self.shutdown_pending = None self.restart_check() From 854aa64ec62e72b2f4e4baf708488056a37113e7 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 07:55:22 +0000 Subject: [PATCH 05/12] I've found cramfs to be very useful for simplifying Xen testing with QEMU. Also, I imagine cramfs is used frequently for initrds so it's probably a good idea to support it out of the box. Signed-off-by: Anthony Liguori --- linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 | 2 +- linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 index 5b61cd071a..299d96dcbc 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 @@ -1123,7 +1123,7 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 index 0d945215c9..314c67bf49 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 @@ -1032,7 +1032,7 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set From c544d29d6f53d04bc7136c473a0d235182f95982 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 07:55:45 +0000 Subject: [PATCH 06/12] Make the check script log to /tmp instead of the working directory. This allows us to install from a read-only file system (such as a cdrom). Signed-off-by: Anthony Liguori --- tools/check/chk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/check/chk b/tools/check/chk index 0ebce4799e..c9b7adead5 100755 --- a/tools/check/chk +++ b/tools/check/chk @@ -17,14 +17,14 @@ export PATH=${PATH}:/sbin:/usr/sbin case $1 in build) check="CHECK-BUILD" - info=".chkbuild" + info="/tmp/xen.chkbuild" ;; install) check="CHECK-INSTALL" - info=".chkinstall" + info="/tmp/xen.chkinstall" ;; clean) - rm -f .chkbuild .chkinstall + rm -f /tmp/xen.chkbuild /tmp/xen.chkinstall exit 0 ;; *) From 7e9596058beeb1bed9384cc56b6a1caae6d8c4fa Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 07:59:12 +0000 Subject: [PATCH 07/12] This patch: * adds a get_ssid ACM command that allows privileged domains to retrieve types for either a given ssid reference or a given domain id (of a running domain); this command can be used to extend access control into device domains, e.g., to control network traffic currently moving through Domain 0 uncontrolled by the ACM policy * adds a script getlabel.sh that allows users inside Dom0 to retrieve the label for a given ssid reference or a given domain id (multiple labels might map onto a single ssid reference) * cleans up label-related code in tools/security by merging common functions into labelfuncs.sh * cleans up ACM code related to above changes (eventually approximating a common coding style) Signed-off-by Reiner Sailer Signed-off by Stefan Berger --- tools/security/Makefile | 1 + tools/security/secpol_tool.c | 140 ++++++++- tools/security/setlabel.sh | 313 +++----------------- xen/acm/acm_chinesewall_hooks.c | 23 ++ xen/acm/acm_core.c | 146 +++++---- xen/acm/acm_null_hooks.c | 13 +- xen/acm/acm_policy.c | 122 ++++++-- xen/acm/acm_simple_type_enforcement_hooks.c | 42 ++- xen/common/acm_ops.c | 33 ++- xen/include/acm/acm_core.h | 9 +- xen/include/acm/acm_hooks.h | 1 + xen/include/public/acm.h | 32 +- xen/include/public/acm_ops.h | 17 +- 13 files changed, 513 insertions(+), 379 deletions(-) diff --git a/tools/security/Makefile b/tools/security/Makefile index f6654d486c..23a6eea078 100644 --- a/tools/security/Makefile +++ b/tools/security/Makefile @@ -45,6 +45,7 @@ build: mk-symlinks $(MAKE) secpol_xml2bin chmod 700 ./setlabel.sh chmod 700 ./updategrub.sh + chmod 700 ./getlabel.sh secpol_tool : secpol_tool.c secpol_compat.h $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< diff --git a/tools/security/secpol_tool.c b/tools/security/secpol_tool.c index a22908d7c0..e5d4e34298 100644 --- a/tools/security/secpol_tool.c +++ b/tools/security/secpol_tool.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,17 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ errno, strerror(errno)) +void usage(char *progname) +{ + printf("Use: %s \n" + "\t getpolicy\n" + "\t dumpstats\n" + "\t loadpolicy \n" + "\t getssid -d [-f]\n" + "\t getssid -s [-f]\n", progname); + exit(-1); +} + static inline int do_policycmd(int xc_handle, unsigned int cmd, unsigned long data) { @@ -320,7 +332,7 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename) if (ret) printf - ("ERROR setting policy. Use 'xm dmesg' to see details.\n"); + ("ERROR setting policy. Try 'xm dmesg' to see details.\n"); else printf("Successfully changed policy.\n"); @@ -370,7 +382,7 @@ int acm_domain_dumpstats(int xc_handle) if (ret < 0) { - printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); + printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n"); return ret; } stats = (struct acm_stats_buffer *) stats_buffer; @@ -421,18 +433,122 @@ int acm_domain_dumpstats(int xc_handle) } return ret; } +/************************ get ssidref & types ******************************/ +/* + * the ssid (types) can be looked up either by domain id or by ssidref + */ +int acm_domain_getssid(int xc_handle, int argc, char * const argv[]) +{ + /* this includes header and a set of types */ + #define MAX_SSIDBUFFER 2000 + int ret, i; + acm_op_t op; + struct acm_ssid_buffer *hdr; + unsigned char *buf; + int nice_print = 1; + + op.cmd = ACM_GETSSID; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getssid.get_ssid_by = UNSET; + /* arguments + -d ... domain id to look up + -s ... ssidref number to look up + -f ... formatted print (scripts depend on this format) + */ + while (1) + { + int c = getopt(argc, argv, "d:s:f"); + if (c == -1) + break; + if (c == 'd') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = DOMAINID; + op.u.getssid.id.domainid = strtoul(optarg, NULL, 0); + } + else if (c== 's') + { + if (op.u.getssid.get_ssid_by != UNSET) + usage(argv[0]); + op.u.getssid.get_ssid_by = SSIDREF; + op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0); + } + else if (c== 'f') + { + nice_print = 0; + } + else + usage(argv[0]); + } + if (op.u.getssid.get_ssid_by == UNSET) + usage(argv[0]); + + buf = malloc(MAX_SSIDBUFFER); + if (!buf) + return -ENOMEM; + + /* dump it and then push it down into xen/acm */ + op.u.getssid.ssidbuf = buf; /* out */ + op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER; + ret = do_acm_op(xc_handle, &op); + + if (ret) + { + printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n"); + goto out; + } + hdr = (struct acm_ssid_buffer *)buf; + if (hdr->len > MAX_SSIDBUFFER) + { + printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n", + ret, hdr->len); + return -EIO; + } + if (nice_print) + { + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + printf(" P: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->primary_policy_code), hdr->primary_max_types); + printf(" Types: "); + for (i=0; i< hdr->primary_max_types; i++) + if (buf[hdr->primary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + + printf(" S: %s, max_types = %d\n", + ACM_POLICY_NAME(hdr->secondary_policy_code), hdr->secondary_max_types); + printf(" Types: "); + for (i=0; i< hdr->secondary_max_types; i++) + if (buf[hdr->secondary_types_offset + i]) + printf("%02x ", i); + else + printf("-- "); + printf("\n"); + } + else + { + /* formatted print for use with scripts (.sh) + * update scripts when updating here (usually + * used in combination with -d to determine a + * running domain's label + */ + printf("SSID: ssidref = 0x%08x \n", hdr->ssidref); + } + + /* return ste ssidref */ + if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) & 0xffff; + else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) + ret = (hdr->ssidref) >> 16; + out: + return ret; +} /***************************** main **************************************/ -void usage(char *progname) -{ - printf("Use: %s \n" - "\t getpolicy\n" - "\t dumpstats\n" - "\t loadpolicy \n", progname); - exit(-1); -} - int main(int argc, char **argv) { @@ -459,6 +575,8 @@ int main(int argc, char **argv) if (argc != 2) usage(argv[0]); ret = acm_domain_dumpstats(acm_cmd_fd); + } else if (!strcmp(argv[1], "getssid")) { + ret = acm_domain_getssid(acm_cmd_fd, argc, argv); } else usage(argv[0]); diff --git a/tools/security/setlabel.sh b/tools/security/setlabel.sh index e0d8ed741a..9e0ec34482 100644 --- a/tools/security/setlabel.sh +++ b/tools/security/setlabel.sh @@ -34,277 +34,29 @@ if [ -z "$runbash" ]; then exec sh -c "bash $0 $*" fi +export PATH=$PATH:. +source labelfuncs.sh usage () { - echo "Usage: $0 [Option]