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