lkml.org 
[lkml]   [2011]   [Apr]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: 2.6.38.2 breaks suspend to disk
    From
    On Fri, Apr 1, 2011 at 1:21 PM, H. Peter Anvin <hpa@zytor.com> wrote:
    > On 04/01/2011 12:54 PM, Yinghai Lu wrote:
    >>
    >> ok, please check if you are happy with this one.
    >>
    >
    > The best would simply be:
    >
    >        mmu_cr4_features = read_cr4_safe();
    >
    > If this has to run before we can handle exceptions, one can verify the
    > existence by testing for the CPUID instruction (a CPU has CR4 if and
    > only if it has CPUID):
    >
    >        if (boot_cpu_data.cpuid_level >= 0)
    >                mmu_cr4_features = read_cr4_safe();
    >
    > ... since we set cpuid_level to -1 if there is no CPUID instruction.

    in that case could use read_cr4 directly.

    please check attached -v4

    Thanks
    From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

    [PATCH -v4] x86: Save cr4 to mmu_cr4_features at boot time

    Save cr4 to mmu_cr4_features at boot time

    Michael reported 2.6.38.2 hibernation is broken by one backported patch.
    it cause a freeze when resuming from hibernation

    | "x86: Cleanup highmap after brk is concluded"
    | commit id e5f15b45ddf3afa2bbbb10c7ea34fb32b6de0a0e.

    it turns out the mmu_cr4 save it lost somehow.

    -v3: read back cr4 for 32bit too according to HPA
    -v4: use cpuid_level to check if we can read cr4 according to HPA
    don't touch mmu_cr4_features if CONFIG_HIBERNATION is defined from Yinghai

    Bisected-and-tested-by: Michael Leun <lkml20101129@newton.leun.net>
    Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    Signed-off-by: Yinghai Lu <yinghai@kernel.org>

    ---
    arch/x86/include/asm/processor.h | 4 ++++
    arch/x86/kernel/setup.c | 11 ++++++++++-
    2 files changed, 14 insertions(+), 1 deletion(-)

    Index: linux-2.6/arch/x86/kernel/setup.c
    ===================================================================
    --- linux-2.6.orig/arch/x86/kernel/setup.c
    +++ linux-2.6/arch/x86/kernel/setup.c
    @@ -212,7 +212,11 @@ struct cpuinfo_x86 boot_cpu_data __read_
    EXPORT_SYMBOL(boot_cpu_data);
    #endif

    -
    +/*
    + * mmu_cr4_features two purpose:
    + * a. head_32.S will access cr4 according if X86_CR4_PAE is set in it.
    + * b. store read back cr4 for hibernation
    + */
    #if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
    unsigned long mmu_cr4_features;
    #else
    @@ -892,6 +896,11 @@ void __init setup_arch(char **cmdline_p)

    high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
    #endif
    +#ifdef CONFIG_HIBERNATION
    + /* a CPU has CR4 iff it has CPUID --- hpa */
    + if (boot_cpu_data.cpuid_level >= 0)
    + mmu_cr4_features = read_cr4();
    +#endif

    /*
    * Find and reserve possible boot-time SMP configuration:
    Index: linux-2.6/arch/x86/include/asm/processor.h
    ===================================================================
    --- linux-2.6.orig/arch/x86/include/asm/processor.h
    +++ linux-2.6/arch/x86/include/asm/processor.h
    @@ -601,7 +601,9 @@ static inline void set_in_cr4(unsigned l
    {
    unsigned long cr4;

    +#ifdef CONFIG_HIBERNATION
    mmu_cr4_features |= mask;
    +#endif
    cr4 = read_cr4();
    cr4 |= mask;
    write_cr4(cr4);
    @@ -611,7 +613,9 @@ static inline void clear_in_cr4(unsigned
    {
    unsigned long cr4;

    +#ifdef CONFIG_HIBERNATION
    mmu_cr4_features &= ~mask;
    +#endif
    cr4 = read_cr4();
    cr4 &= ~mask;
    write_cr4(cr4);
    \
     
     \ /
      Last update: 2011-04-01 23:27    [W:0.026 / U:1.160 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site