From horms@verge.net.au Sun Nov 11 20:11:34 2007
Return-Path: <horms@verge.net.au>
X-Original-To: awilliam@ldl.fc.hp.com
Delivered-To: awilliam@ldl.fc.hp.com
Received: from localhost (ldl.fc.hp.com [127.0.0.1]) by ldl.fc.hp.com
	(Postfix) with ESMTP id 115C9134005 for <awilliam@ldl.fc.hp.com>; Sun, 11
	Nov 2007 20:11:34 -0700 (MST)
X-Virus-Scanned: Debian amavisd-new at ldl.fc.hp.com
Received: from ldl.fc.hp.com ([127.0.0.1]) by localhost (ldl.fc.hp.com
	[127.0.0.1]) (amavisd-new, port 10024) with ESMTP id heUh2v2JqTGP for
	<awilliam@ldl.fc.hp.com>; Sun, 11 Nov 2007 20:11:28 -0700 (MST)
Received: from smtp1.fc.hp.com (smtp.cnd.hp.com [15.15.136.127]) by
	ldl.fc.hp.com (Postfix) with ESMTP id 6BC0F134003 for
	<awilliam@ldl.fc.hp.com>; Sun, 11 Nov 2007 20:11:28 -0700 (MST)
Received: from palrel10.hp.com (palrel10.hp.com [15.81.168.20]) by
	smtp1.fc.hp.com (Postfix) with ESMTP id 4D0631D6233 for
	<awilliam@fc.hp.com>; Mon, 12 Nov 2007 03:11:28 +0000 (UTC)
Received: from address.hp.com (address.hp.com [192.151.81.14]) (using TLSv1
	with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate
	requested) by palrel10.hp.com (Postfix) with ESMTP id 1C40935A2C for
	<awilliam@fc.hp.com>; Sun, 11 Nov 2007 19:10:29 -0800 (PST)
Received: from address.hp.com (localhost [127.0.0.1]) by
	receive-from-antispam-filter (Postfix) with SMTP id 7AD4E32F7B for
	<awilliam@fc.hp.com>; Sun, 11 Nov 2007 19:19:32 -0800 (PST)
Received: from koto.vergenet.net (koto.vergenet.net [210.128.90.7]) by
	address.hp.com (Postfix) with ESMTP id C376A32F14 for
	<alex.williamson@hp.com>; Sun, 11 Nov 2007 19:19:30 -0800 (PST)
Received: from tabatha.lab.ultramonkey.org (vagw.valinux.co.jp
	[210.128.90.14]) by koto.vergenet.net (Postfix) with ESMTP id 1231F34073;
	Mon, 12 Nov 2007 12:11:23 +0900 (JST)
Received: by tabatha.lab.ultramonkey.org (Postfix, from userid 7100) id
	3EBF84F9EB; Mon, 12 Nov 2007 12:11:22 +0900 (JST)
Date: Mon, 12 Nov 2007 12:11:22 +0900
From: Simon Horman <horms@verge.net.au>
To: xen-ia64-devel@lists.xensource.com
Cc: Isaku Yamahata <yamahata@valinux.co.jp>, Alex Williamson <alex.williamson@hp.com>
Subject: Re: [Xen-ia64-devel] [patch 2/7] IA64: Kexec: Use a separate RID
	for EFI
Message-ID: <20071112031119.GA22881@verge.net.au>
References: <20071029044857.773723054@vergenet.net>
	 <20071029045308.748767166@vergenet.net>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20071029045308.748767166@vergenet.net>
User-Agent: mutt-ng/devel-r804 (Debian)
X-PMX-Version: 5.3.1.294258, Antispam-Engine: 2.5.1.298604, Antispam-Data:
	2007.11.11.185125
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.1.3
X-Evolution-Source: imap://awilliam@localhost:9993/
Content-Transfer-Encoding: 8bit

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.

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>

---
Tue, 23 Oct 2007 15:47:27 +0900

* Don't use #ifndef XEN to denote changes to SAL, PAL and EFI macros,
  as this means that the macros have to be duplicated which leads to
  a very bulky patch. Instead, define the new functionality as
  XEN_EFI_RR_SAVE and XEN_EFI_RR_RESTORE (previously EFI_RR_SAV and
  EFI_RR_RESTOR) and put these macros straight into the existing macros -
  this should be obvious enough for future up-porters.

  As suggested by Alex Williamson.

* Break header changes out into a separate patch

* Break macro definitions out into a separate patch and
  put them in efi.h instead of pal.h. Documentation of how the
  EFI RID is selected is included in this new patch.

* Use a uniform defineition of XEN_EFI_RID in assembly and C code

Mon, 29 Oct 2007 13:43:33 +0900

* Put assembly code into a separate patch

* C code is no longer needed with the new assembly code

Mon, 12 Nov 2007 12:02:59 +0900

* Trivial upport to ia64/xen-unstable.hg 16287:b235b68a0f4f

Thu, 22 Nov 2007 00:19:38 -0700

* Make use of XEN_EFI_RR_DECLARE for consistency
  - There were instances of rr6 and rr7 that were declared as int
    instead of unsigned long which caused compiler warnings
Index: 20071119-ia64/xen/include/asm-ia64/linux/asm/sal.h
===================================================================
--- 20071119-ia64.orig/xen/include/asm-ia64/linux/asm/sal.h	2007-11-21 23:56:46.000000000 -0700
+++ 20071119-ia64/xen/include/asm-ia64/linux/asm/sal.h	2007-11-22 00:00:33.000000000 -0700
@@ -52,9 +52,12 @@
 # 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_SAVE(rr6, rr7);				\
 	__SAL_CALL(result, args);				\
+	XEN_EFI_RR_RESTORE(rr6, rr7);				\
 	spin_unlock_irqrestore(&sal_lock, __ia64_sc_flags);	\
 	ia64_load_scratch_fpregs(__ia64_sc_fr);			\
 } while (0)
@@ -62,18 +65,24 @@
 # 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_SAVE(rr6, rr7);			\
 	__SAL_CALL(result, args);			\
+	XEN_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];		\
+	XEN_EFI_RR_DECLARE(rr6, rr7);			\
 	ia64_save_scratch_fpregs(__ia64_scs_fr);	\
 	preempt_disable();				\
+	XEN_EFI_RR_SAVE(rr6, rr7);			\
 	__SAL_CALL(result, args);			\
+	XEN_EFI_RR_RESTORE(rr6, rr7);			\
 	preempt_enable();				\
 	ia64_load_scratch_fpregs(__ia64_scs_fr);	\
 } while (0)
Index: 20071119-ia64/xen/arch/ia64/linux-xen/efi.c
===================================================================
--- 20071119-ia64.orig/xen/arch/ia64/linux-xen/efi.c	2007-11-21 23:56:46.000000000 -0700
+++ 20071119-ia64/xen/arch/ia64/linux-xen/efi.c	2007-11-22 00:13:39.000000000 -0700
@@ -65,12 +65,16 @@
 	struct ia64_fpreg fr[6];								  \
 	efi_time_cap_t *atc = NULL;								  \
 	efi_status_t ret;									  \
+	unsigned long rr6, rr7;									  \
 												  \
 	if (tc)											  \
 		atc = adjust_arg(tc);								  \
 	ia64_save_scratch_fpregs(fr);								  \
+	XEN_EFI_RR_SAVE(rr6, rr7);								  \
 	ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), atc); \
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								  \
+	ia64_set_rr(7, rr7);									  \
 	return ret;										  \
 }
 
@@ -80,9 +84,12 @@
 {												\
 	struct ia64_fpreg fr[6];								\
 	efi_status_t ret;									\
+	XEN_EFI_RR_DECLARE(rr6, rr7);								  \
 												\
 	ia64_save_scratch_fpregs(fr);								\
+	XEN_EFI_RR_SAVE(rr6, rr7);								  \
 	ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm));	\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								\
 	return ret;										\
 }
@@ -93,10 +100,13 @@
 {												\
 	struct ia64_fpreg fr[6];								\
 	efi_status_t ret;									\
+	XEN_EFI_RR_DECLARE(rr6, rr7);								  \
 												\
 	ia64_save_scratch_fpregs(fr);								\
+	XEN_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));	\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								\
 	return ret;										\
 }
@@ -108,12 +118,15 @@
 	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_SAVE(rr6, rr7);								  \
 	ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time),	\
 				enabled, atm);							\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								\
 	return ret;										\
 }
@@ -126,13 +139,16 @@
 	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_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));		\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);							\
 	return ret;									\
 }
@@ -143,10 +159,13 @@
 {												\
 	struct ia64_fpreg fr[6];								\
 	efi_status_t ret;									\
+	XEN_EFI_RR_DECLARE(rr6, rr7);								  \
 												\
 	ia64_save_scratch_fpregs(fr);								\
+	XEN_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));	\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								\
 	return ret;										\
 }
@@ -158,11 +177,14 @@
 {											\
 	struct ia64_fpreg fr[6];							\
 	efi_status_t ret;								\
+	XEN_EFI_RR_DECLARE(rr6, rr7);								  \
 											\
 	ia64_save_scratch_fpregs(fr);							\
+	XEN_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));					\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);							\
 	return ret;									\
 }
@@ -173,10 +195,13 @@
 {												\
 	struct ia64_fpreg fr[6];								\
 	efi_status_t ret;									\
+	XEN_EFI_RR_DECLARE(rr6, rr7);								  \
 												\
 	ia64_save_scratch_fpregs(fr);								\
+	XEN_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));	\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);								\
 	return ret;										\
 }
@@ -188,14 +213,17 @@
 {										\
 	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_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... */				\
+	XEN_EFI_RR_RESTORE(rr6, rr7);								  \
 	ia64_load_scratch_fpregs(fr);						\
 }
 
Index: 20071119-ia64/xen/include/asm-ia64/linux-xen/asm/pal.h
===================================================================
--- 20071119-ia64.orig/xen/include/asm-ia64/linux-xen/asm/pal.h	2007-11-21 23:56:46.000000000 -0700
+++ 20071119-ia64/xen/include/asm-ia64/linux-xen/asm/pal.h	2007-11-22 00:02:15.000000000 -0700
@@ -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 @@
 
 #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_SAVE(rr6, rr7);			\
 	iprv = ia64_pal_call_static(a0, a1, a2, a3);	\
+	XEN_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];			\
+	XEN_EFI_RR_DECLARE(rr6, rr7);			\
 	ia64_save_scratch_fpregs(fr);			\
+	XEN_EFI_RR_SAVE(rr6, rr7);			\
 	iprv = ia64_pal_call_stacked(a0, a1, a2, a3);	\
+	XEN_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];				\
+	XEN_EFI_RR_DECLARE(rr6, rr7);				\
 	ia64_save_scratch_fpregs(fr);				\
+	XEN_EFI_RR_SAVE(rr6, rr7);				\
 	iprv = ia64_pal_call_phys_static(a0, a1, a2, a3);	\
+	XEN_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];				\
+	XEN_EFI_RR_DECLARE(rr6, rr7);				\
 	ia64_save_scratch_fpregs(fr);				\
+	XEN_EFI_RR_SAVE(rr6, rr7);				\
 	iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3);	\
+	XEN_EFI_RR_RESTORE(rr6, rr7);				\
 	ia64_load_scratch_fpregs(fr);				\
 } while (0)
 
