[IA64] kexec: Use a separate RID for EFI
authorIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 22 Jul 2008 03:15:02 +0000 (12:15 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 22 Jul 2008 03:15:02 +0000 (12:15 +0900)
This activates the use of the EFI RID.

The basic idea is to switch to this RID, which is in the range reserved
for the hypervisor, before making EFI, PAL or SAL calls. The page fault
handler where the identity mapping checks for this RID, if present it
does the identity mapping, else it just follows the normal mapping
rules. In this way, VMX domains should not be able to access this
memory, and they should be able to use the virtual addresses that are
used by EFI for their own purposes.

Subsequent patches move EFI memory such that faults to it will
be protected by the EFI RID.

Cc: Tristan Gingold <tgingold@free.fr>
Cc: Isaku Yamahata <yamahata@valinux.co.jp>
Cc: Alex Williamson <alex.williamson@hp.com>
Cc: Aron Griffis <aron@hp.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
xen/arch/ia64/linux-xen/efi.c
xen/include/asm-ia64/linux-xen/asm/pal.h
xen/include/asm-ia64/linux-xen/asm/sal.h

index 3eebc229ddae0e5b5939b4c9ba6aed86afa81676..1aa44ec1fcf49b5a3e1ccc3c2f179dd83a719f3f 100644 (file)
@@ -65,11 +65,14 @@ prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc)                                                \
        struct ia64_fpreg fr[6];                                                                  \
        efi_time_cap_t *atc = NULL;                                                               \
        efi_status_t ret;                                                                         \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                  \
        if (tc)                                                                                   \
                atc = adjust_arg(tc);                                                             \
        ia64_save_scratch_fpregs(fr);                                                             \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), atc); \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                             \
        return ret;                                                                               \
 }
@@ -80,9 +83,12 @@ prefix##_set_time (efi_time_t *tm)                                                           \
 {                                                                                              \
        struct ia64_fpreg fr[6];                                                                \
        efi_status_t ret;                                                                       \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                \
        ia64_save_scratch_fpregs(fr);                                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm));    \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                           \
        return ret;                                                                             \
 }
@@ -93,10 +99,13 @@ prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *
 {                                                                                              \
        struct ia64_fpreg fr[6];                                                                \
        efi_status_t ret;                                                                       \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                \
        ia64_save_scratch_fpregs(fr);                                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time),       \
                                adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm));      \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                           \
        return ret;                                                                             \
 }
@@ -108,12 +117,15 @@ prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)                                     \
        struct ia64_fpreg fr[6];                                                                \
        efi_time_t *atm = NULL;                                                                 \
        efi_status_t ret;                                                                       \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                \
        if (tm)                                                                                 \
                atm = adjust_arg(tm);                                                           \
        ia64_save_scratch_fpregs(fr);                                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time),       \
                                enabled, atm);                                                  \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                           \
        return ret;                                                                             \
 }
@@ -126,13 +138,16 @@ prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,         \
        struct ia64_fpreg fr[6];                                                        \
        u32 *aattr = NULL;                                                                      \
        efi_status_t ret;                                                               \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                        \
        if (attr)                                                                       \
                aattr = adjust_arg(attr);                                               \
        ia64_save_scratch_fpregs(fr);                                                   \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_get_variable_t *) __va(runtime->get_variable),     \
                                adjust_arg(name), adjust_arg(vendor), aattr,            \
                                adjust_arg(data_size), adjust_arg(data));               \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                   \
        return ret;                                                                     \
 }
@@ -143,10 +158,13 @@ prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_gu
 {                                                                                              \
        struct ia64_fpreg fr[6];                                                                \
        efi_status_t ret;                                                                       \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                \
        ia64_save_scratch_fpregs(fr);                                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_get_next_variable_t *) __va(runtime->get_next_variable),   \
                                adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor));   \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                           \
        return ret;                                                                             \
 }
@@ -158,11 +176,14 @@ prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, unsigned long att
 {                                                                                      \
        struct ia64_fpreg fr[6];                                                        \
        efi_status_t ret;                                                               \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                        \
        ia64_save_scratch_fpregs(fr);                                                   \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_set_variable_t *) __va(runtime->set_variable),     \
                                adjust_arg(name), adjust_arg(vendor), attr, data_size,  \
                                adjust_arg(data));                                      \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                   \
        return ret;                                                                     \
 }
@@ -173,10 +194,13 @@ prefix##_get_next_high_mono_count (u32 *count)                                                    \
 {                                                                                              \
        struct ia64_fpreg fr[6];                                                                \
        efi_status_t ret;                                                                       \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                                \
        ia64_save_scratch_fpregs(fr);                                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                                               \
        ret = efi_call_##prefix((efi_get_next_high_mono_count_t *)                              \
                                __va(runtime->get_next_high_mono_count), adjust_arg(count));    \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                                           \
        return ret;                                                                             \
 }
@@ -188,14 +212,17 @@ prefix##_reset_system (int reset_type, efi_status_t status,                       \
 {                                                                              \
        struct ia64_fpreg fr[6];                                                \
        efi_char16_t *adata = NULL;                                             \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                                                             \
                                                                                \
        if (data)                                                               \
                adata = adjust_arg(data);                                       \
                                                                                \
        ia64_save_scratch_fpregs(fr);                                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                                             \
        efi_call_##prefix((efi_reset_system_t *) __va(runtime->reset_system),   \
                          reset_type, status, data_size, adata);                \
        /* should not return, but just in case... */                            \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                                                               \
        ia64_load_scratch_fpregs(fr);                                           \
 }
 
index 00e32c5d6e01a1f33b0ad58e3942c5a5923a7d0f..c6340ed59146b49e4c2eed13fee1fac560c01b72 100644 (file)
@@ -93,6 +93,9 @@
 
 #include <linux/types.h>
 #include <asm/fpu.h>
+#ifdef XEN
+#include <linux/efi.h>
+#endif
 
 /*
  * Data types needed to pass information into PAL procedures and
@@ -791,29 +794,41 @@ extern void ia64_load_scratch_fpregs (struct ia64_fpreg *);
 
 #define PAL_CALL(iprv,a0,a1,a2,a3) do {                        \
        struct ia64_fpreg fr[6];                        \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                   \
        ia64_save_scratch_fpregs(fr);                   \
+       XEN_EFI_RR_ENTER(rr6, rr7);                     \
        iprv = ia64_pal_call_static(a0, a1, a2, a3);    \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                     \
        ia64_load_scratch_fpregs(fr);                   \
 } while (0)
 
 #define PAL_CALL_STK(iprv,a0,a1,a2,a3) do {            \
        struct ia64_fpreg fr[6];                        \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                   \
        ia64_save_scratch_fpregs(fr);                   \
+       XEN_EFI_RR_ENTER(rr6, rr7);                     \
        iprv = ia64_pal_call_stacked(a0, a1, a2, a3);   \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                     \
        ia64_load_scratch_fpregs(fr);                   \
 } while (0)
 
 #define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) do {                   \
        struct ia64_fpreg fr[6];                                \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                           \
        ia64_save_scratch_fpregs(fr);                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                             \
        iprv = ia64_pal_call_phys_static(a0, a1, a2, a3);       \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                             \
        ia64_load_scratch_fpregs(fr);                           \
 } while (0)
 
 #define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) do {               \
        struct ia64_fpreg fr[6];                                \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                           \
        ia64_save_scratch_fpregs(fr);                           \
+       XEN_EFI_RR_ENTER(rr6, rr7);                             \
        iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3);      \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                             \
        ia64_load_scratch_fpregs(fr);                           \
 } while (0)
 
index 2af85b14b6265d3dd0b28642d1ff1b1117309cf1..e52ac0dbf53b40364c04da3f7934a0c1f548b7df 100644 (file)
@@ -52,9 +52,12 @@ extern spinlock_t sal_lock;
 # define SAL_CALL(result,args...) do {                         \
        unsigned long __ia64_sc_flags;                          \
        struct ia64_fpreg __ia64_sc_fr[6];                      \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                           \
        ia64_save_scratch_fpregs(__ia64_sc_fr);                 \
        spin_lock_irqsave(&sal_lock, __ia64_sc_flags);          \
+       XEN_EFI_RR_ENTER(rr6, rr7);                             \
        __SAL_CALL(result, args);                               \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                             \
        spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags);     \
        ia64_load_scratch_fpregs(__ia64_sc_fr);                 \
 } while (0)
@@ -62,18 +65,24 @@ extern spinlock_t sal_lock;
 # define SAL_CALL_NOLOCK(result,args...) do {          \
        unsigned long __ia64_scn_flags;                 \
        struct ia64_fpreg __ia64_scn_fr[6];             \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                   \
        ia64_save_scratch_fpregs(__ia64_scn_fr);        \
        local_irq_save(__ia64_scn_flags);               \
+       XEN_EFI_RR_ENTER(rr6, rr7);                     \
        __SAL_CALL(result, args);                       \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                     \
        local_irq_restore(__ia64_scn_flags);            \
        ia64_load_scratch_fpregs(__ia64_scn_fr);        \
 } while (0)
 
 # define SAL_CALL_REENTRANT(result,args...) do {       \
        struct ia64_fpreg __ia64_scs_fr[6];             \
+       XEN_EFI_RR_DECLARE(rr6, rr7);                   \
        ia64_save_scratch_fpregs(__ia64_scs_fr);        \
        preempt_disable();                              \
+       XEN_EFI_RR_ENTER(rr6, rr7);                     \
        __SAL_CALL(result, args);                       \
+       XEN_EFI_RR_LEAVE(rr6, rr7);                     \
        preempt_enable();                               \
        ia64_load_scratch_fpregs(__ia64_scs_fr);        \
 } while (0)