[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.