|
|
|
|
|
|
|
|
|
|
xen-devel
[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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-devel] RFCs: drivers/xen/core/reboot.c for ia64,
Tristan Gingold <=
|
|
|
|
|