Samuel Thibault
2008-Jun-09 12:01 UTC
[Xen-devel] [PATCH] minios: add proper shutdown facilities
minios: add proper shutdown facilities Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r a40c23c25b0d extras/mini-os/arch/ia64/common.c --- a/extras/mini-os/arch/ia64/common.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/arch/ia64/common.c Mon Jun 09 10:14:04 2008 +0100 @@ -236,6 +236,12 @@ } void +arch_fini(void) +{ + /* TODO */ +} + +void arch_print_info(void) { int major, minor; --- a/extras/mini-os/arch/ia64/time.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/arch/ia64/time.c Mon Jun 09 10:14:04 2008 +0100 @@ -280,3 +280,9 @@ ia64_set_itm(new); ia64_srlz_d(); } + +void +fini_time(void) +{ + /* TODO */ +} --- a/extras/mini-os/arch/x86/setup.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/arch/x86/setup.c Mon Jun 09 10:14:05 2008 +0100 @@ -100,6 +100,16 @@ } void +arch_fini(void) +{ +#ifdef __i386__ + HYPERVISOR_set_callbacks(0, 0, 0, 0); +#else + HYPERVISOR_set_callbacks(0, 0, 0); +#endif +} + +void arch_print_info(void) { printk(" stack: %p-%p\n", stack, stack + sizeof(stack)); --- a/extras/mini-os/arch/x86/time.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/arch/x86/time.c Mon Jun 09 10:14:05 2008 +0100 @@ -222,10 +222,17 @@ +static evtchn_port_t port; void init_time(void) { - evtchn_port_t port; printk("Initialising timer interface\n"); port = bind_virq(VIRQ_TIMER, &timer_handler, NULL); unmask_evtchn(port); } + +void fini_time(void) +{ + /* Clear any pending timer */ + HYPERVISOR_set_timer_op(0); + unbind_evtchn(port); +} --- a/extras/mini-os/arch/x86/traps.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/arch/x86/traps.c Mon Jun 09 10:14:05 2008 +0100 @@ -268,3 +268,7 @@ HYPERVISOR_set_trap_table(trap_table); } +void trap_fini(void) +{ + HYPERVISOR_set_trap_table(NULL); +} --- a/extras/mini-os/blkfront.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/blkfront.c Mon Jun 09 10:14:05 2008 +0100 @@ -239,6 +239,8 @@ xenbus_wait_for_value(path, "6", &dev->events); xenbus_unwatch_path(XBT_NIL, path); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); free_blkfront(dev); } --- a/extras/mini-os/console/console.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/console/console.c Mon Jun 09 10:14:05 2008 +0100 @@ -150,3 +150,8 @@ /* This is also required to notify the daemon */ printk("done.\n"); } + +void fini_console(void) +{ + /* Destruct the console and get the parameters of the restarted one */ +} --- a/extras/mini-os/events.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/events.c Mon Jun 09 10:14:05 2008 +0100 @@ -39,19 +39,29 @@ void unbind_all_ports(void) { int i; + int cpu = 0; + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; for (i = 0; i < NR_EVS; i++) { + if (i == start_info.console.domU.evtchn || + i == start_info.store_evtchn) + continue; if (test_and_clear_bit(i, bound_ports)) { struct evtchn_close close; + printk("port %d still bound!\n", i); mask_evtchn(i); close.port = i; HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + clear_evtchn(i); } } + vcpu_info->evtchn_upcall_pending = 0; + vcpu_info->evtchn_pending_sel = 0; } - + /* * Demux events to different handlers. */ @@ -86,17 +96,27 @@ ev_actions[port].data = data; wmb(); ev_actions[port].handler = handler; + set_bit(port, bound_ports); return port; } void unbind_evtchn(evtchn_port_t port ) { + struct evtchn_close close; + if (ev_actions[port].handler == default_handler) printk("WARN: No handler for port %d when unbinding\n", port); + mask_evtchn(port); + clear_evtchn(port); + ev_actions[port].handler = default_handler; wmb(); ev_actions[port].data = NULL; + clear_bit(port, bound_ports); + + close.port = port; + HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); } evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data) @@ -112,7 +132,6 @@ printk("Failed to bind virtual IRQ %d\n", virq); return -1; } - set_bit(op.port,bound_ports); bind_evtchn(op.port, handler, data); return op.port; } @@ -145,6 +164,15 @@ ev_actions[i].handler = default_handler; mask_evtchn(i); } +} + +void fini_events(void) +{ + /* Dealloc all events */ + unbind_all_ports(); +#if defined(__x86_64__) + wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */ +#endif } void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore) @@ -185,7 +213,6 @@ int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op); if (err) return err; - set_bit(op.local_port,bound_ports); evtchn_port_t port = op.local_port; *local_port = bind_evtchn(port, handler, data); return err; --- a/extras/mini-os/fbfront.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/fbfront.c Mon Jun 09 10:14:05 2008 +0100 @@ -224,6 +224,8 @@ xenbus_wait_for_value(path, "6", &dev->events); xenbus_unwatch_path(XBT_NIL, path); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); free_kbdfront(dev); } @@ -549,6 +551,8 @@ xenbus_unwatch_path(XBT_NIL, path); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + unbind_evtchn(dev->evtchn); free_fbfront(dev); --- a/extras/mini-os/fs-front.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/fs-front.c Mon Jun 09 10:14:05 2008 +0100 @@ -1127,3 +1127,5 @@ if (!fs_import) printk("No FS import\n"); } + +/* TODO: shutdown */ --- a/extras/mini-os/gnttab.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/gnttab.c Mon Jun 09 10:14:05 2008 +0100 @@ -193,3 +193,14 @@ gnttab_table = map_frames(frames, NR_GRANT_FRAMES); printk("gnttab_table mapped at %p.\n", gnttab_table); } + +void +fini_gnttab(void) +{ + struct gnttab_setup_table setup; + + setup.dom = DOMID_SELF; + setup.nr_frames = 0; + + HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); +} --- a/extras/mini-os/include/console.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/console.h Mon Jun 09 10:14:05 2008 +0100 @@ -51,6 +51,7 @@ void init_console(void); void console_print(char *data, int length); +void fini_console(void); /* Low level functions defined in xencons_ring.c */ extern struct wait_queue_head console_queue; --- a/extras/mini-os/include/events.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/events.h Mon Jun 09 10:14:05 2008 +0100 @@ -45,5 +45,6 @@ return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op); } +void fini_events(void); #endif /* _EVENTS_H_ */ --- a/extras/mini-os/include/gnttab.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/gnttab.h Mon Jun 09 10:14:05 2008 +0100 @@ -11,5 +11,6 @@ unsigned long gnttab_end_transfer(grant_ref_t gref); int gnttab_end_access(grant_ref_t ref); const char *gnttabop_error(int16_t status); +void fini_gnttab(void); #endif /* !__GNTTAB_H__ */ --- a/extras/mini-os/include/ia64/os.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/ia64/os.h Mon Jun 09 10:14:05 2008 +0100 @@ -35,6 +35,7 @@ #include "sal.h" #include "pal.h" #include "hypervisor.h" +#include <kernel.h> typedef uint64_t paddr_t; /* Physical address. */ @@ -46,9 +47,9 @@ #include "mm.h" -void do_exit(void) __attribute__((noreturn)); void arch_init(start_info_t *si); /* in common.c */ void arch_print_info(void); /* in common.c */ +void arch_fini(void); /* Size of xen_ia64_boot_param.command_line */ --- a/extras/mini-os/include/ia64/traps.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/ia64/traps.h Mon Jun 09 10:14:05 2008 +0100 @@ -38,6 +38,10 @@ { //printk("trap_init() until now not needed!\n"); } +inline static void trap_fini(void) +{ + //printk("trap_fini() until now not needed!\n"); +} #endif /* !defined(__ASSEMBLY__) */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/kernel.h Mon Jun 09 10:14:05 2008 +0100 @@ -0,0 +1,7 @@ +#ifndef _KERNEL_H_ +#define _KERNEL_H_ + +extern void do_exit(void) __attribute__((noreturn)); +extern void stop_kernel(void); + +#endif /* _KERNEL_H_ */ --- a/extras/mini-os/include/mm.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/mm.h Mon Jun 09 10:14:05 2008 +0100 @@ -75,5 +75,6 @@ #endif int free_physical_pages(xen_pfn_t *mfns, int n); +void fini_mm(void); #endif /* _MM_H_ */ --- a/extras/mini-os/include/netfront.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/netfront.h Mon Jun 09 10:14:05 2008 +0100 @@ -18,6 +18,7 @@ * N.B. _must_ be called from a thread; it''s not safe to call this from * app_main(). */ void start_networking(void); +void stop_networking(void); void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw); #endif --- a/extras/mini-os/include/time.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/time.h Mon Jun 09 10:14:05 2008 +0100 @@ -54,6 +54,7 @@ /* prototypes */ void init_time(void); +void fini_time(void); s_time_t get_s_time(void); s_time_t get_v_time(void); u64 monotonic_clock(void); --- a/extras/mini-os/include/x86/os.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/x86/os.h Mon Jun 09 10:14:05 2008 +0100 @@ -18,10 +18,10 @@ #ifndef __ASSEMBLY__ #include <types.h> #include <hypervisor.h> +#include <kernel.h> #define USED __attribute__ ((used)) -extern void do_exit(void) __attribute__((noreturn)); #define BUG do_exit #endif @@ -61,9 +61,11 @@ extern shared_info_t *HYPERVISOR_shared_info; void trap_init(void); +void trap_fini(void); void arch_init(start_info_t *si); void arch_print_info(void); +void arch_fini(void); --- a/extras/mini-os/include/xenbus.h Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/include/xenbus.h Mon Jun 09 10:14:05 2008 +0100 @@ -90,4 +90,7 @@ char* node, char* path, char* fmt, ...); +/* Reset the XenBus system. */ +void fini_xenbus(void); + #endif /* XENBUS_H__ */ --- a/extras/mini-os/kernel.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/kernel.c Mon Jun 09 10:14:05 2008 +0100 @@ -46,6 +46,7 @@ #include <xen/features.h> #include <xen/version.h> +static struct netfront_dev *net_dev; u8 xen_features[XENFEAT_NR_SUBMAPS * 32]; @@ -87,7 +88,7 @@ static void netfront_thread(void *p) { - init_netfront(NULL, NULL, NULL, NULL); + net_dev = init_netfront(NULL, NULL, NULL, NULL); } static struct blkfront_dev *blk_dev; @@ -347,9 +348,9 @@ fbfront_update(fb_dev, new_x, new_y, 9, 9); } +static struct kbdfront_dev *kbd_dev; static void kbdfront_thread(void *p) { - struct kbdfront_dev *kbd_dev; DEFINE_WAIT(w); int x = WIDTH / 2, y = HEIGHT / 2, z = 0; @@ -509,6 +510,49 @@ run_idle_thread(); } +void stop_kernel(void) +{ + if (net_dev) + shutdown_netfront(net_dev); + + if (blk_dev) + shutdown_blkfront(blk_dev); + + if (fb_dev) + shutdown_fbfront(fb_dev); + + if (kbd_dev) + shutdown_kbdfront(kbd_dev); + + /* TODO: fs import */ + + local_irq_disable(); + + /* Reset grant tables */ + fini_gnttab(); + + /* Reset the console driver. */ + fini_console(); + /* TODO: record new ring mfn & event in start_info */ + + /* Reset XenBus */ + fini_xenbus(); + + /* Reset timers */ + fini_time(); + + /* Reset memory management. */ + fini_mm(); + + /* Reset events. */ + fini_events(); + + /* Reset traps */ + trap_fini(); + + /* Reset arch details */ + arch_fini(); +} /* * do_exit: This is called whenever an IRET fails in entry.S. --- a/extras/mini-os/lwip-net.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/lwip-net.c Mon Jun 09 10:14:05 2008 +0100 @@ -376,3 +376,9 @@ tprintk("Network is ready.\n"); } + +/* Shut down the network */ +void stop_networking(void) +{ + shutdown_netfront(dev); +} --- a/extras/mini-os/mm.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/mm.c Mon Jun 09 10:14:06 2008 +0100 @@ -419,6 +419,10 @@ arch_init_demand_mapping_area(max_pfn); } +void fini_mm(void) +{ +} + void sanity_check(void) { int x; --- a/extras/mini-os/netfront.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/netfront.c Mon Jun 09 10:14:06 2008 +0100 @@ -501,6 +501,8 @@ xenbus_unwatch_path(XBT_NIL, path); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + free_netfront(dev); } --- a/extras/mini-os/xenbus/xenbus.c Mon Jun 09 09:51:14 2008 +0100 +++ b/extras/mini-os/xenbus/xenbus.c Mon Jun 09 10:14:06 2008 +0100 @@ -124,7 +124,7 @@ static void xenbus_thread_func(void *ign) { struct xsd_sockmsg msg; - unsigned prod = 0; + unsigned prod = xenstore_buf->rsp_prod; for (;;) { @@ -174,9 +174,14 @@ break; } - event->next = *events; - *events = event; - wake_up(&xenbus_watch_queue); + if (events) { + event->next = *events; + *events = event; + wake_up(&xenbus_watch_queue); + } else { + printk("unexpected watch token %s\n", event->token); + free(event); + } } else @@ -263,6 +268,10 @@ NULL); unmask_evtchn(start_info.store_evtchn); DEBUG("xenbus on irq %d\n", err); +} + +void fini_xenbus(void) +{ } /* Send data to xenbus. This can block. All of the requests are seen _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel