Tristan Gingold
2006-Jul-07 11:06 UTC
[Xen-devel] RFCs: drivers/xen/core/reboot.c for ia64
Hi, recently I have ported the save & restore feature on ia64. We are now trying to merge. I have created an ia64/ subdirectory in tools/libxc (as recently suggested). The first question is wether should I write a Makefile in this subdirectly or should I reference the files directly in the libxc/ Makefile ? I expected about 5 ia64-specific files. The next question is about reboot.c. Currently it is rather x86-specific. Severals lines have to be #if/#endif for ia64. The file is reproduces below. I''d just expect comments to know if this approach is ok or how to improve it. Thanks, Tristan. #define __KERNEL_SYSCALLS__ #include <linux/version.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/unistd.h> #include <linux/module.h> #include <linux/reboot.h> #include <linux/sysrq.h> #include <linux/stringify.h> #include <asm/irq.h> #include <asm/mmu_context.h> #include <xen/evtchn.h> #include <asm/hypervisor.h> #include <xen/interface/dom0_ops.h> #include <xen/xenbus.h> #include <linux/cpu.h> #include <linux/kthread.h> #include <xen/gnttab.h> #include <xen/xencons.h> #include <xen/cpu_hotplug.h> #if defined(__i386__) || defined(__x86_64__) /* * Power off function, if any */ void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); #endif extern void ctrl_alt_del(void); #define SHUTDOWN_INVALID -1 #define SHUTDOWN_POWEROFF 0 #define SHUTDOWN_SUSPEND 2 /* Code 3 is SHUTDOWN_CRASH, which we don''t use because the domain can only * report a crash, not be instructed to crash! * HALT is the same as POWEROFF, as far as we''re concerned. The tools use * the distinction when we return the reason code to them. */ #define SHUTDOWN_HALT 4 #ifdef CONFIG_X86 void machine_emergency_restart(void) { /* We really want to get pending console data out before we die. */ xencons_force_flush(); HYPERVISOR_shutdown(SHUTDOWN_reboot); } void machine_restart(char * __unused) { machine_emergency_restart(); } void machine_halt(void) { machine_power_off(); } void machine_power_off(void) { /* We really want to get pending console data out before we die. */ xencons_force_flush(); #if defined(__i386__) || defined(__x86_64__) if (pm_power_off) pm_power_off(); #endif HYPERVISOR_shutdown(SHUTDOWN_poweroff); } int reboot_thru_bios = 0; /* for dmi_scan.c */ EXPORT_SYMBOL(machine_restart); EXPORT_SYMBOL(machine_halt); EXPORT_SYMBOL(machine_power_off); #endif /****************************************************************************** * Stop/pickle callback handling. */ /* Ignore multiple shutdown requests. */ static int shutting_down = SHUTDOWN_INVALID; static void __shutdown_handler(void *unused); static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); #ifdef CONFIG_X86 /* Ensure we run on the idle task page tables so that we will switch page tables before running user space. This is needed on architectures with separate kernel and user page tables because the user page table pointer is not saved/restored. */ static void switch_idle_mm(void) { struct mm_struct *mm = current->active_mm; if (mm == &init_mm) return; atomic_inc(&init_mm.mm_count); switch_mm(mm, &init_mm, current); current->active_mm = &init_mm; mmdrop(mm); } #endif static int __do_suspend(void *ignore) { int err; #ifdef CONFIG_X86 int i, j, k, fpp; extern unsigned long max_pfn; extern unsigned long *pfn_to_mfn_frame_list_list; extern unsigned long *pfn_to_mfn_frame_list[]; #endif extern void time_resume(void); BUG_ON(smp_processor_id() != 0); BUG_ON(in_interrupt()); #ifdef CONFIG_X86 if (xen_feature(XENFEAT_auto_translated_physmap)) { printk(KERN_WARNING "Cannot suspend in " "auto_translated_physmap mode.\n"); return -EOPNOTSUPP; } #endif err = smp_suspend(); if (err) return err; xenbus_suspend(); preempt_disable(); #ifdef __i386__ kmem_cache_shrink(pgd_cache); #endif #ifdef CONFIG_X86 mm_pin_all(); __cli(); #endif #ifdef __ia64__ local_irq_disable(); #endif preempt_enable(); gnttab_suspend(); #ifdef CONFIG_X86 HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; clear_fixmap(FIX_SHARED_INFO); xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn); #endif /* * We''ll stop somewhere inside this hypercall. When it returns, * we''ll start resuming after the restore. */ HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); shutting_down = SHUTDOWN_INVALID; #ifdef CONFIG_X86 set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); memset(empty_zero_page, 0, PAGE_SIZE); HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list virt_to_mfn(pfn_to_mfn_frame_list_list); fpp = PAGE_SIZE/sizeof(unsigned long); for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { if ((j % fpp) == 0) { k++; pfn_to_mfn_frame_list_list[k] virt_to_mfn(pfn_to_mfn_frame_list[k]); j = 0; } pfn_to_mfn_frame_list[k][j] virt_to_mfn(&phys_to_machine_mapping[i]); } HYPERVISOR_shared_info->arch.max_pfn = max_pfn; #endif gnttab_resume(); irq_resume(); time_resume(); #ifdef CONFIG_X86 switch_idle_mm(); __sti(); #endif #ifdef __ia64__ local_irq_enable(); #endif xencons_resume(); xenbus_resume(); smp_resume(); return err; } [...] _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel