WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

[Xen-ia64-devel] [patch 5/5] IA64: Kexec: Use a separate RID for EFI

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [patch 5/5] IA64: Kexec: Use a separate RID for EFI
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Mon, 22 Oct 2007 11:49:35 +0900
Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>, Alex Williamson <alex.williamson@xxxxxx>
Delivery-date: Sun, 21 Oct 2007 20:01:48 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20071022024930.186104656@xxxxxxxxxxxx>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
This patch is a first cut at implementing Yamahata-san's idea of
assigning a special RID for use with EFI mappings. 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.

The patch does seem to work, in the sense that the EFI mappings work.
I have not stress tested it to see if domains can still do nefarious
things. I would appreciate a review of this.

The patch is rather long, this is almost entirely due to
duplicating the PAL, EFI and SAL macros in order to squeeze
in the RID changes and wrap them in #if XEN. It would be shorter
if I didn't bother with #if XEN. I'm happy to do that if its
the prefered solution.

The patch also includes some header foo. This is basically
because pal.h needs to know about GRANULE_SIZE, and thus needs
pgtable.h. But without the header manipulation I added a loop
is formed. I can break this out into another patch if need be.
I'm also happy to examine alternative solutions to this problem,
but to be frank, the headers are a mess.

Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>

Index: xen-unstable.hg/xen/include/asm-ia64/linux/asm/sal.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux/asm/sal.h   2007-10-19 
16:59:50.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux/asm/sal.h        2007-10-19 
17:01:19.000000000 +0900
@@ -49,12 +49,48 @@ extern spinlock_t sal_lock;
 #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)     \
        result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7)
 
+#ifndef XEN
+
+# define SAL_CALL(result,args...) do {                         \
+       unsigned long __ia64_sc_flags;                          \
+       struct ia64_fpreg __ia64_sc_fr[6];                      \
+       ia64_save_scratch_fpregs(__ia64_sc_fr);                 \
+       spin_lock_irqsave(&sal_lock, __ia64_sc_flags);          \
+       __SAL_CALL(result, args);                               \
+       spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags);     \
+       ia64_load_scratch_fpregs(__ia64_sc_fr);                 \
+} while (0)
+
+# define SAL_CALL_NOLOCK(result,args...) do {          \
+       unsigned long __ia64_scn_flags;                 \
+       struct ia64_fpreg __ia64_scn_fr[6];             \
+       ia64_save_scratch_fpregs(__ia64_scn_fr);        \
+       local_irq_save(__ia64_scn_flags);               \
+       __SAL_CALL(result, args);                       \
+       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];             \
+       ia64_save_scratch_fpregs(__ia64_scs_fr);        \
+       preempt_disable();                              \
+       __SAL_CALL(result, args);                       \
+       preempt_enable();                               \
+       ia64_load_scratch_fpregs(__ia64_scs_fr);        \
+} while (0)
+
+#else /* XEN */
+
 # define SAL_CALL(result,args...) do {                         \
        unsigned long __ia64_sc_flags;                          \
        struct ia64_fpreg __ia64_sc_fr[6];                      \
+       int rr6, rr7;                                           \
        ia64_save_scratch_fpregs(__ia64_sc_fr);                 \
        spin_lock_irqsave(&sal_lock, __ia64_sc_flags);          \
+       EFI_RR_SAVE(rr6, rr7);                                  \
        __SAL_CALL(result, args);                               \
+       EFI_RR_RESTORE(rr6, rr7);                               \
        spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags);     \
        ia64_load_scratch_fpregs(__ia64_sc_fr);                 \
 } while (0)
@@ -62,22 +98,30 @@ extern spinlock_t sal_lock;
 # define SAL_CALL_NOLOCK(result,args...) do {          \
        unsigned long __ia64_scn_flags;                 \
        struct ia64_fpreg __ia64_scn_fr[6];             \
+       int rr6, rr7;                                   \
        ia64_save_scratch_fpregs(__ia64_scn_fr);        \
        local_irq_save(__ia64_scn_flags);               \
+       EFI_RR_SAVE(rr6, rr7);                          \
        __SAL_CALL(result, args);                       \
+       EFI_RR_RESTORE(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];             \
+       int rr6, rr7;                                   \
        ia64_save_scratch_fpregs(__ia64_scs_fr);        \
        preempt_disable();                              \
+       EFI_RR_SAVE(rr6, rr7);                          \
        __SAL_CALL(result, args);                       \
+       EFI_RR_RESTORE(rr6, rr7);                       \
        preempt_enable();                               \
        ia64_load_scratch_fpregs(__ia64_scs_fr);        \
 } while (0)
 
+#endif /* XEN */
+
 #define SAL_SET_VECTORS                        0x01000000
 #define SAL_GET_STATE_INFO             0x01000001
 #define SAL_GET_STATE_INFO_SIZE                0x01000002
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/efi.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/efi.c  2007-10-19 
17:01:19.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/efi.c       2007-10-19 
17:01:19.000000000 +0900
@@ -58,6 +58,7 @@ static unsigned long mem_limit = ~0UL, m
 
 #define efi_call_virt(f, args...)      (*(f))(args)
 
+#ifndef XEN
 #define STUB_GET_TIME(prefix, adjust_arg)                                      
                  \
 static efi_status_t                                                            
                  \
 prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc)                         
                  \
@@ -71,6 +72,7 @@ prefix##_get_time (efi_time_t *tm, efi_t
        ia64_save_scratch_fpregs(fr);                                           
                  \
        ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), 
adjust_arg(tm), atc); \
        ia64_load_scratch_fpregs(fr);                                           
                  \
+       ia64_set_rr(7, rr7);                                                    
                  \
        return ret;                                                             
                  \
 }
 
@@ -199,6 +201,179 @@ prefix##_reset_system (int reset_type, e
        ia64_load_scratch_fpregs(fr);                                           
\
 }
 
+#else /* XEN */
+
+#define STUB_GET_TIME(prefix, adjust_arg)                                      
                  \
+static efi_status_t                                                            
                  \
+prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc)                         
                  \
+{                                                                              
                  \
+       struct ia64_fpreg fr[6];                                                
                  \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_time_cap_t *atc = NULL;                                             
                  \
+       efi_status_t ret;                                                       
                  \
+                                                                               
                  \
+       if (tc)                                                                 
                  \
+               atc = adjust_arg(tc);                                           
                  \
+       ia64_save_scratch_fpregs(fr);                                           
                  \
+       EFI_RR_SAVE(rr6, rr7);                                                  
                  \
+       ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), 
adjust_arg(tm), atc); \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                  \
+       ia64_set_rr(7, rr7);                                                    
                  \
+       return ret;                                                             
                  \
+}
+
+#define STUB_SET_TIME(prefix, adjust_arg)                                      
                \
+static efi_status_t                                                            
                \
+prefix##_set_time (efi_time_t *tm)                                             
                \
+{                                                                              
                \
+       struct ia64_fpreg fr[6];                                                
                \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_status_t ret;                                                       
                \
+                                                                               
                \
+       ia64_save_scratch_fpregs(fr);                                           
                \
+       EFI_RR_SAVE(rr6, rr7);                                                  
                  \
+       ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), 
adjust_arg(tm));    \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                \
+       return ret;                                                             
                \
+}
+
+#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg)                               
                \
+static efi_status_t                                                            
                \
+prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t 
*tm)            \
+{                                                                              
                \
+       struct ia64_fpreg fr[6];                                                
                \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_status_t ret;                                                       
                \
+                                                                               
                \
+       ia64_save_scratch_fpregs(fr);                                           
                \
+       EFI_RR_SAVE(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));      \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                \
+       return ret;                                                             
                \
+}
+
+#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg)                               
                \
+static efi_status_t                                                            
                \
+prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)                  
                \
+{                                                                              
                \
+       struct ia64_fpreg fr[6];                                                
                \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_time_t *atm = NULL;                                                 
                \
+       efi_status_t ret;                                                       
                \
+                                                                               
                \
+       if (tm)                                                                 
                \
+               atm = adjust_arg(tm);                                           
                \
+       ia64_save_scratch_fpregs(fr);                                           
                \
+       EFI_RR_SAVE(rr6, rr7);                                                  
                  \
+       ret = efi_call_##prefix((efi_set_wakeup_time_t *) 
__va(runtime->set_wakeup_time),       \
+                               enabled, atm);                                  
                \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                \
+       return ret;                                                             
                \
+}
+
+#define STUB_GET_VARIABLE(prefix, adjust_arg)                                  
        \
+static efi_status_t                                                            
        \
+prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,      
        \
+                      unsigned long *data_size, void *data)                    
        \
+{                                                                              
        \
+       struct ia64_fpreg fr[6];                                                
        \
+       unsigned long rr6, rr7;                                                 
                  \
+       u32 *aattr = NULL;                                                      
                \
+       efi_status_t ret;                                                       
        \
+                                                                               
        \
+       if (attr)                                                               
        \
+               aattr = adjust_arg(attr);                                       
        \
+       ia64_save_scratch_fpregs(fr);                                           
        \
+       EFI_RR_SAVE(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));       
        \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
        \
+       return ret;                                                             
        \
+}
+
+#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg)                             
                \
+static efi_status_t                                                            
                \
+prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, 
efi_guid_t *vendor)  \
+{                                                                              
                \
+       struct ia64_fpreg fr[6];                                                
                \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_status_t ret;                                                       
                \
+                                                                               
                \
+       ia64_save_scratch_fpregs(fr);                                           
                \
+       EFI_RR_SAVE(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));   \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                \
+       return ret;                                                             
                \
+}
+
+#define STUB_SET_VARIABLE(prefix, adjust_arg)                                  
        \
+static efi_status_t                                                            
        \
+prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, unsigned long 
attr,     \
+                      unsigned long data_size, void *data)                     
        \
+{                                                                              
        \
+       struct ia64_fpreg fr[6];                                                
        \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_status_t ret;                                                       
        \
+                                                                               
        \
+       ia64_save_scratch_fpregs(fr);                                           
        \
+       EFI_RR_SAVE(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));                              
        \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
        \
+       return ret;                                                             
        \
+}
+
+#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg)                      
                \
+static efi_status_t                                                            
                \
+prefix##_get_next_high_mono_count (u32 *count)                                 
                \
+{                                                                              
                \
+       struct ia64_fpreg fr[6];                                                
                \
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_status_t ret;                                                       
                \
+                                                                               
                \
+       ia64_save_scratch_fpregs(fr);                                           
                \
+       EFI_RR_SAVE(rr6, rr7);                                                  
                  \
+       ret = efi_call_##prefix((efi_get_next_high_mono_count_t *)              
                \
+                               __va(runtime->get_next_high_mono_count), 
adjust_arg(count));    \
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
                \
+       return ret;                                                             
                \
+}
+
+#define STUB_RESET_SYSTEM(prefix, adjust_arg)                                  
\
+static void                                                                    
\
+prefix##_reset_system (int reset_type, efi_status_t status,                    
\
+                      unsigned long data_size, efi_char16_t *data)             
\
+{                                                                              
\
+       struct ia64_fpreg fr[6];                                                
\
+       unsigned long rr6, rr7;                                                 
                  \
+       efi_char16_t *adata = NULL;                                             
\
+                                                                               
\
+       if (data)                                                               
\
+               adata = adjust_arg(data);                                       
\
+                                                                               
\
+       ia64_save_scratch_fpregs(fr);                                           
\
+       EFI_RR_SAVE(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... */                            
\
+       EFI_RR_RESTORE(rr6, rr7);                                               
                  \
+       ia64_load_scratch_fpregs(fr);                                           
\
+}
+
+#endif /* XEN */
+
 #define phys_ptr(arg)  ((__typeof__(arg)) ia64_tpa(arg))
 
 STUB_GET_TIME(phys, phys_ptr)
Index: xen-unstable.hg/xen/arch/ia64/xen/faults.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/faults.c     2007-10-19 
17:01:19.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/faults.c  2007-10-19 17:01:19.000000000 
+0900
@@ -32,6 +32,7 @@
 #include <asm/shadow.h>
 #include <asm/uaccess.h>
 #include <asm/p2m_entry.h>
+#include <asm/pal.h>
 
 extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
 /* FIXME: where these declarations shold be there ? */
@@ -188,7 +189,8 @@ void ia64_do_page_fault(unsigned long ad
                        attr = efi_mem_attributes(address &
                                                  ~__IA64_EFI_CACHED_OFFSET);
                        if (! (attr & EFI_MEMORY_RUNTIME &&
-                              attr & EFI_MEMORY_WB) )
+                              attr & EFI_MEMORY_WB &&
+                              ia64_get_rr(7) == EFI_RID) )
                                attr = 0;
                }
                else if (address >> 59 == __IA64_EFI_UNCACHED_OFFSET >> 59) {
@@ -196,7 +198,8 @@ void ia64_do_page_fault(unsigned long ad
                                                  ~__IA64_EFI_UNCACHED_OFFSET);
                        if (! ((attr & EFI_MEMORY_RUNTIME) &&
                               (attr & (EFI_MEMORY_UC|EFI_MEMORY_WC|
-                                       EFI_MEMORY_WT))) )
+                                       EFI_MEMORY_WT)) &&
+                              ia64_get_rr(6) == EFI_RID) )
                                attr = 0;
                }
        }
Index: xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/pal.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux-xen/asm/pal.h       
2007-10-19 16:59:50.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/pal.h    2007-10-19 
17:01:19.000000000 +0900
@@ -80,6 +80,10 @@
 
 #include <linux/types.h>
 #include <asm/fpu.h>
+#ifdef XEN
+#include <asm/mmu_context.h> // For IA64_REGION_ID_EFI and ia64_rid()
+#include <asm/pgtable.h>
+#endif
 
 /*
  * Data types needed to pass information into PAL procedures and
@@ -770,6 +774,9 @@ extern struct ia64_pal_retval ia64_pal_c
 extern void ia64_save_scratch_fpregs (struct ia64_fpreg *);
 extern void ia64_load_scratch_fpregs (struct ia64_fpreg *);
 
+
+#ifndef XEN
+
 #define PAL_CALL(iprv,a0,a1,a2,a3) do {                        \
        struct ia64_fpreg fr[6];                        \
        ia64_save_scratch_fpregs(fr);                   \
@@ -805,6 +812,83 @@ extern void ia64_load_scratch_fpregs (st
        ia64_load_scratch_fpregs(fr);                           \
 } while (0)
 
+#else /* XEN */
+
+/* It doesn't really matter what the second argument to ia64_rid()
+ * is, as long as it is in the range 0-8.
+ * The page size is 2^IA64_GRANULE_SHIFT: bits 2-7 = IA64_GRANULE_SHIFT
+ * VHPT should be on: bit 1 = 1
+ */
+
+#define EFI_RID ((ia64_rid(IA64_REGION_ID_EFI, 0UL) << 8) |    \
+                (IA64_GRANULE_SHIFT << 2) | 1)
+
+#define EFI_RR_SAVE(rr6, rr7) do {                     \
+       rr6 = ia64_get_rr(6);                           \
+       rr7 = ia64_get_rr(7);                           \
+       ia64_set_rr(6, EFI_RID);                        \
+       ia64_set_rr(7, EFI_RID);                        \
+       ia64_srlz_d();                                  \
+} while (0)
+
+#define EFI_RR_RESTORE(rr6, rr7) do {                  \
+       ia64_set_rr(6, rr6);                            \
+       ia64_set_rr(7, rr7);                            \
+       ia64_srlz_d();                                  \
+} while (0)
+
+#define PAL_CALL(iprv,a0,a1,a2,a3) do {                        \
+       struct ia64_fpreg fr[6];                        \
+       unsigned long rr6, rr7;                         \
+       ia64_save_scratch_fpregs(fr);                   \
+       EFI_RR_SAVE(rr6, rr7);                          \
+       iprv = ia64_pal_call_static(a0, a1, a2, a3, 0); \
+       EFI_RR_RESTORE(rr6, rr7);                       \
+       ia64_load_scratch_fpregs(fr);                   \
+} while (0)
+
+#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) do {         \
+       struct ia64_fpreg fr[6];                        \
+       unsigned long rr6, rr7;                         \
+       ia64_save_scratch_fpregs(fr);                   \
+       EFI_RR_SAVE(rr6, rr7);                          \
+       iprv = ia64_pal_call_static(a0, a1, a2, a3, 1); \
+       EFI_RR_RESTORE(rr6, rr7);                       \
+       ia64_load_scratch_fpregs(fr);                   \
+} while (0)
+
+#define PAL_CALL_STK(iprv,a0,a1,a2,a3) do {            \
+       struct ia64_fpreg fr[6];                        \
+       unsigned long rr6, rr7;                         \
+       ia64_save_scratch_fpregs(fr);                   \
+       EFI_RR_SAVE(rr6, rr7);                          \
+       iprv = ia64_pal_call_stacked(a0, a1, a2, a3);   \
+       EFI_RR_RESTORE(rr6, rr7);                       \
+       ia64_load_scratch_fpregs(fr);                   \
+} while (0)
+
+#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) do {                   \
+       struct ia64_fpreg fr[6];                                \
+       unsigned long rr6, rr7;                                 \
+       ia64_save_scratch_fpregs(fr);                           \
+       EFI_RR_SAVE(rr6, rr7);                                  \
+       iprv = ia64_pal_call_phys_static(a0, a1, a2, a3);       \
+       EFI_RR_RESTORE(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];                                \
+       unsigned long rr6, rr7;                                 \
+       ia64_save_scratch_fpregs(fr);                           \
+       EFI_RR_SAVE(rr6, rr7);                                  \
+       iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3);      \
+       EFI_RR_RESTORE(rr6, rr7);                               \
+       ia64_load_scratch_fpregs(fr);                           \
+} while (0)
+
+#endif /* XEN */
+
 typedef int (*ia64_pal_handler) (u64, ...);
 extern ia64_pal_handler ia64_pal;
 extern void ia64_pal_handler_init (void *);
Index: xen-unstable.hg/xen/include/asm-ia64/mmu_context.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/mmu_context.h     2007-10-19 
16:59:50.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/mmu_context.h  2007-10-19 
17:01:19.000000000 +0900
@@ -3,9 +3,12 @@
 //dummy file to resolve non-arch-indep include
 #ifdef XEN
 #define IA64_REGION_ID_KERNEL 0
+#define IA64_REGION_ID_EFI    1
 #define ia64_rid(ctx,addr)     (((ctx) << 3) | (addr >> 61))
 
 #ifndef __ASSEMBLY__
+#include <asm/spinlock.h>
+
 struct ia64_ctx {
        spinlock_t lock;
        unsigned int next;      /* next context number to use */
@@ -15,5 +18,5 @@ struct ia64_ctx {
 
 extern struct ia64_ctx ia64_ctx;
 #endif /* ! __ASSEMBLY__ */
-#endif
+#endif /* ! XEN */
 #endif /* ! __ASM_MMU_CONTEXT_H */
Index: xen-unstable.hg/xen/arch/ia64/xen/ivt.S
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/ivt.S        2007-10-19 
17:01:19.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/ivt.S     2007-10-19 17:01:19.000000000 
+0900
@@ -172,6 +172,8 @@ late_alt_itlb_miss:
        rfi
 END(alt_itlb_miss)
 
+#define EFI_RID 0x861
+
        .org ia64_ivt+0x1000
 //////////////////////////////////////////////////////////////////////////
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
@@ -206,17 +208,31 @@ late_alt_dtlb_miss:
 (p8)   br.cond.sptk frametable_miss ;;
 #endif
        // If it is not a Xen address, handle it via page_fault.
+       // !( r22 == 0xf || (r22 == 0xc && rr[6] == EFI_RID) ||
+       //                  (r22 == 0xe && rr[7] == EFI_RID) ) )
        extr.u r22=r16,59,5
        ;;
        dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN   // clear the key
-       cmp.ne p8,p0=0x1e,r22           // 0xf...
-       ;;
-       cmp.ne.and p8,p0=0x18,r22       // 0xc...
-       ;;
-       cmp.ne.and p8,p0=0x1c,r22       // 0xe...
-       ;;
-(p8)   br.cond.sptk page_fault
+       cmp.eq p8,p0=0x1e,r22           // 0xf...
+       mov r23=6
+       mov r24=7
+       ;;
+       mov r23=rr[r23]
+       mov r24=rr[r24]
+(p8)   br.cond.spnt no_slow_page_fault
+       ;;
+       mov r25=EFI_RID
+       cmp.eq p8,p0=0x18,r22           // 0xc...
+       cmp.eq p9,p0=0x1c,r22           // 0xe...
+       ;;
+       cmp.eq.and p8,p0=r25,r23        // rr[6] == EFI_RID
+       cmp.eq.and p9,p0=r25,r24        // rr[7] == EFI_RID
+       ;;
+(p8)   br.cond.spnt no_slow_page_fault
+(p9)   br.cond.spnt no_slow_page_fault
+       br.cond.sptk page_fault
        ;;
+no_slow_page_fault:
        dep r21=-1,r21,IA64_PSR_ED_BIT,1
        or r19=r19,r17          // insert PTE control bits into r19
        mov cr.itir=r20         // set itir with cleared key
Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c  2007-10-19 
16:59:50.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c       2007-10-19 
17:01:19.000000000 +0900
@@ -15,6 +15,7 @@
 #include <asm/regionreg.h>
 #include <asm/vhpt.h>
 #include <asm/vcpu.h>
+#include <asm/pal.h>
 
 /* Defined in xemasm.S  */
 extern void ia64_new_rr7(unsigned long rid, void *shared_info, void 
*shared_arch_info, unsigned long shared_info_va, unsigned long va_vhpt);
Index: xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/perfmon.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux-xen/asm/perfmon.h   
2007-10-19 16:59:50.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/perfmon.h        
2007-10-19 17:01:19.000000000 +0900
@@ -8,6 +8,7 @@
 
 #ifdef XEN
 #include <asm/config.h>
+#include <linux/list.h>
 #ifndef pt_regs
 #define pt_regs cpu_user_regs
 #endif
Index: xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/system.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux-xen/asm/system.h    
2007-10-19 17:02:01.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux-xen/asm/system.h 2007-10-19 
17:02:15.000000000 +0900
@@ -16,7 +16,9 @@
 
 #include <asm/kregs.h>
 #include <asm/page.h>
+#ifndef XEN
 #include <asm/pal.h>
+#endif
 #include <asm/percpu.h>
 
 #ifndef XEN

-- 

-- 
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/


_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel