All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/9] xen: Add EFI support
@ 2014-06-20 21:29 ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Hey,

This patch series adds EFI support for Xen dom0 guests.
It is based on Jan Beulich and Tang Liang work. I was
trying to take into account all previous comments,
however, if I missed something sorry for that.

Daniel

 arch/x86/kernel/setup.c          |    4 +-
 arch/x86/platform/efi/efi.c      |  106 ++++++++++--------------
 arch/x86/xen/enlighten.c         |   24 ++++++
 drivers/firmware/efi/efi.c       |   25 +++---
 drivers/xen/Kconfig              |    4 +
 drivers/xen/Makefile             |    3 +
 drivers/xen/efi.c                |  367 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/efi.h              |    4 +-
 include/xen/interface/platform.h |  123 ++++++++++++++++++++++++++++
 9 files changed, 583 insertions(+), 77 deletions(-)

Daniel Kiper (9):
      efi: Use early_mem*() instead of early_io*()
      arch/x86: Do not access EFI memory map if it is not available
      efi: Introduce EFI_PARAVIRT flag
      arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call
      arch/x86: Remove redundant set_bit(EFI_MEMMAP) call
      xen: Define EFI related stuff
      xen: Put EFI machinery in place
      arch/x86: Replace plain strings with constants
      arch/x86: Remove efi_set_rtc_mmss()


^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 0/9] xen: Add EFI support
@ 2014-06-20 21:29 ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	jeremy-TSDbQ3PG+2Y, konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, mjg59-1xO5oi07KQx4cg9Nei1l7Q,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

Hey,

This patch series adds EFI support for Xen dom0 guests.
It is based on Jan Beulich and Tang Liang work. I was
trying to take into account all previous comments,
however, if I missed something sorry for that.

Daniel

 arch/x86/kernel/setup.c          |    4 +-
 arch/x86/platform/efi/efi.c      |  106 ++++++++++--------------
 arch/x86/xen/enlighten.c         |   24 ++++++
 drivers/firmware/efi/efi.c       |   25 +++---
 drivers/xen/Kconfig              |    4 +
 drivers/xen/Makefile             |    3 +
 drivers/xen/efi.c                |  367 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/efi.h              |    4 +-
 include/xen/interface/platform.h |  123 ++++++++++++++++++++++++++++
 9 files changed, 583 insertions(+), 77 deletions(-)

Daniel Kiper (9):
      efi: Use early_mem*() instead of early_io*()
      arch/x86: Do not access EFI memory map if it is not available
      efi: Introduce EFI_PARAVIRT flag
      arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call
      arch/x86: Remove redundant set_bit(EFI_MEMMAP) call
      xen: Define EFI related stuff
      xen: Put EFI machinery in place
      arch/x86: Replace plain strings with constants
      arch/x86: Remove efi_set_rtc_mmss()

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-20 21:29   ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Use early_mem*() instead of early_io*() because all mapped EFI regions
are memory (usually RAM but they could also be ROM, EPROM, EEPROM, flash,
etc.) not I/O regions. Additionally, I/O family calls do not work correctly
under Xen in our case. early_ioremap() skips the PFN to MFN conversion
when building the PTE. Using it for memory will attempt to map the wrong
machine frame. However, all artificial EFI structures created under Xen
live in dom0 memory and should be mapped/unmapped using early_mem*() family
calls which map domain memory.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - improve commit message
     (suggested by Matthew Garrett and Matt Fleming),
   - do not change indentation
     (suggested by Matt Fleming).
---
 arch/x86/platform/efi/efi.c |   32 ++++++++++++++++----------------
 drivers/firmware/efi/efi.c  |    4 ++--
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 87fc96b..0ee1f46 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -427,7 +427,7 @@ void __init efi_unmap_memmap(void)
 {
 	clear_bit(EFI_MEMMAP, &efi.flags);
 	if (memmap.map) {
-		early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
+		early_memunmap(memmap.map, memmap.nr_map * memmap.desc_size);
 		memmap.map = NULL;
 	}
 }
@@ -467,12 +467,12 @@ static int __init efi_systab_init(void *phys)
 			if (!data)
 				return -ENOMEM;
 		}
-		systab64 = early_ioremap((unsigned long)phys,
+		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
 			if (data)
-				early_iounmap(data, sizeof(*data));
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
@@ -504,9 +504,9 @@ static int __init efi_systab_init(void *phys)
 					   systab64->tables;
 		tmp |= data ? data->tables : systab64->tables;
 
-		early_iounmap(systab64, sizeof(*systab64));
+		early_memunmap(systab64, sizeof(*systab64));
 		if (data)
-			early_iounmap(data, sizeof(*data));
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -516,7 +516,7 @@ static int __init efi_systab_init(void *phys)
 	} else {
 		efi_system_table_32_t *systab32;
 
-		systab32 = early_ioremap((unsigned long)phys,
+		systab32 = early_memremap((unsigned long)phys,
 					 sizeof(*systab32));
 		if (systab32 == NULL) {
 			pr_err("Couldn't map the system table!\n");
@@ -537,7 +537,7 @@ static int __init efi_systab_init(void *phys)
 		efi_systab.nr_tables = systab32->nr_tables;
 		efi_systab.tables = systab32->tables;
 
-		early_iounmap(systab32, sizeof(*systab32));
+		early_memunmap(systab32, sizeof(*systab32));
 	}
 
 	efi.systab = &efi_systab;
@@ -563,7 +563,7 @@ static int __init efi_runtime_init32(void)
 {
 	efi_runtime_services_32_t *runtime;
 
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 			sizeof(efi_runtime_services_32_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -578,7 +578,7 @@ static int __init efi_runtime_init32(void)
 	efi_phys.set_virtual_address_map =
 			(efi_set_virtual_address_map_t *)
 			(unsigned long)runtime->set_virtual_address_map;
-	early_iounmap(runtime, sizeof(efi_runtime_services_32_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_32_t));
 
 	return 0;
 }
@@ -587,7 +587,7 @@ static int __init efi_runtime_init64(void)
 {
 	efi_runtime_services_64_t *runtime;
 
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 			sizeof(efi_runtime_services_64_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -602,7 +602,7 @@ static int __init efi_runtime_init64(void)
 	efi_phys.set_virtual_address_map =
 			(efi_set_virtual_address_map_t *)
 			(unsigned long)runtime->set_virtual_address_map;
-	early_iounmap(runtime, sizeof(efi_runtime_services_64_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_64_t));
 
 	return 0;
 }
@@ -633,7 +633,7 @@ static int __init efi_runtime_init(void)
 static int __init efi_memmap_init(void)
 {
 	/* Map the EFI memory map */
-	memmap.map = early_ioremap((unsigned long)memmap.phys_map,
+	memmap.map = early_memremap((unsigned long)memmap.phys_map,
 				   memmap.nr_map * memmap.desc_size);
 	if (memmap.map == NULL) {
 		pr_err("Could not map the memory map!\n");
@@ -697,10 +697,10 @@ static int __init efi_reuse_config(u64 tables, int nr_tables)
 			((efi_config_table_64_t *)p)->table = data->smbios;
 		p += sz;
 	}
-	early_iounmap(tablep, nr_tables * sz);
+	early_memunmap(tablep, nr_tables * sz);
 
 out_memremap:
-	early_iounmap(data, sizeof(*data));
+	early_memunmap(data, sizeof(*data));
 out:
 	return ret;
 }
@@ -737,14 +737,14 @@ void __init efi_init(void)
 	/*
 	 * Show what we know for posterity
 	 */
-	c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2);
+	c16 = tmp = early_memremap(efi.systab->fw_vendor, 2);
 	if (c16) {
 		for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i)
 			vendor[i] = *c16++;
 		vendor[i] = '\0';
 	} else
 		pr_err("Could not map the firmware vendor!\n");
-	early_iounmap(tmp, 2);
+	early_memunmap(tmp, 2);
 
 	pr_info("EFI v%u.%.02u by %s\n",
 		efi.systab->hdr.revision >> 16,
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index cd36deb..023937a 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
 			if (table64 >> 32) {
 				pr_cont("\n");
 				pr_err("Table located above 4GB, disabling EFI.\n");
-				early_iounmap(config_tables,
+				early_memunmap(config_tables,
 					       efi.systab->nr_tables * sz);
 				return -EINVAL;
 			}
@@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
 		tablep += sz;
 	}
 	pr_cont("\n");
-	early_iounmap(config_tables, efi.systab->nr_tables * sz);
+	early_memunmap(config_tables, efi.systab->nr_tables * sz);
 
 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Use early_mem*() instead of early_io*() because all mapped EFI regions
are memory (usually RAM but they could also be ROM, EPROM, EEPROM, flash,
etc.) not I/O regions. Additionally, I/O family calls do not work correctly
under Xen in our case. early_ioremap() skips the PFN to MFN conversion
when building the PTE. Using it for memory will attempt to map the wrong
machine frame. However, all artificial EFI structures created under Xen
live in dom0 memory and should be mapped/unmapped using early_mem*() family
calls which map domain memory.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - improve commit message
     (suggested by Matthew Garrett and Matt Fleming),
   - do not change indentation
     (suggested by Matt Fleming).
---
 arch/x86/platform/efi/efi.c |   32 ++++++++++++++++----------------
 drivers/firmware/efi/efi.c  |    4 ++--
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 87fc96b..0ee1f46 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -427,7 +427,7 @@ void __init efi_unmap_memmap(void)
 {
 	clear_bit(EFI_MEMMAP, &efi.flags);
 	if (memmap.map) {
-		early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
+		early_memunmap(memmap.map, memmap.nr_map * memmap.desc_size);
 		memmap.map = NULL;
 	}
 }
@@ -467,12 +467,12 @@ static int __init efi_systab_init(void *phys)
 			if (!data)
 				return -ENOMEM;
 		}
-		systab64 = early_ioremap((unsigned long)phys,
+		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
 			if (data)
-				early_iounmap(data, sizeof(*data));
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
@@ -504,9 +504,9 @@ static int __init efi_systab_init(void *phys)
 					   systab64->tables;
 		tmp |= data ? data->tables : systab64->tables;
 
-		early_iounmap(systab64, sizeof(*systab64));
+		early_memunmap(systab64, sizeof(*systab64));
 		if (data)
-			early_iounmap(data, sizeof(*data));
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -516,7 +516,7 @@ static int __init efi_systab_init(void *phys)
 	} else {
 		efi_system_table_32_t *systab32;
 
-		systab32 = early_ioremap((unsigned long)phys,
+		systab32 = early_memremap((unsigned long)phys,
 					 sizeof(*systab32));
 		if (systab32 == NULL) {
 			pr_err("Couldn't map the system table!\n");
@@ -537,7 +537,7 @@ static int __init efi_systab_init(void *phys)
 		efi_systab.nr_tables = systab32->nr_tables;
 		efi_systab.tables = systab32->tables;
 
-		early_iounmap(systab32, sizeof(*systab32));
+		early_memunmap(systab32, sizeof(*systab32));
 	}
 
 	efi.systab = &efi_systab;
@@ -563,7 +563,7 @@ static int __init efi_runtime_init32(void)
 {
 	efi_runtime_services_32_t *runtime;
 
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 			sizeof(efi_runtime_services_32_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -578,7 +578,7 @@ static int __init efi_runtime_init32(void)
 	efi_phys.set_virtual_address_map =
 			(efi_set_virtual_address_map_t *)
 			(unsigned long)runtime->set_virtual_address_map;
-	early_iounmap(runtime, sizeof(efi_runtime_services_32_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_32_t));
 
 	return 0;
 }
@@ -587,7 +587,7 @@ static int __init efi_runtime_init64(void)
 {
 	efi_runtime_services_64_t *runtime;
 
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 			sizeof(efi_runtime_services_64_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -602,7 +602,7 @@ static int __init efi_runtime_init64(void)
 	efi_phys.set_virtual_address_map =
 			(efi_set_virtual_address_map_t *)
 			(unsigned long)runtime->set_virtual_address_map;
-	early_iounmap(runtime, sizeof(efi_runtime_services_64_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_64_t));
 
 	return 0;
 }
@@ -633,7 +633,7 @@ static int __init efi_runtime_init(void)
 static int __init efi_memmap_init(void)
 {
 	/* Map the EFI memory map */
-	memmap.map = early_ioremap((unsigned long)memmap.phys_map,
+	memmap.map = early_memremap((unsigned long)memmap.phys_map,
 				   memmap.nr_map * memmap.desc_size);
 	if (memmap.map == NULL) {
 		pr_err("Could not map the memory map!\n");
@@ -697,10 +697,10 @@ static int __init efi_reuse_config(u64 tables, int nr_tables)
 			((efi_config_table_64_t *)p)->table = data->smbios;
 		p += sz;
 	}
-	early_iounmap(tablep, nr_tables * sz);
+	early_memunmap(tablep, nr_tables * sz);
 
 out_memremap:
-	early_iounmap(data, sizeof(*data));
+	early_memunmap(data, sizeof(*data));
 out:
 	return ret;
 }
@@ -737,14 +737,14 @@ void __init efi_init(void)
 	/*
 	 * Show what we know for posterity
 	 */
-	c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2);
+	c16 = tmp = early_memremap(efi.systab->fw_vendor, 2);
 	if (c16) {
 		for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i)
 			vendor[i] = *c16++;
 		vendor[i] = '\0';
 	} else
 		pr_err("Could not map the firmware vendor!\n");
-	early_iounmap(tmp, 2);
+	early_memunmap(tmp, 2);
 
 	pr_info("EFI v%u.%.02u by %s\n",
 		efi.systab->hdr.revision >> 16,
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index cd36deb..023937a 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
 			if (table64 >> 32) {
 				pr_cont("\n");
 				pr_err("Table located above 4GB, disabling EFI.\n");
-				early_iounmap(config_tables,
+				early_memunmap(config_tables,
 					       efi.systab->nr_tables * sz);
 				return -EINVAL;
 			}
@@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
 		tablep += sz;
 	}
 	pr_cont("\n");
-	early_iounmap(config_tables, efi.systab->nr_tables * sz);
+	early_memunmap(config_tables, efi.systab->nr_tables * sz);
 
 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
  2014-06-20 21:29 ` Daniel Kiper
  (?)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  2014-06-23  9:53     ` David Vrabel
  2014-06-23  9:53   ` David Vrabel
  -1 siblings, 2 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Do not access EFI memory map if it is not available. At least
Xen dom0 EFI implementation does not have an access to it.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - create this separate patch from main EFI_PARAVIRT patch
     (suggested by Matt Fleming).
---
 arch/x86/platform/efi/efi.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 0ee1f46..d2d3c41 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -1220,6 +1220,9 @@ u64 efi_mem_attributes(unsigned long phys_addr)
 	efi_memory_desc_t *md;
 	void *p;
 
+	if (!efi_enabled(EFI_MEMMAP))
+		return 0;
+
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
 		if ((md->phys_addr <= phys_addr) &&
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
  2014-06-20 21:29 ` Daniel Kiper
                   ` (2 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Do not access EFI memory map if it is not available. At least
Xen dom0 EFI implementation does not have an access to it.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - create this separate patch from main EFI_PARAVIRT patch
     (suggested by Matt Fleming).
---
 arch/x86/platform/efi/efi.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 0ee1f46..d2d3c41 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -1220,6 +1220,9 @@ u64 efi_mem_attributes(unsigned long phys_addr)
 	efi_memory_desc_t *md;
 	void *p;
 
+	if (!efi_enabled(EFI_MEMMAP))
+		return 0;
+
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
 		if ((md->phys_addr <= phys_addr) &&
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 3/9] efi: Introduce EFI_PARAVIRT flag
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Introduce EFI_PARAVIRT flag. If it is set then kernel runs
on EFI platform but it has not direct control on EFI stuff
like EFI runtime, tables, structures, etc. If not this means
that Linux Kernel has direct access to EFI infrastructure
and everything runs as usual.

This functionality is used in Xen dom0 because hypervisor
has full control on EFI stuff and all calls from dom0 to
EFI must be requested via special hypercall which in turn
executes relevant EFI code in behalf of dom0.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - rename EFI_NO_DIRECT to EFI_PARAVIRT
     (suggested by David Vrabel),
   - improve code comments
     (suggested by Matt Fleming).

v5 - suggestions/fixes:
   - rename EFI_DIRECT to EFI_NO_DIRECT
     (suggested by David Vrabel),
   - limit EFI_NO_DIRECT usage
     (suggested by Jan Beulich and Matt Fleming),
   - improve commit message
     (suggested by David Vrabel).
---
 arch/x86/platform/efi/efi.c |   31 +++++++++++++++++++++++++------
 drivers/firmware/efi/efi.c  |   21 ++++++++++++---------
 include/linux/efi.h         |    3 ++-
 3 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index d2d3c41..b9c23d7 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -350,6 +350,9 @@ int __init efi_memblock_x86_reserve_range(void)
 	struct efi_info *e = &boot_params.efi_info;
 	unsigned long pmap;
 
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 #ifdef CONFIG_X86_32
 	/* Can't handle data above 4GB at this time */
 	if (e->efi_memmap_hi) {
@@ -616,14 +619,24 @@ static int __init efi_runtime_init(void)
 	 * the runtime services table so that we can grab the physical
 	 * address of several of the EFI runtime functions, needed to
 	 * set the firmware into virtual mode.
+	 *
+	 * When EFI_PARAVIRT is in force then we could not map runtime
+	 * service memory region because we do not have direct access to it.
+	 * However, runtime services are available through proxy functions
+	 * (e.g. in case of Xen dom0 EFI implementation they call special
+	 * hypercall which executes relevant EFI functions) and that is why
+	 * they are always enabled.
 	 */
-	if (efi_enabled(EFI_64BIT))
-		rv = efi_runtime_init64();
-	else
-		rv = efi_runtime_init32();
 
-	if (rv)
-		return rv;
+	if (!efi_enabled(EFI_PARAVIRT)) {
+		if (efi_enabled(EFI_64BIT))
+			rv = efi_runtime_init64();
+		else
+			rv = efi_runtime_init32();
+
+		if (rv)
+			return rv;
+	}
 
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
@@ -632,6 +645,9 @@ static int __init efi_runtime_init(void)
 
 static int __init efi_memmap_init(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 	/* Map the EFI memory map */
 	memmap.map = early_memremap((unsigned long)memmap.phys_map,
 				   memmap.nr_map * memmap.desc_size);
@@ -1188,6 +1204,9 @@ static void __init __efi_enter_virtual_mode(void)
 
 void __init efi_enter_virtual_mode(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return;
+
 	if (efi_setup)
 		kexec_enter_virtual_mode();
 	else
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 023937a..ac88ec0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -104,16 +104,19 @@ static struct attribute *efi_subsys_attrs[] = {
 static umode_t efi_attr_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
-	umode_t mode = attr->mode;
-
-	if (attr == &efi_attr_fw_vendor.attr)
-		return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_runtime.attr)
-		return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_config_table.attr)
-		return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
+	if (attr == &efi_attr_fw_vendor.attr) {
+		if (efi_enabled(EFI_PARAVIRT) ||
+				efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_runtime.attr) {
+		if (efi.runtime == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_config_table.attr) {
+		if (efi.config_table == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	}
 
-	return mode;
+	return attr->mode;
 }
 
 static struct attribute_group efi_subsys_attr_group = {
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 41bbf8b..713a4f1 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -916,7 +916,8 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_RUNTIME_SERVICES	3	/* Can we use runtime services? */
 #define EFI_MEMMAP		4	/* Can we use EFI memory map? */
 #define EFI_64BIT		5	/* Is the firmware 64-bit? */
-#define EFI_ARCH_1		6	/* First arch-specific bit */
+#define EFI_PARAVIRT		6	/* Access is via a paravirt interface */
+#define EFI_ARCH_1		7	/* First arch-specific bit */
 
 #ifdef CONFIG_EFI
 /*
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 3/9] efi: Introduce EFI_PARAVIRT flag
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	jeremy-TSDbQ3PG+2Y, konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, mjg59-1xO5oi07KQx4cg9Nei1l7Q,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

Introduce EFI_PARAVIRT flag. If it is set then kernel runs
on EFI platform but it has not direct control on EFI stuff
like EFI runtime, tables, structures, etc. If not this means
that Linux Kernel has direct access to EFI infrastructure
and everything runs as usual.

This functionality is used in Xen dom0 because hypervisor
has full control on EFI stuff and all calls from dom0 to
EFI must be requested via special hypercall which in turn
executes relevant EFI code in behalf of dom0.

Signed-off-by: Daniel Kiper <daniel.kiper-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
---
v6 - suggestions/fixes:
   - rename EFI_NO_DIRECT to EFI_PARAVIRT
     (suggested by David Vrabel),
   - improve code comments
     (suggested by Matt Fleming).

v5 - suggestions/fixes:
   - rename EFI_DIRECT to EFI_NO_DIRECT
     (suggested by David Vrabel),
   - limit EFI_NO_DIRECT usage
     (suggested by Jan Beulich and Matt Fleming),
   - improve commit message
     (suggested by David Vrabel).
---
 arch/x86/platform/efi/efi.c |   31 +++++++++++++++++++++++++------
 drivers/firmware/efi/efi.c  |   21 ++++++++++++---------
 include/linux/efi.h         |    3 ++-
 3 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index d2d3c41..b9c23d7 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -350,6 +350,9 @@ int __init efi_memblock_x86_reserve_range(void)
 	struct efi_info *e = &boot_params.efi_info;
 	unsigned long pmap;
 
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 #ifdef CONFIG_X86_32
 	/* Can't handle data above 4GB at this time */
 	if (e->efi_memmap_hi) {
@@ -616,14 +619,24 @@ static int __init efi_runtime_init(void)
 	 * the runtime services table so that we can grab the physical
 	 * address of several of the EFI runtime functions, needed to
 	 * set the firmware into virtual mode.
+	 *
+	 * When EFI_PARAVIRT is in force then we could not map runtime
+	 * service memory region because we do not have direct access to it.
+	 * However, runtime services are available through proxy functions
+	 * (e.g. in case of Xen dom0 EFI implementation they call special
+	 * hypercall which executes relevant EFI functions) and that is why
+	 * they are always enabled.
 	 */
-	if (efi_enabled(EFI_64BIT))
-		rv = efi_runtime_init64();
-	else
-		rv = efi_runtime_init32();
 
-	if (rv)
-		return rv;
+	if (!efi_enabled(EFI_PARAVIRT)) {
+		if (efi_enabled(EFI_64BIT))
+			rv = efi_runtime_init64();
+		else
+			rv = efi_runtime_init32();
+
+		if (rv)
+			return rv;
+	}
 
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
@@ -632,6 +645,9 @@ static int __init efi_runtime_init(void)
 
 static int __init efi_memmap_init(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 	/* Map the EFI memory map */
 	memmap.map = early_memremap((unsigned long)memmap.phys_map,
 				   memmap.nr_map * memmap.desc_size);
@@ -1188,6 +1204,9 @@ static void __init __efi_enter_virtual_mode(void)
 
 void __init efi_enter_virtual_mode(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return;
+
 	if (efi_setup)
 		kexec_enter_virtual_mode();
 	else
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 023937a..ac88ec0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -104,16 +104,19 @@ static struct attribute *efi_subsys_attrs[] = {
 static umode_t efi_attr_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
-	umode_t mode = attr->mode;
-
-	if (attr == &efi_attr_fw_vendor.attr)
-		return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_runtime.attr)
-		return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_config_table.attr)
-		return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
+	if (attr == &efi_attr_fw_vendor.attr) {
+		if (efi_enabled(EFI_PARAVIRT) ||
+				efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_runtime.attr) {
+		if (efi.runtime == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_config_table.attr) {
+		if (efi.config_table == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	}
 
-	return mode;
+	return attr->mode;
 }
 
 static struct attribute_group efi_subsys_attr_group = {
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 41bbf8b..713a4f1 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -916,7 +916,8 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_RUNTIME_SERVICES	3	/* Can we use runtime services? */
 #define EFI_MEMMAP		4	/* Can we use EFI memory map? */
 #define EFI_64BIT		5	/* Is the firmware 64-bit? */
-#define EFI_ARCH_1		6	/* First arch-specific bit */
+#define EFI_PARAVIRT		6	/* Access is via a paravirt interface */
+#define EFI_ARCH_1		7	/* First arch-specific bit */
 
 #ifdef CONFIG_EFI
 /*
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 3/9] efi: Introduce EFI_PARAVIRT flag
  2014-06-20 21:29 ` Daniel Kiper
                   ` (3 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Introduce EFI_PARAVIRT flag. If it is set then kernel runs
on EFI platform but it has not direct control on EFI stuff
like EFI runtime, tables, structures, etc. If not this means
that Linux Kernel has direct access to EFI infrastructure
and everything runs as usual.

This functionality is used in Xen dom0 because hypervisor
has full control on EFI stuff and all calls from dom0 to
EFI must be requested via special hypercall which in turn
executes relevant EFI code in behalf of dom0.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - rename EFI_NO_DIRECT to EFI_PARAVIRT
     (suggested by David Vrabel),
   - improve code comments
     (suggested by Matt Fleming).

v5 - suggestions/fixes:
   - rename EFI_DIRECT to EFI_NO_DIRECT
     (suggested by David Vrabel),
   - limit EFI_NO_DIRECT usage
     (suggested by Jan Beulich and Matt Fleming),
   - improve commit message
     (suggested by David Vrabel).
---
 arch/x86/platform/efi/efi.c |   31 +++++++++++++++++++++++++------
 drivers/firmware/efi/efi.c  |   21 ++++++++++++---------
 include/linux/efi.h         |    3 ++-
 3 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index d2d3c41..b9c23d7 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -350,6 +350,9 @@ int __init efi_memblock_x86_reserve_range(void)
 	struct efi_info *e = &boot_params.efi_info;
 	unsigned long pmap;
 
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 #ifdef CONFIG_X86_32
 	/* Can't handle data above 4GB at this time */
 	if (e->efi_memmap_hi) {
@@ -616,14 +619,24 @@ static int __init efi_runtime_init(void)
 	 * the runtime services table so that we can grab the physical
 	 * address of several of the EFI runtime functions, needed to
 	 * set the firmware into virtual mode.
+	 *
+	 * When EFI_PARAVIRT is in force then we could not map runtime
+	 * service memory region because we do not have direct access to it.
+	 * However, runtime services are available through proxy functions
+	 * (e.g. in case of Xen dom0 EFI implementation they call special
+	 * hypercall which executes relevant EFI functions) and that is why
+	 * they are always enabled.
 	 */
-	if (efi_enabled(EFI_64BIT))
-		rv = efi_runtime_init64();
-	else
-		rv = efi_runtime_init32();
 
-	if (rv)
-		return rv;
+	if (!efi_enabled(EFI_PARAVIRT)) {
+		if (efi_enabled(EFI_64BIT))
+			rv = efi_runtime_init64();
+		else
+			rv = efi_runtime_init32();
+
+		if (rv)
+			return rv;
+	}
 
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
@@ -632,6 +645,9 @@ static int __init efi_runtime_init(void)
 
 static int __init efi_memmap_init(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return 0;
+
 	/* Map the EFI memory map */
 	memmap.map = early_memremap((unsigned long)memmap.phys_map,
 				   memmap.nr_map * memmap.desc_size);
@@ -1188,6 +1204,9 @@ static void __init __efi_enter_virtual_mode(void)
 
 void __init efi_enter_virtual_mode(void)
 {
+	if (efi_enabled(EFI_PARAVIRT))
+		return;
+
 	if (efi_setup)
 		kexec_enter_virtual_mode();
 	else
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 023937a..ac88ec0 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -104,16 +104,19 @@ static struct attribute *efi_subsys_attrs[] = {
 static umode_t efi_attr_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
-	umode_t mode = attr->mode;
-
-	if (attr == &efi_attr_fw_vendor.attr)
-		return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_runtime.attr)
-		return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
-	else if (attr == &efi_attr_config_table.attr)
-		return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
+	if (attr == &efi_attr_fw_vendor.attr) {
+		if (efi_enabled(EFI_PARAVIRT) ||
+				efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_runtime.attr) {
+		if (efi.runtime == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	} else if (attr == &efi_attr_config_table.attr) {
+		if (efi.config_table == EFI_INVALID_TABLE_ADDR)
+			return 0;
+	}
 
-	return mode;
+	return attr->mode;
 }
 
 static struct attribute_group efi_subsys_attr_group = {
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 41bbf8b..713a4f1 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -916,7 +916,8 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_RUNTIME_SERVICES	3	/* Can we use runtime services? */
 #define EFI_MEMMAP		4	/* Can we use EFI memory map? */
 #define EFI_64BIT		5	/* Is the firmware 64-bit? */
-#define EFI_ARCH_1		6	/* First arch-specific bit */
+#define EFI_PARAVIRT		6	/* Access is via a paravirt interface */
+#define EFI_ARCH_1		7	/* First arch-specific bit */
 
 #ifdef CONFIG_EFI
 /*
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 4/9] arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-20 21:29   ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Remove redundant set_bit(EFI_SYSTEM_TABLES, &efi.flags) call.
It is executed earlier in efi_systab_init().

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 arch/x86/platform/efi/efi.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b9c23d7..ae3d398 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -744,8 +744,6 @@ void __init efi_init(void)
 	if (efi_systab_init(efi_phys.systab))
 		return;
 
-	set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-
 	efi.config_table = (unsigned long)efi.systab->tables;
 	efi.fw_vendor	 = (unsigned long)efi.systab->fw_vendor;
 	efi.runtime	 = (unsigned long)efi.systab->runtime;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 4/9] arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Remove redundant set_bit(EFI_SYSTEM_TABLES, &efi.flags) call.
It is executed earlier in efi_systab_init().

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 arch/x86/platform/efi/efi.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b9c23d7..ae3d398 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -744,8 +744,6 @@ void __init efi_init(void)
 	if (efi_systab_init(efi_phys.systab))
 		return;
 
-	set_bit(EFI_SYSTEM_TABLES, &efi.flags);
-
 	efi.config_table = (unsigned long)efi.systab->tables;
 	efi.fw_vendor	 = (unsigned long)efi.systab->fw_vendor;
 	efi.runtime	 = (unsigned long)efi.systab->runtime;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 5/9] arch/x86: Remove redundant set_bit(EFI_MEMMAP) call
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-20 21:29   ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Remove redundant set_bit(EFI_MEMMAP, &efi.flags) call.
It is executed earlier in efi_memmap_init().

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 arch/x86/platform/efi/efi.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ae3d398..da15df9 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -784,8 +784,6 @@ void __init efi_init(void)
 	if (efi_memmap_init())
 		return;
 
-	set_bit(EFI_MEMMAP, &efi.flags);
-
 	print_efi_memmap();
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 5/9] arch/x86: Remove redundant set_bit(EFI_MEMMAP) call
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Remove redundant set_bit(EFI_MEMMAP, &efi.flags) call.
It is executed earlier in efi_memmap_init().

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 arch/x86/platform/efi/efi.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ae3d398..da15df9 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -784,8 +784,6 @@ void __init efi_init(void)
 	if (efi_memmap_init())
 		return;
 
-	set_bit(EFI_MEMMAP, &efi.flags);
-
 	print_efi_memmap();
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 6/9] xen: Define EFI related stuff
  2014-06-20 21:29 ` Daniel Kiper
                   ` (8 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  2014-06-23  9:50   ` David Vrabel
  2014-06-23  9:50     ` David Vrabel
  -1 siblings, 2 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

Define constants and structures which are needed to properly
execute EFI related hypercall in Xen dom0.

This patch is based on Jan Beulich and Tang Liang work.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Tang Liang <liang.tang@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - fix indentation
     (suggested by David Vrabel).

v5 - suggestions/fixes:
   - improve commit message
     (suggested by David Vrabel).

v4 - suggestions/fixes:
   - change some types from generic to Xen specific ones
     (suggested by Stefano Stabellini),
   - do some formating changes
     (suggested by Jan Beulich).
---
 include/xen/interface/platform.h |  123 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index f1331e3..5cc49ea 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -108,11 +108,113 @@ struct xenpf_platform_quirk {
 };
 DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
 
+#define XENPF_efi_runtime_call    49
+#define XEN_EFI_get_time                      1
+#define XEN_EFI_set_time                      2
+#define XEN_EFI_get_wakeup_time               3
+#define XEN_EFI_set_wakeup_time               4
+#define XEN_EFI_get_next_high_monotonic_count 5
+#define XEN_EFI_get_variable                  6
+#define XEN_EFI_set_variable                  7
+#define XEN_EFI_get_next_variable_name        8
+#define XEN_EFI_query_variable_info           9
+#define XEN_EFI_query_capsule_capabilities   10
+#define XEN_EFI_update_capsule               11
+
+struct xenpf_efi_runtime_call {
+	uint32_t function;
+	/*
+	 * This field is generally used for per sub-function flags (defined
+	 * below), except for the XEN_EFI_get_next_high_monotonic_count case,
+	 * where it holds the single returned value.
+	 */
+	uint32_t misc;
+	xen_ulong_t status;
+	union {
+#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001
+		struct {
+			struct xenpf_efi_time {
+				uint16_t year;
+				uint8_t month;
+				uint8_t day;
+				uint8_t hour;
+				uint8_t min;
+				uint8_t sec;
+				uint32_t ns;
+				int16_t tz;
+				uint8_t daylight;
+			} time;
+			uint32_t resolution;
+			uint32_t accuracy;
+		} get_time;
+
+		struct xenpf_efi_time set_time;
+
+#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001
+#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002
+		struct xenpf_efi_time get_wakeup_time;
+
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE      0x00000001
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002
+		struct xenpf_efi_time set_wakeup_time;
+
+#define XEN_EFI_VARIABLE_NON_VOLATILE       0x00000001
+#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define XEN_EFI_VARIABLE_RUNTIME_ACCESS     0x00000004
+		struct {
+			GUEST_HANDLE(void) name;  /* UCS-2/UTF-16 string */
+			xen_ulong_t size;
+			GUEST_HANDLE(void) data;
+			struct xenpf_efi_guid {
+				uint32_t data1;
+				uint16_t data2;
+				uint16_t data3;
+				uint8_t data4[8];
+			} vendor_guid;
+		} get_variable, set_variable;
+
+		struct {
+			xen_ulong_t size;
+			GUEST_HANDLE(void) name;  /* UCS-2/UTF-16 string */
+			struct xenpf_efi_guid vendor_guid;
+		} get_next_variable_name;
+
+		struct {
+			uint32_t attr;
+			uint64_t max_store_size;
+			uint64_t remain_store_size;
+			uint64_t max_size;
+		} query_variable_info;
+
+		struct {
+			GUEST_HANDLE(void) capsule_header_array;
+			xen_ulong_t capsule_count;
+			uint64_t max_capsule_size;
+			uint32_t reset_type;
+		} query_capsule_capabilities;
+
+		struct {
+			GUEST_HANDLE(void) capsule_header_array;
+			xen_ulong_t capsule_count;
+			uint64_t sg_list; /* machine address */
+		} update_capsule;
+	} u;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_efi_runtime_call);
+
+#define  XEN_FW_EFI_VERSION        0
+#define  XEN_FW_EFI_CONFIG_TABLE   1
+#define  XEN_FW_EFI_VENDOR         2
+#define  XEN_FW_EFI_MEM_INFO       3
+#define  XEN_FW_EFI_RT_VERSION     4
+
 #define XENPF_firmware_info       50
 #define XEN_FW_DISK_INFO          1 /* from int 13 AH=08/41/48 */
 #define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
 #define XEN_FW_VBEDDC_INFO        3 /* from int 10 AX=4f15 */
+#define XEN_FW_EFI_INFO           4 /* from EFI */
 #define XEN_FW_KBD_SHIFT_FLAGS    5 /* Int16, Fn02: Get keyboard shift flags. */
+
 struct xenpf_firmware_info {
 	/* IN variables. */
 	uint32_t type;
@@ -144,6 +246,26 @@ struct xenpf_firmware_info {
 			GUEST_HANDLE(uchar) edid;
 		} vbeddc_info; /* XEN_FW_VBEDDC_INFO */
 
+		union xenpf_efi_info {
+			uint32_t version;
+			struct {
+				uint64_t addr;   /* EFI_CONFIGURATION_TABLE */
+				uint32_t nent;
+			} cfg;
+			struct {
+				uint32_t revision;
+				uint32_t bufsz;  /* input, in bytes */
+				GUEST_HANDLE(void) name;
+				/* UCS-2/UTF-16 string */
+			} vendor;
+			struct {
+				uint64_t addr;
+				uint64_t size;
+				uint64_t attr;
+				uint32_t type;
+			} mem;
+		} efi_info; /* XEN_FW_EFI_INFO */
+
 		uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
 	} u;
 };
@@ -362,6 +484,7 @@ struct xen_platform_op {
 		struct xenpf_read_memtype      read_memtype;
 		struct xenpf_microcode_update  microcode;
 		struct xenpf_platform_quirk    platform_quirk;
+		struct xenpf_efi_runtime_call  efi_runtime_call;
 		struct xenpf_firmware_info     firmware_info;
 		struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
 		struct xenpf_change_freq       change_freq;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 6/9] xen: Define EFI related stuff
  2014-06-20 21:29 ` Daniel Kiper
                   ` (7 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

Define constants and structures which are needed to properly
execute EFI related hypercall in Xen dom0.

This patch is based on Jan Beulich and Tang Liang work.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Tang Liang <liang.tang@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - fix indentation
     (suggested by David Vrabel).

v5 - suggestions/fixes:
   - improve commit message
     (suggested by David Vrabel).

v4 - suggestions/fixes:
   - change some types from generic to Xen specific ones
     (suggested by Stefano Stabellini),
   - do some formating changes
     (suggested by Jan Beulich).
---
 include/xen/interface/platform.h |  123 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index f1331e3..5cc49ea 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -108,11 +108,113 @@ struct xenpf_platform_quirk {
 };
 DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
 
+#define XENPF_efi_runtime_call    49
+#define XEN_EFI_get_time                      1
+#define XEN_EFI_set_time                      2
+#define XEN_EFI_get_wakeup_time               3
+#define XEN_EFI_set_wakeup_time               4
+#define XEN_EFI_get_next_high_monotonic_count 5
+#define XEN_EFI_get_variable                  6
+#define XEN_EFI_set_variable                  7
+#define XEN_EFI_get_next_variable_name        8
+#define XEN_EFI_query_variable_info           9
+#define XEN_EFI_query_capsule_capabilities   10
+#define XEN_EFI_update_capsule               11
+
+struct xenpf_efi_runtime_call {
+	uint32_t function;
+	/*
+	 * This field is generally used for per sub-function flags (defined
+	 * below), except for the XEN_EFI_get_next_high_monotonic_count case,
+	 * where it holds the single returned value.
+	 */
+	uint32_t misc;
+	xen_ulong_t status;
+	union {
+#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001
+		struct {
+			struct xenpf_efi_time {
+				uint16_t year;
+				uint8_t month;
+				uint8_t day;
+				uint8_t hour;
+				uint8_t min;
+				uint8_t sec;
+				uint32_t ns;
+				int16_t tz;
+				uint8_t daylight;
+			} time;
+			uint32_t resolution;
+			uint32_t accuracy;
+		} get_time;
+
+		struct xenpf_efi_time set_time;
+
+#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001
+#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002
+		struct xenpf_efi_time get_wakeup_time;
+
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE      0x00000001
+#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002
+		struct xenpf_efi_time set_wakeup_time;
+
+#define XEN_EFI_VARIABLE_NON_VOLATILE       0x00000001
+#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define XEN_EFI_VARIABLE_RUNTIME_ACCESS     0x00000004
+		struct {
+			GUEST_HANDLE(void) name;  /* UCS-2/UTF-16 string */
+			xen_ulong_t size;
+			GUEST_HANDLE(void) data;
+			struct xenpf_efi_guid {
+				uint32_t data1;
+				uint16_t data2;
+				uint16_t data3;
+				uint8_t data4[8];
+			} vendor_guid;
+		} get_variable, set_variable;
+
+		struct {
+			xen_ulong_t size;
+			GUEST_HANDLE(void) name;  /* UCS-2/UTF-16 string */
+			struct xenpf_efi_guid vendor_guid;
+		} get_next_variable_name;
+
+		struct {
+			uint32_t attr;
+			uint64_t max_store_size;
+			uint64_t remain_store_size;
+			uint64_t max_size;
+		} query_variable_info;
+
+		struct {
+			GUEST_HANDLE(void) capsule_header_array;
+			xen_ulong_t capsule_count;
+			uint64_t max_capsule_size;
+			uint32_t reset_type;
+		} query_capsule_capabilities;
+
+		struct {
+			GUEST_HANDLE(void) capsule_header_array;
+			xen_ulong_t capsule_count;
+			uint64_t sg_list; /* machine address */
+		} update_capsule;
+	} u;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_efi_runtime_call);
+
+#define  XEN_FW_EFI_VERSION        0
+#define  XEN_FW_EFI_CONFIG_TABLE   1
+#define  XEN_FW_EFI_VENDOR         2
+#define  XEN_FW_EFI_MEM_INFO       3
+#define  XEN_FW_EFI_RT_VERSION     4
+
 #define XENPF_firmware_info       50
 #define XEN_FW_DISK_INFO          1 /* from int 13 AH=08/41/48 */
 #define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
 #define XEN_FW_VBEDDC_INFO        3 /* from int 10 AX=4f15 */
+#define XEN_FW_EFI_INFO           4 /* from EFI */
 #define XEN_FW_KBD_SHIFT_FLAGS    5 /* Int16, Fn02: Get keyboard shift flags. */
+
 struct xenpf_firmware_info {
 	/* IN variables. */
 	uint32_t type;
@@ -144,6 +246,26 @@ struct xenpf_firmware_info {
 			GUEST_HANDLE(uchar) edid;
 		} vbeddc_info; /* XEN_FW_VBEDDC_INFO */
 
+		union xenpf_efi_info {
+			uint32_t version;
+			struct {
+				uint64_t addr;   /* EFI_CONFIGURATION_TABLE */
+				uint32_t nent;
+			} cfg;
+			struct {
+				uint32_t revision;
+				uint32_t bufsz;  /* input, in bytes */
+				GUEST_HANDLE(void) name;
+				/* UCS-2/UTF-16 string */
+			} vendor;
+			struct {
+				uint64_t addr;
+				uint64_t size;
+				uint64_t attr;
+				uint32_t type;
+			} mem;
+		} efi_info; /* XEN_FW_EFI_INFO */
+
 		uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
 	} u;
 };
@@ -362,6 +484,7 @@ struct xen_platform_op {
 		struct xenpf_read_memtype      read_memtype;
 		struct xenpf_microcode_update  microcode;
 		struct xenpf_platform_quirk    platform_quirk;
+		struct xenpf_efi_runtime_call  efi_runtime_call;
 		struct xenpf_firmware_info     firmware_info;
 		struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
 		struct xenpf_change_freq       change_freq;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 7/9] xen: Put EFI machinery in place
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-20 21:29   ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

This patch enables EFI usage under Xen dom0. Standard EFI Linux
Kernel infrastructure cannot be used because it requires direct
access to EFI data and code. However, in dom0 case it is not possible
because above mentioned EFI stuff is fully owned and controlled
by Xen hypervisor. In this case all calls from dom0 to EFI must
be requested via special hypercall which in turn executes relevant
EFI code in behalf of dom0.

When dom0 kernel boots it checks for EFI availability on a machine.
If it is detected then artificial EFI system table is filled.
Native EFI callas are replaced by functions which mimics them
by calling relevant hypercall. Later pointer to EFI system table
is passed to standard EFI machinery and it continues EFI subsystem
initialization taking into account that there is no direct access
to EFI boot services, runtime, tables, structures, etc. After that
system runs as usual.

This patch is based on Jan Beulich and Tang Liang work.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Tang Liang <liang.tang@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - remove unneeded BUG() call
     (suggested by Stefano Stabellini).

v5 - suggestions/fixes:
   - improve macro usage readability
     (suggested by Andrew Cooper and David Vrabel),
   - conditions cleanup
     (suggested by David Vrabel),
   - use -fshort-wchar option
     (suggested by Jan Beulich),
   - Kconfig rule cleanup
     (suggested by Jan Beulich),
   - forward port fixes from SUSE kernel
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by David Vrabel).

v4 - suggestions/fixes:
   - "just populate an efi_system_table_t object"
     (suggested by Matt Fleming).
---
 arch/x86/xen/enlighten.c |   24 +++
 drivers/xen/Kconfig      |    4 +
 drivers/xen/Makefile     |    3 +
 drivers/xen/efi.c        |  367 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 398 insertions(+)
 create mode 100644 drivers/xen/efi.c

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ffb101e..04611ea 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -32,6 +32,7 @@
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/edd.h>
+#include <linux/efi.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
@@ -150,6 +151,15 @@ struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
  */
 static int have_vcpu_info_placement = 1;
 
+#ifdef CONFIG_XEN_EFI
+extern efi_system_table_t __init *xen_efi_probe(void);
+#else
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+	return NULL;
+}
+#endif
+
 struct tls_descs {
 	struct desc_struct desc[3];
 };
@@ -1520,6 +1530,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 {
 	struct physdev_set_iopl set_iopl;
 	int rc;
+	efi_system_table_t *efi_systab_xen;
 
 	if (!xen_start_info)
 		return;
@@ -1718,6 +1729,19 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
 	xen_setup_runstate_info(0);
 
+	efi_systab_xen = xen_efi_probe();
+
+	if (efi_systab_xen) {
+		strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen",
+				sizeof(boot_params.efi_info.efi_loader_signature));
+		boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
+		boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
+
+		set_bit(EFI_BOOT, &efi.flags);
+		set_bit(EFI_PARAVIRT, &efi.flags);
+		set_bit(EFI_64BIT, &efi.flags);
+	}
+
 	/* Start the world */
 #ifdef CONFIG_X86_32
 	i386_start_kernel();
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 38fb36e..8bc0183 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -240,4 +240,8 @@ config XEN_MCE_LOG
 config XEN_HAVE_PVMMU
        bool
 
+config XEN_EFI
+	def_bool y
+	depends on X86_64 && EFI
+
 endmenu
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 45e00af..84044b5 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -9,6 +9,8 @@ obj-y	+= xenbus/
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_features.o			:= $(nostackp)
 
+CFLAGS_efi.o				+= -fshort-wchar
+
 dom0-$(CONFIG_PCI) += pci.o
 dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
 dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
@@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB)			+= xen-stub.o
 obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)	+= xen-acpi-memhotplug.o
 obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU)	+= xen-acpi-cpuhotplug.o
 obj-$(CONFIG_XEN_ACPI_PROCESSOR)	+= xen-acpi-processor.o
+obj-$(CONFIG_XEN_EFI)			+= efi.o
 xen-evtchn-y				:= evtchn.o
 xen-gntdev-y				:= gntdev.o
 xen-gntalloc-y				:= gntalloc.o
diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
new file mode 100644
index 0000000..d8d55a5
--- /dev/null
+++ b/drivers/xen/efi.c
@@ -0,0 +1,367 @@
+/*
+ * EFI support for Xen.
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2005-2008 Intel Co.
+ *	Fenghua Yu <fenghua.yu@intel.com>
+ *	Bibo Mao <bibo.mao@intel.com>
+ *	Chandramouli Narayanan <mouli@linux.intel.com>
+ *	Huang Ying <ying.huang@intel.com>
+ * Copyright (C) 2011 Novell Co.
+ *	Jan Beulich <JBeulich@suse.com>
+ * Copyright (C) 2011-2012 Oracle Co.
+ *	Liang Tang <liang.tang@oracle.com>
+ * Copyright (c) 2014 Oracle Co., Daniel Kiper
+ */
+
+#include <linux/bug.h>
+#include <linux/efi.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <xen/interface/xen.h>
+#include <xen/interface/platform.h>
+
+#include <asm/xen/hypercall.h>
+
+#define INIT_EFI_OP(name) \
+	{.cmd = XENPF_efi_runtime_call, \
+	 .u.efi_runtime_call.function = XEN_EFI_##name, \
+	 .u.efi_runtime_call.misc = 0}
+
+#define efi_data(op)	(op.u.efi_runtime_call)
+
+static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_time);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	if (tm) {
+		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_time.time));
+		memcpy(tm, &efi_data(op).u.get_time.time, sizeof(*tm));
+	}
+
+	if (tc) {
+		tc->resolution = efi_data(op).u.get_time.resolution;
+		tc->accuracy = efi_data(op).u.get_time.accuracy;
+		tc->sets_to_zero = !!(efi_data(op).misc &
+				      XEN_EFI_GET_TIME_SET_CLEARS_NS);
+	}
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_time(efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_time);
+
+	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time));
+	memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm));
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
+					    efi_bool_t *pending,
+					    efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	if (tm) {
+		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_wakeup_time));
+		memcpy(tm, &efi_data(op).u.get_wakeup_time, sizeof(*tm));
+	}
+
+	if (enabled)
+		*enabled = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED);
+
+	if (pending)
+		*pending = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_PENDING);
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
+
+	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_wakeup_time));
+	if (enabled)
+		efi_data(op).misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE;
+	if (tm)
+		memcpy(&efi_data(op).u.set_wakeup_time, tm, sizeof(*tm));
+	else
+		efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_variable(efi_char16_t *name,
+					 efi_guid_t *vendor,
+					 u32 *attr,
+					 unsigned long *data_size,
+					 void *data)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_variable);
+
+	set_xen_guest_handle(efi_data(op).u.get_variable.name, name);
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.get_variable.vendor_guid));
+	memcpy(&efi_data(op).u.get_variable.vendor_guid, vendor, sizeof(*vendor));
+	efi_data(op).u.get_variable.size = *data_size;
+	set_xen_guest_handle(efi_data(op).u.get_variable.data, data);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*data_size = efi_data(op).u.get_variable.size;
+	if (attr)
+		*attr = efi_data(op).misc;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+					      efi_char16_t *name,
+					      efi_guid_t *vendor)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
+
+	efi_data(op).u.get_next_variable_name.size = *name_size;
+	set_xen_guest_handle(efi_data(op).u.get_next_variable_name.name, name);
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.get_next_variable_name.vendor_guid));
+	memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor,
+	       sizeof(*vendor));
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*name_size = efi_data(op).u.get_next_variable_name.size;
+	memcpy(vendor, &efi_data(op).u.get_next_variable_name.vendor_guid,
+	       sizeof(*vendor));
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_variable(efi_char16_t *name,
+					 efi_guid_t *vendor,
+					 u32 attr,
+					 unsigned long data_size,
+					 void *data)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_variable);
+
+	set_xen_guest_handle(efi_data(op).u.set_variable.name, name);
+	efi_data(op).misc = attr;
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.set_variable.vendor_guid));
+	memcpy(&efi_data(op).u.set_variable.vendor_guid, vendor, sizeof(*vendor));
+	efi_data(op).u.set_variable.size = data_size;
+	set_xen_guest_handle(efi_data(op).u.set_variable.data, data);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_query_variable_info(u32 attr,
+						u64 *storage_space,
+						u64 *remaining_space,
+						u64 *max_variable_size)
+{
+	struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	efi_data(op).u.query_variable_info.attr = attr;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*storage_space = efi_data(op).u.query_variable_info.max_store_size;
+	*remaining_space = efi_data(op).u.query_variable_info.remain_store_size;
+	*max_variable_size = efi_data(op).u.query_variable_info.max_size;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*count = efi_data(op).misc;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+					   unsigned long count,
+					   unsigned long sg_list)
+{
+	struct xen_platform_op op = INIT_EFI_OP(update_capsule);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	set_xen_guest_handle(efi_data(op).u.update_capsule.capsule_header_array,
+			     capsules);
+	efi_data(op).u.update_capsule.capsule_count = count;
+	efi_data(op).u.update_capsule.sg_list = sg_list;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+					       unsigned long count,
+					       u64 *max_size,
+					       int *reset_type)
+{
+	struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	set_xen_guest_handle(efi_data(op).u.query_capsule_capabilities.capsule_header_array,
+					capsules);
+	efi_data(op).u.query_capsule_capabilities.capsule_count = count;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size;
+	*reset_type = efi_data(op).u.query_capsule_capabilities.reset_type;
+
+	return efi_data(op).status;
+}
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+	.hdr = {
+		.signature	= EFI_SYSTEM_TABLE_SIGNATURE,
+		.revision	= 0, /* Initialized later. */
+		.headersize	= 0, /* Ignored by Linux Kernel. */
+		.crc32		= 0, /* Ignored by Linux Kernel. */
+		.reserved	= 0
+	},
+	.fw_vendor	= EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+	.fw_revision	= 0,			  /* Initialized later. */
+	.con_in_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_in		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_out_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_out	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.stderr_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.stderr		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.runtime	= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+						  /* Not used under Xen. */
+	.boottime	= (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+						  /* Not used under Xen. */
+	.nr_tables	= 0,			  /* Initialized later. */
+	.tables		= EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+	.systab                   = NULL, /* Initialized later. */
+	.runtime_version	  = 0,    /* Initialized later. */
+	.mps                      = EFI_INVALID_TABLE_ADDR,
+	.acpi                     = EFI_INVALID_TABLE_ADDR,
+	.acpi20                   = EFI_INVALID_TABLE_ADDR,
+	.smbios                   = EFI_INVALID_TABLE_ADDR,
+	.sal_systab               = EFI_INVALID_TABLE_ADDR,
+	.boot_info                = EFI_INVALID_TABLE_ADDR,
+	.hcdp                     = EFI_INVALID_TABLE_ADDR,
+	.uga                      = EFI_INVALID_TABLE_ADDR,
+	.uv_systab                = EFI_INVALID_TABLE_ADDR,
+	.fw_vendor                = EFI_INVALID_TABLE_ADDR,
+	.runtime                  = EFI_INVALID_TABLE_ADDR,
+	.config_table             = EFI_INVALID_TABLE_ADDR,
+	.get_time                 = xen_efi_get_time,
+	.set_time                 = xen_efi_set_time,
+	.get_wakeup_time          = xen_efi_get_wakeup_time,
+	.set_wakeup_time          = xen_efi_set_wakeup_time,
+	.get_variable             = xen_efi_get_variable,
+	.get_next_variable        = xen_efi_get_next_variable,
+	.set_variable             = xen_efi_set_variable,
+	.query_variable_info      = xen_efi_query_variable_info,
+	.update_capsule           = xen_efi_update_capsule,
+	.query_capsule_caps       = xen_efi_query_capsule_caps,
+	.get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+	.reset_system             = NULL, /* Functionality provided by Xen. */
+	.set_virtual_address_map  = NULL, /* Not used under Xen. */
+	.memmap                   = NULL, /* Not used under Xen. */
+	.flags			  = 0     /* Initialized later. */
+};
+
+efi_system_table_t __init *xen_efi_probe(void)
+{
+	struct xen_platform_op op = {
+		.cmd = XENPF_firmware_info,
+		.u.firmware_info = {
+			.type = XEN_FW_EFI_INFO,
+			.index = XEN_FW_EFI_CONFIG_TABLE
+		}
+	};
+	union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
+
+	if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0)
+		return NULL;
+
+	/* Here we know that Xen runs on EFI platform. */
+
+	efi = efi_xen;
+
+	efi_systab_xen.tables = info->cfg.addr;
+	efi_systab_xen.nr_tables = info->cfg.nent;
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
+	info->vendor.bufsz = sizeof(vendor);
+	set_xen_guest_handle(info->vendor.name, vendor);
+
+	if (HYPERVISOR_dom0_op(&op) == 0) {
+		efi_systab_xen.fw_vendor = __pa_symbol(vendor);
+		efi_systab_xen.fw_revision = info->vendor.revision;
+	} else
+		efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_VERSION;
+
+	if (HYPERVISOR_dom0_op(&op) == 0)
+		efi_systab_xen.hdr.revision = info->version;
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
+
+	if (HYPERVISOR_dom0_op(&op) == 0)
+		efi.runtime_version = info->version;
+
+	return &efi_systab_xen;
+}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

This patch enables EFI usage under Xen dom0. Standard EFI Linux
Kernel infrastructure cannot be used because it requires direct
access to EFI data and code. However, in dom0 case it is not possible
because above mentioned EFI stuff is fully owned and controlled
by Xen hypervisor. In this case all calls from dom0 to EFI must
be requested via special hypercall which in turn executes relevant
EFI code in behalf of dom0.

When dom0 kernel boots it checks for EFI availability on a machine.
If it is detected then artificial EFI system table is filled.
Native EFI callas are replaced by functions which mimics them
by calling relevant hypercall. Later pointer to EFI system table
is passed to standard EFI machinery and it continues EFI subsystem
initialization taking into account that there is no direct access
to EFI boot services, runtime, tables, structures, etc. After that
system runs as usual.

This patch is based on Jan Beulich and Tang Liang work.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Tang Liang <liang.tang@oracle.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - remove unneeded BUG() call
     (suggested by Stefano Stabellini).

v5 - suggestions/fixes:
   - improve macro usage readability
     (suggested by Andrew Cooper and David Vrabel),
   - conditions cleanup
     (suggested by David Vrabel),
   - use -fshort-wchar option
     (suggested by Jan Beulich),
   - Kconfig rule cleanup
     (suggested by Jan Beulich),
   - forward port fixes from SUSE kernel
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by David Vrabel).

v4 - suggestions/fixes:
   - "just populate an efi_system_table_t object"
     (suggested by Matt Fleming).
---
 arch/x86/xen/enlighten.c |   24 +++
 drivers/xen/Kconfig      |    4 +
 drivers/xen/Makefile     |    3 +
 drivers/xen/efi.c        |  367 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 398 insertions(+)
 create mode 100644 drivers/xen/efi.c

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ffb101e..04611ea 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -32,6 +32,7 @@
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/edd.h>
+#include <linux/efi.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
@@ -150,6 +151,15 @@ struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
  */
 static int have_vcpu_info_placement = 1;
 
+#ifdef CONFIG_XEN_EFI
+extern efi_system_table_t __init *xen_efi_probe(void);
+#else
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+	return NULL;
+}
+#endif
+
 struct tls_descs {
 	struct desc_struct desc[3];
 };
@@ -1520,6 +1530,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 {
 	struct physdev_set_iopl set_iopl;
 	int rc;
+	efi_system_table_t *efi_systab_xen;
 
 	if (!xen_start_info)
 		return;
@@ -1718,6 +1729,19 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
 	xen_setup_runstate_info(0);
 
+	efi_systab_xen = xen_efi_probe();
+
+	if (efi_systab_xen) {
+		strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen",
+				sizeof(boot_params.efi_info.efi_loader_signature));
+		boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
+		boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
+
+		set_bit(EFI_BOOT, &efi.flags);
+		set_bit(EFI_PARAVIRT, &efi.flags);
+		set_bit(EFI_64BIT, &efi.flags);
+	}
+
 	/* Start the world */
 #ifdef CONFIG_X86_32
 	i386_start_kernel();
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 38fb36e..8bc0183 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -240,4 +240,8 @@ config XEN_MCE_LOG
 config XEN_HAVE_PVMMU
        bool
 
+config XEN_EFI
+	def_bool y
+	depends on X86_64 && EFI
+
 endmenu
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 45e00af..84044b5 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -9,6 +9,8 @@ obj-y	+= xenbus/
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_features.o			:= $(nostackp)
 
+CFLAGS_efi.o				+= -fshort-wchar
+
 dom0-$(CONFIG_PCI) += pci.o
 dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
 dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
@@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB)			+= xen-stub.o
 obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)	+= xen-acpi-memhotplug.o
 obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU)	+= xen-acpi-cpuhotplug.o
 obj-$(CONFIG_XEN_ACPI_PROCESSOR)	+= xen-acpi-processor.o
+obj-$(CONFIG_XEN_EFI)			+= efi.o
 xen-evtchn-y				:= evtchn.o
 xen-gntdev-y				:= gntdev.o
 xen-gntalloc-y				:= gntalloc.o
diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
new file mode 100644
index 0000000..d8d55a5
--- /dev/null
+++ b/drivers/xen/efi.c
@@ -0,0 +1,367 @@
+/*
+ * EFI support for Xen.
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2005-2008 Intel Co.
+ *	Fenghua Yu <fenghua.yu@intel.com>
+ *	Bibo Mao <bibo.mao@intel.com>
+ *	Chandramouli Narayanan <mouli@linux.intel.com>
+ *	Huang Ying <ying.huang@intel.com>
+ * Copyright (C) 2011 Novell Co.
+ *	Jan Beulich <JBeulich@suse.com>
+ * Copyright (C) 2011-2012 Oracle Co.
+ *	Liang Tang <liang.tang@oracle.com>
+ * Copyright (c) 2014 Oracle Co., Daniel Kiper
+ */
+
+#include <linux/bug.h>
+#include <linux/efi.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <xen/interface/xen.h>
+#include <xen/interface/platform.h>
+
+#include <asm/xen/hypercall.h>
+
+#define INIT_EFI_OP(name) \
+	{.cmd = XENPF_efi_runtime_call, \
+	 .u.efi_runtime_call.function = XEN_EFI_##name, \
+	 .u.efi_runtime_call.misc = 0}
+
+#define efi_data(op)	(op.u.efi_runtime_call)
+
+static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_time);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	if (tm) {
+		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_time.time));
+		memcpy(tm, &efi_data(op).u.get_time.time, sizeof(*tm));
+	}
+
+	if (tc) {
+		tc->resolution = efi_data(op).u.get_time.resolution;
+		tc->accuracy = efi_data(op).u.get_time.accuracy;
+		tc->sets_to_zero = !!(efi_data(op).misc &
+				      XEN_EFI_GET_TIME_SET_CLEARS_NS);
+	}
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_time(efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_time);
+
+	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time));
+	memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm));
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
+					    efi_bool_t *pending,
+					    efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	if (tm) {
+		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_wakeup_time));
+		memcpy(tm, &efi_data(op).u.get_wakeup_time, sizeof(*tm));
+	}
+
+	if (enabled)
+		*enabled = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED);
+
+	if (pending)
+		*pending = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_PENDING);
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
+
+	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_wakeup_time));
+	if (enabled)
+		efi_data(op).misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE;
+	if (tm)
+		memcpy(&efi_data(op).u.set_wakeup_time, tm, sizeof(*tm));
+	else
+		efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_variable(efi_char16_t *name,
+					 efi_guid_t *vendor,
+					 u32 *attr,
+					 unsigned long *data_size,
+					 void *data)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_variable);
+
+	set_xen_guest_handle(efi_data(op).u.get_variable.name, name);
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.get_variable.vendor_guid));
+	memcpy(&efi_data(op).u.get_variable.vendor_guid, vendor, sizeof(*vendor));
+	efi_data(op).u.get_variable.size = *data_size;
+	set_xen_guest_handle(efi_data(op).u.get_variable.data, data);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*data_size = efi_data(op).u.get_variable.size;
+	if (attr)
+		*attr = efi_data(op).misc;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+					      efi_char16_t *name,
+					      efi_guid_t *vendor)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
+
+	efi_data(op).u.get_next_variable_name.size = *name_size;
+	set_xen_guest_handle(efi_data(op).u.get_next_variable_name.name, name);
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.get_next_variable_name.vendor_guid));
+	memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor,
+	       sizeof(*vendor));
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*name_size = efi_data(op).u.get_next_variable_name.size;
+	memcpy(vendor, &efi_data(op).u.get_next_variable_name.vendor_guid,
+	       sizeof(*vendor));
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_set_variable(efi_char16_t *name,
+					 efi_guid_t *vendor,
+					 u32 attr,
+					 unsigned long data_size,
+					 void *data)
+{
+	struct xen_platform_op op = INIT_EFI_OP(set_variable);
+
+	set_xen_guest_handle(efi_data(op).u.set_variable.name, name);
+	efi_data(op).misc = attr;
+	BUILD_BUG_ON(sizeof(*vendor) !=
+		     sizeof(efi_data(op).u.set_variable.vendor_guid));
+	memcpy(&efi_data(op).u.set_variable.vendor_guid, vendor, sizeof(*vendor));
+	efi_data(op).u.set_variable.size = data_size;
+	set_xen_guest_handle(efi_data(op).u.set_variable.data, data);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_query_variable_info(u32 attr,
+						u64 *storage_space,
+						u64 *remaining_space,
+						u64 *max_variable_size)
+{
+	struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	efi_data(op).u.query_variable_info.attr = attr;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*storage_space = efi_data(op).u.query_variable_info.max_store_size;
+	*remaining_space = efi_data(op).u.query_variable_info.remain_store_size;
+	*max_variable_size = efi_data(op).u.query_variable_info.max_size;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
+{
+	struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*count = efi_data(op).misc;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+					   unsigned long count,
+					   unsigned long sg_list)
+{
+	struct xen_platform_op op = INIT_EFI_OP(update_capsule);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	set_xen_guest_handle(efi_data(op).u.update_capsule.capsule_header_array,
+			     capsules);
+	efi_data(op).u.update_capsule.capsule_count = count;
+	efi_data(op).u.update_capsule.sg_list = sg_list;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	return efi_data(op).status;
+}
+
+static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+					       unsigned long count,
+					       u64 *max_size,
+					       int *reset_type)
+{
+	struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
+
+	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+		return EFI_UNSUPPORTED;
+
+	set_xen_guest_handle(efi_data(op).u.query_capsule_capabilities.capsule_header_array,
+					capsules);
+	efi_data(op).u.query_capsule_capabilities.capsule_count = count;
+
+	if (HYPERVISOR_dom0_op(&op) < 0)
+		return EFI_UNSUPPORTED;
+
+	*max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size;
+	*reset_type = efi_data(op).u.query_capsule_capabilities.reset_type;
+
+	return efi_data(op).status;
+}
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+	.hdr = {
+		.signature	= EFI_SYSTEM_TABLE_SIGNATURE,
+		.revision	= 0, /* Initialized later. */
+		.headersize	= 0, /* Ignored by Linux Kernel. */
+		.crc32		= 0, /* Ignored by Linux Kernel. */
+		.reserved	= 0
+	},
+	.fw_vendor	= EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+	.fw_revision	= 0,			  /* Initialized later. */
+	.con_in_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_in		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_out_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.con_out	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.stderr_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.stderr		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+	.runtime	= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+						  /* Not used under Xen. */
+	.boottime	= (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+						  /* Not used under Xen. */
+	.nr_tables	= 0,			  /* Initialized later. */
+	.tables		= EFI_INVALID_TABLE_ADDR  /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+	.systab                   = NULL, /* Initialized later. */
+	.runtime_version	  = 0,    /* Initialized later. */
+	.mps                      = EFI_INVALID_TABLE_ADDR,
+	.acpi                     = EFI_INVALID_TABLE_ADDR,
+	.acpi20                   = EFI_INVALID_TABLE_ADDR,
+	.smbios                   = EFI_INVALID_TABLE_ADDR,
+	.sal_systab               = EFI_INVALID_TABLE_ADDR,
+	.boot_info                = EFI_INVALID_TABLE_ADDR,
+	.hcdp                     = EFI_INVALID_TABLE_ADDR,
+	.uga                      = EFI_INVALID_TABLE_ADDR,
+	.uv_systab                = EFI_INVALID_TABLE_ADDR,
+	.fw_vendor                = EFI_INVALID_TABLE_ADDR,
+	.runtime                  = EFI_INVALID_TABLE_ADDR,
+	.config_table             = EFI_INVALID_TABLE_ADDR,
+	.get_time                 = xen_efi_get_time,
+	.set_time                 = xen_efi_set_time,
+	.get_wakeup_time          = xen_efi_get_wakeup_time,
+	.set_wakeup_time          = xen_efi_set_wakeup_time,
+	.get_variable             = xen_efi_get_variable,
+	.get_next_variable        = xen_efi_get_next_variable,
+	.set_variable             = xen_efi_set_variable,
+	.query_variable_info      = xen_efi_query_variable_info,
+	.update_capsule           = xen_efi_update_capsule,
+	.query_capsule_caps       = xen_efi_query_capsule_caps,
+	.get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+	.reset_system             = NULL, /* Functionality provided by Xen. */
+	.set_virtual_address_map  = NULL, /* Not used under Xen. */
+	.memmap                   = NULL, /* Not used under Xen. */
+	.flags			  = 0     /* Initialized later. */
+};
+
+efi_system_table_t __init *xen_efi_probe(void)
+{
+	struct xen_platform_op op = {
+		.cmd = XENPF_firmware_info,
+		.u.firmware_info = {
+			.type = XEN_FW_EFI_INFO,
+			.index = XEN_FW_EFI_CONFIG_TABLE
+		}
+	};
+	union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
+
+	if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0)
+		return NULL;
+
+	/* Here we know that Xen runs on EFI platform. */
+
+	efi = efi_xen;
+
+	efi_systab_xen.tables = info->cfg.addr;
+	efi_systab_xen.nr_tables = info->cfg.nent;
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
+	info->vendor.bufsz = sizeof(vendor);
+	set_xen_guest_handle(info->vendor.name, vendor);
+
+	if (HYPERVISOR_dom0_op(&op) == 0) {
+		efi_systab_xen.fw_vendor = __pa_symbol(vendor);
+		efi_systab_xen.fw_revision = info->vendor.revision;
+	} else
+		efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_VERSION;
+
+	if (HYPERVISOR_dom0_op(&op) == 0)
+		efi_systab_xen.hdr.revision = info->version;
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.type = XEN_FW_EFI_INFO;
+	op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
+
+	if (HYPERVISOR_dom0_op(&op) == 0)
+		efi.runtime_version = info->version;
+
+	return &efi_systab_xen;
+}
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 8/9] arch/x86: Replace plain strings with constants
  2014-06-20 21:29 ` Daniel Kiper
                   ` (10 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

We've got constants, so let's use them instead of hard-coded values.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - improve commit message
     (suggested by Matt Fleming).
---
 arch/x86/kernel/setup.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 78a0e62..41ead8d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -924,10 +924,10 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #ifdef CONFIG_EFI
 	if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-		     "EL32", 4)) {
+		     EFI32_LOADER_SIGNATURE, 4)) {
 		set_bit(EFI_BOOT, &efi.flags);
 	} else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-		     "EL64", 4)) {
+		     EFI64_LOADER_SIGNATURE, 4)) {
 		set_bit(EFI_BOOT, &efi.flags);
 		set_bit(EFI_64BIT, &efi.flags);
 	}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 8/9] arch/x86: Replace plain strings with constants
  2014-06-20 21:29 ` Daniel Kiper
                   ` (11 preceding siblings ...)
  (?)
@ 2014-06-20 21:29 ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

We've got constants, so let's use them instead of hard-coded values.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - improve commit message
     (suggested by Matt Fleming).
---
 arch/x86/kernel/setup.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 78a0e62..41ead8d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -924,10 +924,10 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #ifdef CONFIG_EFI
 	if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-		     "EL32", 4)) {
+		     EFI32_LOADER_SIGNATURE, 4)) {
 		set_bit(EFI_BOOT, &efi.flags);
 	} else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
-		     "EL64", 4)) {
+		     EFI64_LOADER_SIGNATURE, 4)) {
 		set_bit(EFI_BOOT, &efi.flags);
 		set_bit(EFI_64BIT, &efi.flags);
 	}
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 9/9] arch/x86: Remove efi_set_rtc_mmss()
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-20 21:29   ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, david.vrabel, eshelton, hpa,
	ian.campbell, jbeulich, jeremy, konrad.wilk, matt.fleming, mingo,
	mjg59, stefano.stabellini, tglx

efi_set_rtc_mmss() is never used to set RTC due to bugs found
on many EFI platforms. It is set directly by mach_set_rtc_mmss().
Hence, remove unused efi_set_rtc_mmss() function.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - remove efi_set_rtc_mmss() instead of commenting out it
     (suggested by Stefano Stabellini, Juergen Gross,
     H. Peter Anvin and Matt Fleming).
---
 arch/x86/platform/efi/efi.c |   36 ------------------------------------
 include/linux/efi.h         |    1 -
 2 files changed, 37 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index da15df9..d569eea 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -244,42 +244,6 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
 	return status;
 }
 
-int efi_set_rtc_mmss(const struct timespec *now)
-{
-	unsigned long nowtime = now->tv_sec;
-	efi_status_t	status;
-	efi_time_t	eft;
-	efi_time_cap_t	cap;
-	struct rtc_time	tm;
-
-	status = efi.get_time(&eft, &cap);
-	if (status != EFI_SUCCESS) {
-		pr_err("Oops: efitime: can't read time!\n");
-		return -1;
-	}
-
-	rtc_time_to_tm(nowtime, &tm);
-	if (!rtc_valid_tm(&tm)) {
-		eft.year = tm.tm_year + 1900;
-		eft.month = tm.tm_mon + 1;
-		eft.day = tm.tm_mday;
-		eft.minute = tm.tm_min;
-		eft.second = tm.tm_sec;
-		eft.nanosecond = 0;
-	} else {
-		pr_err("%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n",
-		       __func__, nowtime);
-		return -1;
-	}
-
-	status = efi.set_time(&eft);
-	if (status != EFI_SUCCESS) {
-		pr_err("Oops: efitime: can't write time!\n");
-		return -1;
-	}
-	return 0;
-}
-
 void efi_get_time(struct timespec *now)
 {
 	efi_status_t status;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 713a4f1..322366b 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -870,7 +870,6 @@ extern int __init efi_uart_console_only (void);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
-extern int efi_set_rtc_mmss(const struct timespec *now);
 extern void efi_reserve_boot_services(void);
 extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
 extern struct efi_memory_map memmap;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH v6 9/9] arch/x86: Remove efi_set_rtc_mmss()
@ 2014-06-20 21:29   ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-20 21:29 UTC (permalink / raw)
  To: linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

efi_set_rtc_mmss() is never used to set RTC due to bugs found
on many EFI platforms. It is set directly by mach_set_rtc_mmss().
Hence, remove unused efi_set_rtc_mmss() function.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v6 - suggestions/fixes:
   - remove efi_set_rtc_mmss() instead of commenting out it
     (suggested by Stefano Stabellini, Juergen Gross,
     H. Peter Anvin and Matt Fleming).
---
 arch/x86/platform/efi/efi.c |   36 ------------------------------------
 include/linux/efi.h         |    1 -
 2 files changed, 37 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index da15df9..d569eea 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -244,42 +244,6 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
 	return status;
 }
 
-int efi_set_rtc_mmss(const struct timespec *now)
-{
-	unsigned long nowtime = now->tv_sec;
-	efi_status_t	status;
-	efi_time_t	eft;
-	efi_time_cap_t	cap;
-	struct rtc_time	tm;
-
-	status = efi.get_time(&eft, &cap);
-	if (status != EFI_SUCCESS) {
-		pr_err("Oops: efitime: can't read time!\n");
-		return -1;
-	}
-
-	rtc_time_to_tm(nowtime, &tm);
-	if (!rtc_valid_tm(&tm)) {
-		eft.year = tm.tm_year + 1900;
-		eft.month = tm.tm_mon + 1;
-		eft.day = tm.tm_mday;
-		eft.minute = tm.tm_min;
-		eft.second = tm.tm_sec;
-		eft.nanosecond = 0;
-	} else {
-		pr_err("%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n",
-		       __func__, nowtime);
-		return -1;
-	}
-
-	status = efi.set_time(&eft);
-	if (status != EFI_SUCCESS) {
-		pr_err("Oops: efitime: can't write time!\n");
-		return -1;
-	}
-	return 0;
-}
-
 void efi_get_time(struct timespec *now)
 {
 	efi_status_t status;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 713a4f1..322366b 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -870,7 +870,6 @@ extern int __init efi_uart_console_only (void);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
-extern int efi_set_rtc_mmss(const struct timespec *now);
 extern void efi_reserve_boot_services(void);
 extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
 extern struct efi_memory_map memmap;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-21 14:53     ` Stefano Stabellini
  0 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2014-06-21 14:53 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: linux-efi, linux-kernel, x86, xen-devel, andrew.cooper3,
	boris.ostrovsky, david.vrabel, eshelton, hpa, ian.campbell,
	jbeulich, jeremy, konrad.wilk, matt.fleming, mingo, mjg59,
	stefano.stabellini, tglx

On Fri, 20 Jun 2014, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.
> 
> This patch is based on Jan Beulich and Tang Liang work.
> 
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Tang Liang <liang.tang@oracle.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v6 - suggestions/fixes:
>    - remove unneeded BUG() call
>      (suggested by Stefano Stabellini).
> 
> v5 - suggestions/fixes:
>    - improve macro usage readability
>      (suggested by Andrew Cooper and David Vrabel),
>    - conditions cleanup
>      (suggested by David Vrabel),
>    - use -fshort-wchar option
>      (suggested by Jan Beulich),
>    - Kconfig rule cleanup
>      (suggested by Jan Beulich),
>    - forward port fixes from SUSE kernel
>      (suggested by Jan Beulich),
>    - improve commit message
>      (suggested by David Vrabel).
> 
> v4 - suggestions/fixes:
>    - "just populate an efi_system_table_t object"
>      (suggested by Matt Fleming).
> ---
>  arch/x86/xen/enlighten.c |   24 +++
>  drivers/xen/Kconfig      |    4 +
>  drivers/xen/Makefile     |    3 +
>  drivers/xen/efi.c        |  367 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 398 insertions(+)
>  create mode 100644 drivers/xen/efi.c
> 
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index ffb101e..04611ea 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -32,6 +32,7 @@
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
>  #include <linux/edd.h>
> +#include <linux/efi.h>
>  
>  #include <xen/xen.h>
>  #include <xen/events.h>
> @@ -150,6 +151,15 @@ struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
>   */
>  static int have_vcpu_info_placement = 1;
>  
> +#ifdef CONFIG_XEN_EFI
> +extern efi_system_table_t __init *xen_efi_probe(void);
> +#else
> +static efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	return NULL;
> +}
> +#endif

I should have spotted this before, but it would be better to move this
chunk to an header file under include/xen.



>  struct tls_descs {
>  	struct desc_struct desc[3];
>  };
> @@ -1520,6 +1530,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  {
>  	struct physdev_set_iopl set_iopl;
>  	int rc;
> +	efi_system_table_t *efi_systab_xen;
>  
>  	if (!xen_start_info)
>  		return;
> @@ -1718,6 +1729,19 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  
>  	xen_setup_runstate_info(0);
>  
> +	efi_systab_xen = xen_efi_probe();
> +
> +	if (efi_systab_xen) {
> +		strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen",
> +				sizeof(boot_params.efi_info.efi_loader_signature));
> +		boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
> +		boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
> +
> +		set_bit(EFI_BOOT, &efi.flags);
> +		set_bit(EFI_PARAVIRT, &efi.flags);
> +		set_bit(EFI_64BIT, &efi.flags);
> +	}
> +
>  	/* Start the world */
>  #ifdef CONFIG_X86_32
>  	i386_start_kernel();
> diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
> index 38fb36e..8bc0183 100644
> --- a/drivers/xen/Kconfig
> +++ b/drivers/xen/Kconfig
> @@ -240,4 +240,8 @@ config XEN_MCE_LOG
>  config XEN_HAVE_PVMMU
>         bool
>  
> +config XEN_EFI
> +	def_bool y
> +	depends on X86_64 && EFI
> +
>  endmenu
> diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
> index 45e00af..84044b5 100644
> --- a/drivers/xen/Makefile
> +++ b/drivers/xen/Makefile
> @@ -9,6 +9,8 @@ obj-y	+= xenbus/
>  nostackp := $(call cc-option, -fno-stack-protector)
>  CFLAGS_features.o			:= $(nostackp)
>  
> +CFLAGS_efi.o				+= -fshort-wchar
> +
>  dom0-$(CONFIG_PCI) += pci.o
>  dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
>  dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
> @@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB)			+= xen-stub.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)	+= xen-acpi-memhotplug.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU)	+= xen-acpi-cpuhotplug.o
>  obj-$(CONFIG_XEN_ACPI_PROCESSOR)	+= xen-acpi-processor.o
> +obj-$(CONFIG_XEN_EFI)			+= efi.o
>  xen-evtchn-y				:= evtchn.o
>  xen-gntdev-y				:= gntdev.o
>  xen-gntalloc-y				:= gntalloc.o
> diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
> new file mode 100644
> index 0000000..d8d55a5
> --- /dev/null
> +++ b/drivers/xen/efi.c
> @@ -0,0 +1,367 @@
> +/*
> + * EFI support for Xen.
> + *
> + * Copyright (C) 1999 VA Linux Systems
> + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
> + * Copyright (C) 1999-2002 Hewlett-Packard Co.
> + *	David Mosberger-Tang <davidm@hpl.hp.com>
> + *	Stephane Eranian <eranian@hpl.hp.com>
> + * Copyright (C) 2005-2008 Intel Co.
> + *	Fenghua Yu <fenghua.yu@intel.com>
> + *	Bibo Mao <bibo.mao@intel.com>
> + *	Chandramouli Narayanan <mouli@linux.intel.com>
> + *	Huang Ying <ying.huang@intel.com>
> + * Copyright (C) 2011 Novell Co.
> + *	Jan Beulich <JBeulich@suse.com>
> + * Copyright (C) 2011-2012 Oracle Co.
> + *	Liang Tang <liang.tang@oracle.com>
> + * Copyright (c) 2014 Oracle Co., Daniel Kiper
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/efi.h>
> +#include <linux/init.h>
> +#include <linux/string.h>
> +
> +#include <xen/interface/xen.h>
> +#include <xen/interface/platform.h>
> +
> +#include <asm/xen/hypercall.h>
> +
> +#define INIT_EFI_OP(name) \
> +	{.cmd = XENPF_efi_runtime_call, \
> +	 .u.efi_runtime_call.function = XEN_EFI_##name, \
> +	 .u.efi_runtime_call.misc = 0}
> +
> +#define efi_data(op)	(op.u.efi_runtime_call)
> +
> +static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_time.time));
> +		memcpy(tm, &efi_data(op).u.get_time.time, sizeof(*tm));
> +	}
> +
> +	if (tc) {
> +		tc->resolution = efi_data(op).u.get_time.resolution;
> +		tc->accuracy = efi_data(op).u.get_time.accuracy;
> +		tc->sets_to_zero = !!(efi_data(op).misc &
> +				      XEN_EFI_GET_TIME_SET_CLEARS_NS);
> +	}
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_time(efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time));
> +	memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
> +					    efi_bool_t *pending,
> +					    efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_wakeup_time));
> +		memcpy(tm, &efi_data(op).u.get_wakeup_time, sizeof(*tm));
> +	}
> +
> +	if (enabled)
> +		*enabled = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED);
> +
> +	if (pending)
> +		*pending = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_PENDING);
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_wakeup_time));
> +	if (enabled)
> +		efi_data(op).misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE;
> +	if (tm)
> +		memcpy(&efi_data(op).u.set_wakeup_time, tm, sizeof(*tm));
> +	else
> +		efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 *attr,
> +					 unsigned long *data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.get_variable.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.get_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.get_variable.size = *data_size;
> +	set_xen_guest_handle(efi_data(op).u.get_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*data_size = efi_data(op).u.get_variable.size;
> +	if (attr)
> +		*attr = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
> +					      efi_char16_t *name,
> +					      efi_guid_t *vendor)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
> +
> +	efi_data(op).u.get_next_variable_name.size = *name_size;
> +	set_xen_guest_handle(efi_data(op).u.get_next_variable_name.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_next_variable_name.vendor_guid));
> +	memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor,
> +	       sizeof(*vendor));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*name_size = efi_data(op).u.get_next_variable_name.size;
> +	memcpy(vendor, &efi_data(op).u.get_next_variable_name.vendor_guid,
> +	       sizeof(*vendor));
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 attr,
> +					 unsigned long data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.set_variable.name, name);
> +	efi_data(op).misc = attr;
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.set_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.set_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.set_variable.size = data_size;
> +	set_xen_guest_handle(efi_data(op).u.set_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_variable_info(u32 attr,
> +						u64 *storage_space,
> +						u64 *remaining_space,
> +						u64 *max_variable_size)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	efi_data(op).u.query_variable_info.attr = attr;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*storage_space = efi_data(op).u.query_variable_info.max_store_size;
> +	*remaining_space = efi_data(op).u.query_variable_info.remain_store_size;
> +	*max_variable_size = efi_data(op).u.query_variable_info.max_size;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*count = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
> +					   unsigned long count,
> +					   unsigned long sg_list)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(update_capsule);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.update_capsule.capsule_header_array,
> +			     capsules);
> +	efi_data(op).u.update_capsule.capsule_count = count;
> +	efi_data(op).u.update_capsule.sg_list = sg_list;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
> +					       unsigned long count,
> +					       u64 *max_size,
> +					       int *reset_type)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.query_capsule_capabilities.capsule_header_array,
> +					capsules);
> +	efi_data(op).u.query_capsule_capabilities.capsule_count = count;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size;
> +	*reset_type = efi_data(op).u.query_capsule_capabilities.reset_type;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_char16_t vendor[100] __initdata;
> +
> +static efi_system_table_t efi_systab_xen __initdata = {
> +	.hdr = {
> +		.signature	= EFI_SYSTEM_TABLE_SIGNATURE,
> +		.revision	= 0, /* Initialized later. */
> +		.headersize	= 0, /* Ignored by Linux Kernel. */
> +		.crc32		= 0, /* Ignored by Linux Kernel. */
> +		.reserved	= 0
> +	},
> +	.fw_vendor	= EFI_INVALID_TABLE_ADDR, /* Initialized later. */
> +	.fw_revision	= 0,			  /* Initialized later. */
> +	.con_in_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_in		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.runtime	= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.boottime	= (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.nr_tables	= 0,			  /* Initialized later. */
> +	.tables		= EFI_INVALID_TABLE_ADDR  /* Initialized later. */
> +};
> +
> +static const struct efi efi_xen __initconst = {
> +	.systab                   = NULL, /* Initialized later. */
> +	.runtime_version	  = 0,    /* Initialized later. */
> +	.mps                      = EFI_INVALID_TABLE_ADDR,
> +	.acpi                     = EFI_INVALID_TABLE_ADDR,
> +	.acpi20                   = EFI_INVALID_TABLE_ADDR,
> +	.smbios                   = EFI_INVALID_TABLE_ADDR,
> +	.sal_systab               = EFI_INVALID_TABLE_ADDR,
> +	.boot_info                = EFI_INVALID_TABLE_ADDR,
> +	.hcdp                     = EFI_INVALID_TABLE_ADDR,
> +	.uga                      = EFI_INVALID_TABLE_ADDR,
> +	.uv_systab                = EFI_INVALID_TABLE_ADDR,
> +	.fw_vendor                = EFI_INVALID_TABLE_ADDR,
> +	.runtime                  = EFI_INVALID_TABLE_ADDR,
> +	.config_table             = EFI_INVALID_TABLE_ADDR,
> +	.get_time                 = xen_efi_get_time,
> +	.set_time                 = xen_efi_set_time,
> +	.get_wakeup_time          = xen_efi_get_wakeup_time,
> +	.set_wakeup_time          = xen_efi_set_wakeup_time,
> +	.get_variable             = xen_efi_get_variable,
> +	.get_next_variable        = xen_efi_get_next_variable,
> +	.set_variable             = xen_efi_set_variable,
> +	.query_variable_info      = xen_efi_query_variable_info,
> +	.update_capsule           = xen_efi_update_capsule,
> +	.query_capsule_caps       = xen_efi_query_capsule_caps,
> +	.get_next_high_mono_count = xen_efi_get_next_high_mono_count,
> +	.reset_system             = NULL, /* Functionality provided by Xen. */
> +	.set_virtual_address_map  = NULL, /* Not used under Xen. */
> +	.memmap                   = NULL, /* Not used under Xen. */
> +	.flags			  = 0     /* Initialized later. */
> +};
> +
> +efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	struct xen_platform_op op = {
> +		.cmd = XENPF_firmware_info,
> +		.u.firmware_info = {
> +			.type = XEN_FW_EFI_INFO,
> +			.index = XEN_FW_EFI_CONFIG_TABLE
> +		}
> +	};
> +	union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
> +
> +	if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0)
> +		return NULL;
> +
> +	/* Here we know that Xen runs on EFI platform. */
> +
> +	efi = efi_xen;
> +
> +	efi_systab_xen.tables = info->cfg.addr;
> +	efi_systab_xen.nr_tables = info->cfg.nent;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
> +	info->vendor.bufsz = sizeof(vendor);
> +	set_xen_guest_handle(info->vendor.name, vendor);
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0) {
> +		efi_systab_xen.fw_vendor = __pa_symbol(vendor);
> +		efi_systab_xen.fw_revision = info->vendor.revision;
> +	} else
> +		efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi_systab_xen.hdr.revision = info->version;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi.runtime_version = info->version;
> +
> +	return &efi_systab_xen;
> +}
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-21 14:53     ` Stefano Stabellini
  0 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2014-06-21 14:53 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	jeremy-TSDbQ3PG+2Y, konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, mjg59-1xO5oi07KQx4cg9Nei1l7Q,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

On Fri, 20 Jun 2014, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.
> 
> This patch is based on Jan Beulich and Tang Liang work.
> 
> Signed-off-by: Jan Beulich <jbeulich-IBi9RG/b67k@public.gmane.org>
> Signed-off-by: Tang Liang <liang.tang-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Daniel Kiper <daniel.kiper-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> ---
> v6 - suggestions/fixes:
>    - remove unneeded BUG() call
>      (suggested by Stefano Stabellini).
> 
> v5 - suggestions/fixes:
>    - improve macro usage readability
>      (suggested by Andrew Cooper and David Vrabel),
>    - conditions cleanup
>      (suggested by David Vrabel),
>    - use -fshort-wchar option
>      (suggested by Jan Beulich),
>    - Kconfig rule cleanup
>      (suggested by Jan Beulich),
>    - forward port fixes from SUSE kernel
>      (suggested by Jan Beulich),
>    - improve commit message
>      (suggested by David Vrabel).
> 
> v4 - suggestions/fixes:
>    - "just populate an efi_system_table_t object"
>      (suggested by Matt Fleming).
> ---
>  arch/x86/xen/enlighten.c |   24 +++
>  drivers/xen/Kconfig      |    4 +
>  drivers/xen/Makefile     |    3 +
>  drivers/xen/efi.c        |  367 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 398 insertions(+)
>  create mode 100644 drivers/xen/efi.c
> 
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index ffb101e..04611ea 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -32,6 +32,7 @@
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
>  #include <linux/edd.h>
> +#include <linux/efi.h>
>  
>  #include <xen/xen.h>
>  #include <xen/events.h>
> @@ -150,6 +151,15 @@ struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
>   */
>  static int have_vcpu_info_placement = 1;
>  
> +#ifdef CONFIG_XEN_EFI
> +extern efi_system_table_t __init *xen_efi_probe(void);
> +#else
> +static efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	return NULL;
> +}
> +#endif

I should have spotted this before, but it would be better to move this
chunk to an header file under include/xen.



>  struct tls_descs {
>  	struct desc_struct desc[3];
>  };
> @@ -1520,6 +1530,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  {
>  	struct physdev_set_iopl set_iopl;
>  	int rc;
> +	efi_system_table_t *efi_systab_xen;
>  
>  	if (!xen_start_info)
>  		return;
> @@ -1718,6 +1729,19 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  
>  	xen_setup_runstate_info(0);
>  
> +	efi_systab_xen = xen_efi_probe();
> +
> +	if (efi_systab_xen) {
> +		strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen",
> +				sizeof(boot_params.efi_info.efi_loader_signature));
> +		boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
> +		boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
> +
> +		set_bit(EFI_BOOT, &efi.flags);
> +		set_bit(EFI_PARAVIRT, &efi.flags);
> +		set_bit(EFI_64BIT, &efi.flags);
> +	}
> +
>  	/* Start the world */
>  #ifdef CONFIG_X86_32
>  	i386_start_kernel();
> diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
> index 38fb36e..8bc0183 100644
> --- a/drivers/xen/Kconfig
> +++ b/drivers/xen/Kconfig
> @@ -240,4 +240,8 @@ config XEN_MCE_LOG
>  config XEN_HAVE_PVMMU
>         bool
>  
> +config XEN_EFI
> +	def_bool y
> +	depends on X86_64 && EFI
> +
>  endmenu
> diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
> index 45e00af..84044b5 100644
> --- a/drivers/xen/Makefile
> +++ b/drivers/xen/Makefile
> @@ -9,6 +9,8 @@ obj-y	+= xenbus/
>  nostackp := $(call cc-option, -fno-stack-protector)
>  CFLAGS_features.o			:= $(nostackp)
>  
> +CFLAGS_efi.o				+= -fshort-wchar
> +
>  dom0-$(CONFIG_PCI) += pci.o
>  dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
>  dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
> @@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB)			+= xen-stub.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)	+= xen-acpi-memhotplug.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU)	+= xen-acpi-cpuhotplug.o
>  obj-$(CONFIG_XEN_ACPI_PROCESSOR)	+= xen-acpi-processor.o
> +obj-$(CONFIG_XEN_EFI)			+= efi.o
>  xen-evtchn-y				:= evtchn.o
>  xen-gntdev-y				:= gntdev.o
>  xen-gntalloc-y				:= gntalloc.o
> diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
> new file mode 100644
> index 0000000..d8d55a5
> --- /dev/null
> +++ b/drivers/xen/efi.c
> @@ -0,0 +1,367 @@
> +/*
> + * EFI support for Xen.
> + *
> + * Copyright (C) 1999 VA Linux Systems
> + * Copyright (C) 1999 Walt Drummond <drummond-jCdQPDEk3idBDgjK7y7TUQ@public.gmane.org>
> + * Copyright (C) 1999-2002 Hewlett-Packard Co.
> + *	David Mosberger-Tang <davidm-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org>
> + *	Stephane Eranian <eranian-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org>
> + * Copyright (C) 2005-2008 Intel Co.
> + *	Fenghua Yu <fenghua.yu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> + *	Bibo Mao <bibo.mao-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> + *	Chandramouli Narayanan <mouli-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> + *	Huang Ying <ying.huang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> + * Copyright (C) 2011 Novell Co.
> + *	Jan Beulich <JBeulich-IBi9RG/b67k@public.gmane.org>
> + * Copyright (C) 2011-2012 Oracle Co.
> + *	Liang Tang <liang.tang-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> + * Copyright (c) 2014 Oracle Co., Daniel Kiper
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/efi.h>
> +#include <linux/init.h>
> +#include <linux/string.h>
> +
> +#include <xen/interface/xen.h>
> +#include <xen/interface/platform.h>
> +
> +#include <asm/xen/hypercall.h>
> +
> +#define INIT_EFI_OP(name) \
> +	{.cmd = XENPF_efi_runtime_call, \
> +	 .u.efi_runtime_call.function = XEN_EFI_##name, \
> +	 .u.efi_runtime_call.misc = 0}
> +
> +#define efi_data(op)	(op.u.efi_runtime_call)
> +
> +static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_time.time));
> +		memcpy(tm, &efi_data(op).u.get_time.time, sizeof(*tm));
> +	}
> +
> +	if (tc) {
> +		tc->resolution = efi_data(op).u.get_time.resolution;
> +		tc->accuracy = efi_data(op).u.get_time.accuracy;
> +		tc->sets_to_zero = !!(efi_data(op).misc &
> +				      XEN_EFI_GET_TIME_SET_CLEARS_NS);
> +	}
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_time(efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time));
> +	memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
> +					    efi_bool_t *pending,
> +					    efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_wakeup_time));
> +		memcpy(tm, &efi_data(op).u.get_wakeup_time, sizeof(*tm));
> +	}
> +
> +	if (enabled)
> +		*enabled = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED);
> +
> +	if (pending)
> +		*pending = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_PENDING);
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_wakeup_time));
> +	if (enabled)
> +		efi_data(op).misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE;
> +	if (tm)
> +		memcpy(&efi_data(op).u.set_wakeup_time, tm, sizeof(*tm));
> +	else
> +		efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 *attr,
> +					 unsigned long *data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.get_variable.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.get_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.get_variable.size = *data_size;
> +	set_xen_guest_handle(efi_data(op).u.get_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*data_size = efi_data(op).u.get_variable.size;
> +	if (attr)
> +		*attr = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
> +					      efi_char16_t *name,
> +					      efi_guid_t *vendor)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
> +
> +	efi_data(op).u.get_next_variable_name.size = *name_size;
> +	set_xen_guest_handle(efi_data(op).u.get_next_variable_name.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_next_variable_name.vendor_guid));
> +	memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor,
> +	       sizeof(*vendor));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*name_size = efi_data(op).u.get_next_variable_name.size;
> +	memcpy(vendor, &efi_data(op).u.get_next_variable_name.vendor_guid,
> +	       sizeof(*vendor));
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 attr,
> +					 unsigned long data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.set_variable.name, name);
> +	efi_data(op).misc = attr;
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.set_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.set_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.set_variable.size = data_size;
> +	set_xen_guest_handle(efi_data(op).u.set_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_variable_info(u32 attr,
> +						u64 *storage_space,
> +						u64 *remaining_space,
> +						u64 *max_variable_size)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	efi_data(op).u.query_variable_info.attr = attr;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*storage_space = efi_data(op).u.query_variable_info.max_store_size;
> +	*remaining_space = efi_data(op).u.query_variable_info.remain_store_size;
> +	*max_variable_size = efi_data(op).u.query_variable_info.max_size;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*count = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
> +					   unsigned long count,
> +					   unsigned long sg_list)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(update_capsule);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.update_capsule.capsule_header_array,
> +			     capsules);
> +	efi_data(op).u.update_capsule.capsule_count = count;
> +	efi_data(op).u.update_capsule.sg_list = sg_list;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
> +					       unsigned long count,
> +					       u64 *max_size,
> +					       int *reset_type)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.query_capsule_capabilities.capsule_header_array,
> +					capsules);
> +	efi_data(op).u.query_capsule_capabilities.capsule_count = count;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size;
> +	*reset_type = efi_data(op).u.query_capsule_capabilities.reset_type;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_char16_t vendor[100] __initdata;
> +
> +static efi_system_table_t efi_systab_xen __initdata = {
> +	.hdr = {
> +		.signature	= EFI_SYSTEM_TABLE_SIGNATURE,
> +		.revision	= 0, /* Initialized later. */
> +		.headersize	= 0, /* Ignored by Linux Kernel. */
> +		.crc32		= 0, /* Ignored by Linux Kernel. */
> +		.reserved	= 0
> +	},
> +	.fw_vendor	= EFI_INVALID_TABLE_ADDR, /* Initialized later. */
> +	.fw_revision	= 0,			  /* Initialized later. */
> +	.con_in_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_in		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.runtime	= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.boottime	= (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.nr_tables	= 0,			  /* Initialized later. */
> +	.tables		= EFI_INVALID_TABLE_ADDR  /* Initialized later. */
> +};
> +
> +static const struct efi efi_xen __initconst = {
> +	.systab                   = NULL, /* Initialized later. */
> +	.runtime_version	  = 0,    /* Initialized later. */
> +	.mps                      = EFI_INVALID_TABLE_ADDR,
> +	.acpi                     = EFI_INVALID_TABLE_ADDR,
> +	.acpi20                   = EFI_INVALID_TABLE_ADDR,
> +	.smbios                   = EFI_INVALID_TABLE_ADDR,
> +	.sal_systab               = EFI_INVALID_TABLE_ADDR,
> +	.boot_info                = EFI_INVALID_TABLE_ADDR,
> +	.hcdp                     = EFI_INVALID_TABLE_ADDR,
> +	.uga                      = EFI_INVALID_TABLE_ADDR,
> +	.uv_systab                = EFI_INVALID_TABLE_ADDR,
> +	.fw_vendor                = EFI_INVALID_TABLE_ADDR,
> +	.runtime                  = EFI_INVALID_TABLE_ADDR,
> +	.config_table             = EFI_INVALID_TABLE_ADDR,
> +	.get_time                 = xen_efi_get_time,
> +	.set_time                 = xen_efi_set_time,
> +	.get_wakeup_time          = xen_efi_get_wakeup_time,
> +	.set_wakeup_time          = xen_efi_set_wakeup_time,
> +	.get_variable             = xen_efi_get_variable,
> +	.get_next_variable        = xen_efi_get_next_variable,
> +	.set_variable             = xen_efi_set_variable,
> +	.query_variable_info      = xen_efi_query_variable_info,
> +	.update_capsule           = xen_efi_update_capsule,
> +	.query_capsule_caps       = xen_efi_query_capsule_caps,
> +	.get_next_high_mono_count = xen_efi_get_next_high_mono_count,
> +	.reset_system             = NULL, /* Functionality provided by Xen. */
> +	.set_virtual_address_map  = NULL, /* Not used under Xen. */
> +	.memmap                   = NULL, /* Not used under Xen. */
> +	.flags			  = 0     /* Initialized later. */
> +};
> +
> +efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	struct xen_platform_op op = {
> +		.cmd = XENPF_firmware_info,
> +		.u.firmware_info = {
> +			.type = XEN_FW_EFI_INFO,
> +			.index = XEN_FW_EFI_CONFIG_TABLE
> +		}
> +	};
> +	union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
> +
> +	if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0)
> +		return NULL;
> +
> +	/* Here we know that Xen runs on EFI platform. */
> +
> +	efi = efi_xen;
> +
> +	efi_systab_xen.tables = info->cfg.addr;
> +	efi_systab_xen.nr_tables = info->cfg.nent;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
> +	info->vendor.bufsz = sizeof(vendor);
> +	set_xen_guest_handle(info->vendor.name, vendor);
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0) {
> +		efi_systab_xen.fw_vendor = __pa_symbol(vendor);
> +		efi_systab_xen.fw_revision = info->vendor.revision;
> +	} else
> +		efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi_systab_xen.hdr.revision = info->version;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi.runtime_version = info->version;
> +
> +	return &efi_systab_xen;
> +}
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 7/9] xen: Put EFI machinery in place
  2014-06-20 21:29   ` Daniel Kiper
  (?)
@ 2014-06-21 14:53   ` Stefano Stabellini
  -1 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2014-06-21 14:53 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: mjg59, jeremy, linux-efi, ian.campbell, andrew.cooper3, x86,
	linux-kernel, matt.fleming, tglx, david.vrabel, jbeulich, hpa,
	xen-devel, boris.ostrovsky, mingo, stefano.stabellini, eshelton

On Fri, 20 Jun 2014, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.
> 
> This patch is based on Jan Beulich and Tang Liang work.
> 
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Tang Liang <liang.tang@oracle.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v6 - suggestions/fixes:
>    - remove unneeded BUG() call
>      (suggested by Stefano Stabellini).
> 
> v5 - suggestions/fixes:
>    - improve macro usage readability
>      (suggested by Andrew Cooper and David Vrabel),
>    - conditions cleanup
>      (suggested by David Vrabel),
>    - use -fshort-wchar option
>      (suggested by Jan Beulich),
>    - Kconfig rule cleanup
>      (suggested by Jan Beulich),
>    - forward port fixes from SUSE kernel
>      (suggested by Jan Beulich),
>    - improve commit message
>      (suggested by David Vrabel).
> 
> v4 - suggestions/fixes:
>    - "just populate an efi_system_table_t object"
>      (suggested by Matt Fleming).
> ---
>  arch/x86/xen/enlighten.c |   24 +++
>  drivers/xen/Kconfig      |    4 +
>  drivers/xen/Makefile     |    3 +
>  drivers/xen/efi.c        |  367 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 398 insertions(+)
>  create mode 100644 drivers/xen/efi.c
> 
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index ffb101e..04611ea 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -32,6 +32,7 @@
>  #include <linux/gfp.h>
>  #include <linux/memblock.h>
>  #include <linux/edd.h>
> +#include <linux/efi.h>
>  
>  #include <xen/xen.h>
>  #include <xen/events.h>
> @@ -150,6 +151,15 @@ struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
>   */
>  static int have_vcpu_info_placement = 1;
>  
> +#ifdef CONFIG_XEN_EFI
> +extern efi_system_table_t __init *xen_efi_probe(void);
> +#else
> +static efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	return NULL;
> +}
> +#endif

I should have spotted this before, but it would be better to move this
chunk to an header file under include/xen.



>  struct tls_descs {
>  	struct desc_struct desc[3];
>  };
> @@ -1520,6 +1530,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  {
>  	struct physdev_set_iopl set_iopl;
>  	int rc;
> +	efi_system_table_t *efi_systab_xen;
>  
>  	if (!xen_start_info)
>  		return;
> @@ -1718,6 +1729,19 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  
>  	xen_setup_runstate_info(0);
>  
> +	efi_systab_xen = xen_efi_probe();
> +
> +	if (efi_systab_xen) {
> +		strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen",
> +				sizeof(boot_params.efi_info.efi_loader_signature));
> +		boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen);
> +		boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32);
> +
> +		set_bit(EFI_BOOT, &efi.flags);
> +		set_bit(EFI_PARAVIRT, &efi.flags);
> +		set_bit(EFI_64BIT, &efi.flags);
> +	}
> +
>  	/* Start the world */
>  #ifdef CONFIG_X86_32
>  	i386_start_kernel();
> diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
> index 38fb36e..8bc0183 100644
> --- a/drivers/xen/Kconfig
> +++ b/drivers/xen/Kconfig
> @@ -240,4 +240,8 @@ config XEN_MCE_LOG
>  config XEN_HAVE_PVMMU
>         bool
>  
> +config XEN_EFI
> +	def_bool y
> +	depends on X86_64 && EFI
> +
>  endmenu
> diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
> index 45e00af..84044b5 100644
> --- a/drivers/xen/Makefile
> +++ b/drivers/xen/Makefile
> @@ -9,6 +9,8 @@ obj-y	+= xenbus/
>  nostackp := $(call cc-option, -fno-stack-protector)
>  CFLAGS_features.o			:= $(nostackp)
>  
> +CFLAGS_efi.o				+= -fshort-wchar
> +
>  dom0-$(CONFIG_PCI) += pci.o
>  dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
>  dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
> @@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB)			+= xen-stub.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)	+= xen-acpi-memhotplug.o
>  obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU)	+= xen-acpi-cpuhotplug.o
>  obj-$(CONFIG_XEN_ACPI_PROCESSOR)	+= xen-acpi-processor.o
> +obj-$(CONFIG_XEN_EFI)			+= efi.o
>  xen-evtchn-y				:= evtchn.o
>  xen-gntdev-y				:= gntdev.o
>  xen-gntalloc-y				:= gntalloc.o
> diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
> new file mode 100644
> index 0000000..d8d55a5
> --- /dev/null
> +++ b/drivers/xen/efi.c
> @@ -0,0 +1,367 @@
> +/*
> + * EFI support for Xen.
> + *
> + * Copyright (C) 1999 VA Linux Systems
> + * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
> + * Copyright (C) 1999-2002 Hewlett-Packard Co.
> + *	David Mosberger-Tang <davidm@hpl.hp.com>
> + *	Stephane Eranian <eranian@hpl.hp.com>
> + * Copyright (C) 2005-2008 Intel Co.
> + *	Fenghua Yu <fenghua.yu@intel.com>
> + *	Bibo Mao <bibo.mao@intel.com>
> + *	Chandramouli Narayanan <mouli@linux.intel.com>
> + *	Huang Ying <ying.huang@intel.com>
> + * Copyright (C) 2011 Novell Co.
> + *	Jan Beulich <JBeulich@suse.com>
> + * Copyright (C) 2011-2012 Oracle Co.
> + *	Liang Tang <liang.tang@oracle.com>
> + * Copyright (c) 2014 Oracle Co., Daniel Kiper
> + */
> +
> +#include <linux/bug.h>
> +#include <linux/efi.h>
> +#include <linux/init.h>
> +#include <linux/string.h>
> +
> +#include <xen/interface/xen.h>
> +#include <xen/interface/platform.h>
> +
> +#include <asm/xen/hypercall.h>
> +
> +#define INIT_EFI_OP(name) \
> +	{.cmd = XENPF_efi_runtime_call, \
> +	 .u.efi_runtime_call.function = XEN_EFI_##name, \
> +	 .u.efi_runtime_call.misc = 0}
> +
> +#define efi_data(op)	(op.u.efi_runtime_call)
> +
> +static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_time.time));
> +		memcpy(tm, &efi_data(op).u.get_time.time, sizeof(*tm));
> +	}
> +
> +	if (tc) {
> +		tc->resolution = efi_data(op).u.get_time.resolution;
> +		tc->accuracy = efi_data(op).u.get_time.accuracy;
> +		tc->sets_to_zero = !!(efi_data(op).misc &
> +				      XEN_EFI_GET_TIME_SET_CLEARS_NS);
> +	}
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_time(efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_time));
> +	memcpy(&efi_data(op).u.set_time, tm, sizeof(*tm));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
> +					    efi_bool_t *pending,
> +					    efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	if (tm) {
> +		BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.get_wakeup_time));
> +		memcpy(tm, &efi_data(op).u.get_wakeup_time, sizeof(*tm));
> +	}
> +
> +	if (enabled)
> +		*enabled = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED);
> +
> +	if (pending)
> +		*pending = !!(efi_data(op).misc & XEN_EFI_GET_WAKEUP_TIME_PENDING);
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
> +
> +	BUILD_BUG_ON(sizeof(*tm) != sizeof(efi_data(op).u.set_wakeup_time));
> +	if (enabled)
> +		efi_data(op).misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE;
> +	if (tm)
> +		memcpy(&efi_data(op).u.set_wakeup_time, tm, sizeof(*tm));
> +	else
> +		efi_data(op).misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 *attr,
> +					 unsigned long *data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.get_variable.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.get_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.get_variable.size = *data_size;
> +	set_xen_guest_handle(efi_data(op).u.get_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*data_size = efi_data(op).u.get_variable.size;
> +	if (attr)
> +		*attr = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
> +					      efi_char16_t *name,
> +					      efi_guid_t *vendor)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
> +
> +	efi_data(op).u.get_next_variable_name.size = *name_size;
> +	set_xen_guest_handle(efi_data(op).u.get_next_variable_name.name, name);
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.get_next_variable_name.vendor_guid));
> +	memcpy(&efi_data(op).u.get_next_variable_name.vendor_guid, vendor,
> +	       sizeof(*vendor));
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*name_size = efi_data(op).u.get_next_variable_name.size;
> +	memcpy(vendor, &efi_data(op).u.get_next_variable_name.vendor_guid,
> +	       sizeof(*vendor));
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_set_variable(efi_char16_t *name,
> +					 efi_guid_t *vendor,
> +					 u32 attr,
> +					 unsigned long data_size,
> +					 void *data)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(set_variable);
> +
> +	set_xen_guest_handle(efi_data(op).u.set_variable.name, name);
> +	efi_data(op).misc = attr;
> +	BUILD_BUG_ON(sizeof(*vendor) !=
> +		     sizeof(efi_data(op).u.set_variable.vendor_guid));
> +	memcpy(&efi_data(op).u.set_variable.vendor_guid, vendor, sizeof(*vendor));
> +	efi_data(op).u.set_variable.size = data_size;
> +	set_xen_guest_handle(efi_data(op).u.set_variable.data, data);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_variable_info(u32 attr,
> +						u64 *storage_space,
> +						u64 *remaining_space,
> +						u64 *max_variable_size)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	efi_data(op).u.query_variable_info.attr = attr;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*storage_space = efi_data(op).u.query_variable_info.max_store_size;
> +	*remaining_space = efi_data(op).u.query_variable_info.remain_store_size;
> +	*max_variable_size = efi_data(op).u.query_variable_info.max_size;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*count = efi_data(op).misc;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
> +					   unsigned long count,
> +					   unsigned long sg_list)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(update_capsule);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.update_capsule.capsule_header_array,
> +			     capsules);
> +	efi_data(op).u.update_capsule.capsule_count = count;
> +	efi_data(op).u.update_capsule.sg_list = sg_list;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
> +					       unsigned long count,
> +					       u64 *max_size,
> +					       int *reset_type)
> +{
> +	struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
> +
> +	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
> +		return EFI_UNSUPPORTED;
> +
> +	set_xen_guest_handle(efi_data(op).u.query_capsule_capabilities.capsule_header_array,
> +					capsules);
> +	efi_data(op).u.query_capsule_capabilities.capsule_count = count;
> +
> +	if (HYPERVISOR_dom0_op(&op) < 0)
> +		return EFI_UNSUPPORTED;
> +
> +	*max_size = efi_data(op).u.query_capsule_capabilities.max_capsule_size;
> +	*reset_type = efi_data(op).u.query_capsule_capabilities.reset_type;
> +
> +	return efi_data(op).status;
> +}
> +
> +static efi_char16_t vendor[100] __initdata;
> +
> +static efi_system_table_t efi_systab_xen __initdata = {
> +	.hdr = {
> +		.signature	= EFI_SYSTEM_TABLE_SIGNATURE,
> +		.revision	= 0, /* Initialized later. */
> +		.headersize	= 0, /* Ignored by Linux Kernel. */
> +		.crc32		= 0, /* Ignored by Linux Kernel. */
> +		.reserved	= 0
> +	},
> +	.fw_vendor	= EFI_INVALID_TABLE_ADDR, /* Initialized later. */
> +	.fw_revision	= 0,			  /* Initialized later. */
> +	.con_in_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_in		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.con_out	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr_handle	= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.stderr		= EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
> +	.runtime	= (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.boottime	= (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
> +						  /* Not used under Xen. */
> +	.nr_tables	= 0,			  /* Initialized later. */
> +	.tables		= EFI_INVALID_TABLE_ADDR  /* Initialized later. */
> +};
> +
> +static const struct efi efi_xen __initconst = {
> +	.systab                   = NULL, /* Initialized later. */
> +	.runtime_version	  = 0,    /* Initialized later. */
> +	.mps                      = EFI_INVALID_TABLE_ADDR,
> +	.acpi                     = EFI_INVALID_TABLE_ADDR,
> +	.acpi20                   = EFI_INVALID_TABLE_ADDR,
> +	.smbios                   = EFI_INVALID_TABLE_ADDR,
> +	.sal_systab               = EFI_INVALID_TABLE_ADDR,
> +	.boot_info                = EFI_INVALID_TABLE_ADDR,
> +	.hcdp                     = EFI_INVALID_TABLE_ADDR,
> +	.uga                      = EFI_INVALID_TABLE_ADDR,
> +	.uv_systab                = EFI_INVALID_TABLE_ADDR,
> +	.fw_vendor                = EFI_INVALID_TABLE_ADDR,
> +	.runtime                  = EFI_INVALID_TABLE_ADDR,
> +	.config_table             = EFI_INVALID_TABLE_ADDR,
> +	.get_time                 = xen_efi_get_time,
> +	.set_time                 = xen_efi_set_time,
> +	.get_wakeup_time          = xen_efi_get_wakeup_time,
> +	.set_wakeup_time          = xen_efi_set_wakeup_time,
> +	.get_variable             = xen_efi_get_variable,
> +	.get_next_variable        = xen_efi_get_next_variable,
> +	.set_variable             = xen_efi_set_variable,
> +	.query_variable_info      = xen_efi_query_variable_info,
> +	.update_capsule           = xen_efi_update_capsule,
> +	.query_capsule_caps       = xen_efi_query_capsule_caps,
> +	.get_next_high_mono_count = xen_efi_get_next_high_mono_count,
> +	.reset_system             = NULL, /* Functionality provided by Xen. */
> +	.set_virtual_address_map  = NULL, /* Not used under Xen. */
> +	.memmap                   = NULL, /* Not used under Xen. */
> +	.flags			  = 0     /* Initialized later. */
> +};
> +
> +efi_system_table_t __init *xen_efi_probe(void)
> +{
> +	struct xen_platform_op op = {
> +		.cmd = XENPF_firmware_info,
> +		.u.firmware_info = {
> +			.type = XEN_FW_EFI_INFO,
> +			.index = XEN_FW_EFI_CONFIG_TABLE
> +		}
> +	};
> +	union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
> +
> +	if (!xen_initial_domain() || HYPERVISOR_dom0_op(&op) < 0)
> +		return NULL;
> +
> +	/* Here we know that Xen runs on EFI platform. */
> +
> +	efi = efi_xen;
> +
> +	efi_systab_xen.tables = info->cfg.addr;
> +	efi_systab_xen.nr_tables = info->cfg.nent;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
> +	info->vendor.bufsz = sizeof(vendor);
> +	set_xen_guest_handle(info->vendor.name, vendor);
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0) {
> +		efi_systab_xen.fw_vendor = __pa_symbol(vendor);
> +		efi_systab_xen.fw_revision = info->vendor.revision;
> +	} else
> +		efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi_systab_xen.hdr.revision = info->version;
> +
> +	op.cmd = XENPF_firmware_info;
> +	op.u.firmware_info.type = XEN_FW_EFI_INFO;
> +	op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
> +
> +	if (HYPERVISOR_dom0_op(&op) == 0)
> +		efi.runtime_version = info->version;
> +
> +	return &efi_systab_xen;
> +}
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-23  7:19     ` Jan Beulich
  0 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23  7:19 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: andrew.cooper3, david.vrabel, ian.campbell, stefano.stabellini,
	jeremy, matt.fleming, x86, tglx, xen-devel, boris.ostrovsky,
	konrad.wilk, eshelton, mingo, mjg59, linux-efi, linux-kernel,
	hpa

>>> On 20.06.14 at 23:29, <daniel.kiper@oracle.com> wrote:
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  			if (table64 >> 32) {
>  				pr_cont("\n");
>  				pr_err("Table located above 4GB, disabling EFI.\n");
> -				early_iounmap(config_tables,
> +				early_memunmap(config_tables,
>  					       efi.systab->nr_tables * sz);
>  				return -EINVAL;
>  			}
> @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  		tablep += sz;
>  	}
>  	pr_cont("\n");
> -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
>  
>  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
>  

If these two changes are really deemed necessary (there's the
implied assumption currently in place that early_iounmap() can
undo early_memremap() mappings), then ia64 will need a
definition added for early_memunmap() or its build will break.

Jan


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-23  7:19     ` Jan Beulich
  0 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23  7:19 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ, jeremy-TSDbQ3PG+2Y,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, hpa-YMNOUZJC4hwAvxtiuMwx3w

>>> On 20.06.14 at 23:29, <daniel.kiper-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org> wrote:
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  			if (table64 >> 32) {
>  				pr_cont("\n");
>  				pr_err("Table located above 4GB, disabling EFI.\n");
> -				early_iounmap(config_tables,
> +				early_memunmap(config_tables,
>  					       efi.systab->nr_tables * sz);
>  				return -EINVAL;
>  			}
> @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  		tablep += sz;
>  	}
>  	pr_cont("\n");
> -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
>  
>  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
>  

If these two changes are really deemed necessary (there's the
implied assumption currently in place that early_iounmap() can
undo early_memremap() mappings), then ia64 will need a
definition added for early_memunmap() or its build will break.

Jan

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
  2014-06-20 21:29   ` Daniel Kiper
  (?)
  (?)
@ 2014-06-23  7:19   ` Jan Beulich
  -1 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23  7:19 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, stefano.stabellini,
	linux-efi, andrew.cooper3, x86, linux-kernel, mingo,
	david.vrabel, hpa, xen-devel, tglx, boris.ostrovsky, eshelton

>>> On 20.06.14 at 23:29, <daniel.kiper@oracle.com> wrote:
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  			if (table64 >> 32) {
>  				pr_cont("\n");
>  				pr_err("Table located above 4GB, disabling EFI.\n");
> -				early_iounmap(config_tables,
> +				early_memunmap(config_tables,
>  					       efi.systab->nr_tables * sz);
>  				return -EINVAL;
>  			}
> @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
>  		tablep += sz;
>  	}
>  	pr_cont("\n");
> -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
>  
>  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
>  

If these two changes are really deemed necessary (there's the
implied assumption currently in place that early_iounmap() can
undo early_memremap() mappings), then ia64 will need a
definition added for early_memunmap() or its build will break.

Jan

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 6/9] xen: Define EFI related stuff
@ 2014-06-23  9:50     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:50 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, eshelton, hpa, ian.campbell,
	jbeulich, jeremy, konrad.wilk, matt.fleming, mingo, mjg59,
	stefano.stabellini, tglx

On 20/06/14 22:29, Daniel Kiper wrote:
> Define constants and structures which are needed to properly
> execute EFI related hypercall in Xen dom0.

Reviewed-by: David Vrabel <david.vrabel@citrix.com>

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 6/9] xen: Define EFI related stuff
@ 2014-06-23  9:50     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:50 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	jeremy-TSDbQ3PG+2Y, konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, mjg59-1xO5oi07KQx4cg9Nei1l7Q,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

On 20/06/14 22:29, Daniel Kiper wrote:
> Define constants and structures which are needed to properly
> execute EFI related hypercall in Xen dom0.

Reviewed-by: David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org>

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 6/9] xen: Define EFI related stuff
  2014-06-20 21:29 ` Daniel Kiper
@ 2014-06-23  9:50   ` David Vrabel
  2014-06-23  9:50     ` David Vrabel
  1 sibling, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:50 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, jbeulich, hpa, boris.ostrovsky, tglx,
	eshelton

On 20/06/14 22:29, Daniel Kiper wrote:
> Define constants and structures which are needed to properly
> execute EFI related hypercall in Xen dom0.

Reviewed-by: David Vrabel <david.vrabel@citrix.com>

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23  9:53     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:53 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: andrew.cooper3, boris.ostrovsky, eshelton, hpa, ian.campbell,
	jbeulich, jeremy, konrad.wilk, matt.fleming, mingo, mjg59,
	stefano.stabellini, tglx

On 20/06/14 22:29, Daniel Kiper wrote:
> Do not access EFI memory map if it is not available. At least
> Xen dom0 EFI implementation does not have an access to it.

Could it make one based on the XENMEM_memory_map or
XENMEM_machine_memory_map hypercall?

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23  9:53     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:53 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	jeremy-TSDbQ3PG+2Y, konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, mjg59-1xO5oi07KQx4cg9Nei1l7Q,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

On 20/06/14 22:29, Daniel Kiper wrote:
> Do not access EFI memory map if it is not available. At least
> Xen dom0 EFI implementation does not have an access to it.

Could it make one based on the XENMEM_memory_map or
XENMEM_machine_memory_map hypercall?

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
  2014-06-20 21:29 ` [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available Daniel Kiper
  2014-06-23  9:53     ` David Vrabel
@ 2014-06-23  9:53   ` David Vrabel
  1 sibling, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:53 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, jbeulich, hpa, boris.ostrovsky, tglx,
	eshelton

On 20/06/14 22:29, Daniel Kiper wrote:
> Do not access EFI memory map if it is not available. At least
> Xen dom0 EFI implementation does not have an access to it.

Could it make one based on the XENMEM_memory_map or
XENMEM_machine_memory_map hypercall?

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [Xen-devel] [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-23  9:57     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:57 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, andrew.cooper3,
	stefano.stabellini, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

On 20/06/14 22:29, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.

Reviewed-by: David Vrabel <david.vrabel@citrix.com>

(With or without the change suggested by Stefano).

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [Xen-devel] [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-23  9:57     ` David Vrabel
  0 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:57 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, jeremy-TSDbQ3PG+2Y,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	mingo-H+wXaHxf7aLQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	hpa-YMNOUZJC4hwAvxtiuMwx3w,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	tglx-hfZtesqFncYOwBW4kG4KsQ, eshelton-e+AXbWqSrlAAvxtiuMwx3w

On 20/06/14 22:29, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.

Reviewed-by: David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org>

(With or without the change suggested by Stefano).

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 7/9] xen: Put EFI machinery in place
  2014-06-20 21:29   ` Daniel Kiper
                     ` (3 preceding siblings ...)
  (?)
@ 2014-06-23  9:57   ` David Vrabel
  -1 siblings, 0 replies; 51+ messages in thread
From: David Vrabel @ 2014-06-23  9:57 UTC (permalink / raw)
  To: Daniel Kiper, linux-efi, linux-kernel, x86, xen-devel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, stefano.stabellini,
	andrew.cooper3, mingo, david.vrabel, jbeulich, hpa,
	boris.ostrovsky, tglx, eshelton

On 20/06/14 22:29, Daniel Kiper wrote:
> This patch enables EFI usage under Xen dom0. Standard EFI Linux
> Kernel infrastructure cannot be used because it requires direct
> access to EFI data and code. However, in dom0 case it is not possible
> because above mentioned EFI stuff is fully owned and controlled
> by Xen hypervisor. In this case all calls from dom0 to EFI must
> be requested via special hypercall which in turn executes relevant
> EFI code in behalf of dom0.
> 
> When dom0 kernel boots it checks for EFI availability on a machine.
> If it is detected then artificial EFI system table is filled.
> Native EFI callas are replaced by functions which mimics them
> by calling relevant hypercall. Later pointer to EFI system table
> is passed to standard EFI machinery and it continues EFI subsystem
> initialization taking into account that there is no direct access
> to EFI boot services, runtime, tables, structures, etc. After that
> system runs as usual.

Reviewed-by: David Vrabel <david.vrabel@citrix.com>

(With or without the change suggested by Stefano).

Thanks.

David

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23 11:00       ` Jan Beulich
  0 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23 11:00 UTC (permalink / raw)
  To: David Vrabel, x86, xen-devel, Daniel Kiper, linux-efi, linux-kernel
  Cc: andrew.cooper3, ian.campbell, stefano.stabellini, jeremy,
	matt.fleming, tglx, boris.ostrovsky, konrad.wilk, eshelton,
	mingo, mjg59, hpa

>>> On 23.06.14 at 11:53, <david.vrabel@citrix.com> wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
>> Do not access EFI memory map if it is not available. At least
>> Xen dom0 EFI implementation does not have an access to it.
> 
> Could it make one based on the XENMEM_memory_map or
> XENMEM_machine_memory_map hypercall?

No, the correct operation to implement this and efi_mem_type()
similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

Jan


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23 11:00       ` Jan Beulich
  0 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23 11:00 UTC (permalink / raw)
  To: David Vrabel, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b, Daniel Kiper,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ, jeremy-TSDbQ3PG+2Y,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w, tglx-hfZtesqFncYOwBW4kG4KsQ,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w

>>> On 23.06.14 at 11:53, <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
>> Do not access EFI memory map if it is not available. At least
>> Xen dom0 EFI implementation does not have an access to it.
> 
> Could it make one based on the XENMEM_memory_map or
> XENMEM_machine_memory_map hypercall?

No, the correct operation to implement this and efi_mem_type()
similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

Jan

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
  2014-06-23  9:53     ` David Vrabel
  (?)
@ 2014-06-23 11:00     ` Jan Beulich
  -1 siblings, 0 replies; 51+ messages in thread
From: Jan Beulich @ 2014-06-23 11:00 UTC (permalink / raw)
  To: David Vrabel, x86, xen-devel, Daniel Kiper, linux-efi, linux-kernel
  Cc: mjg59, jeremy, matt.fleming, ian.campbell, stefano.stabellini,
	andrew.cooper3, mingo, hpa, tglx, boris.ostrovsky, eshelton

>>> On 23.06.14 at 11:53, <david.vrabel@citrix.com> wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
>> Do not access EFI memory map if it is not available. At least
>> Xen dom0 EFI implementation does not have an access to it.
> 
> Could it make one based on the XENMEM_memory_map or
> XENMEM_machine_memory_map hypercall?

No, the correct operation to implement this and efi_mem_type()
similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

Jan

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
  2014-06-23  7:19     ` Jan Beulich
@ 2014-06-23 13:54       ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: andrew.cooper3, david.vrabel, ian.campbell, stefano.stabellini,
	jeremy, matt.fleming, x86, tglx, xen-devel, boris.ostrovsky,
	konrad.wilk, eshelton, mingo, mjg59, linux-efi, linux-kernel,
	hpa, tony.luck, fenghua.yu, linux-ia64

I am CC'ing IA-64 guys.

On Mon, Jun 23, 2014 at 08:19:00AM +0100, Jan Beulich wrote:
> >>> On 20.06.14 at 23:29, <daniel.kiper@oracle.com> wrote:
> > --- a/drivers/firmware/efi/efi.c
> > +++ b/drivers/firmware/efi/efi.c
> > @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  			if (table64 >> 32) {
> >  				pr_cont("\n");
> >  				pr_err("Table located above 4GB, disabling EFI.\n");
> > -				early_iounmap(config_tables,
> > +				early_memunmap(config_tables,
> >  					       efi.systab->nr_tables * sz);
> >  				return -EINVAL;
> >  			}
> > @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  		tablep += sz;
> >  	}
> >  	pr_cont("\n");
> > -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> > +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
> >
> >  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
> >
>
> If these two changes are really deemed necessary (there's the
> implied assumption currently in place that early_iounmap() can
> undo early_memremap() mappings), then ia64 will need a
> definition added for early_memunmap() or its build will break.

I know that early_memunmap() == early_iounmap() in general. However,
I think that it is less confusing if use relevant functions in pairs
(i.e. early_memremap() with early_memunmap(), ...) than mix them up.

We have following choices here:
  - leave early_iounmap() as is in drivers/firmware/efi/efi.c
    (arch/x86/platform/efi/efi.c:early_iounmap() -> early_memunmap()
    changes should be left as is),
  - include asm/early_ioremap.h in arch/ia64/include/asm/io.h
    (as I can see the same think is done for x86 and arm64).

I prefer second solution but I do not insist.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
  2014-06-23  7:19     ` Jan Beulich
  (?)
  (?)
@ 2014-06-23 13:54     ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: tony.luck, mjg59, jeremy, matt.fleming, linux-ia64, ian.campbell,
	stefano.stabellini, linux-efi, andrew.cooper3, x86, linux-kernel,
	fenghua.yu, mingo, david.vrabel, hpa, xen-devel, tglx,
	boris.ostrovsky, eshelton

I am CC'ing IA-64 guys.

On Mon, Jun 23, 2014 at 08:19:00AM +0100, Jan Beulich wrote:
> >>> On 20.06.14 at 23:29, <daniel.kiper@oracle.com> wrote:
> > --- a/drivers/firmware/efi/efi.c
> > +++ b/drivers/firmware/efi/efi.c
> > @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  			if (table64 >> 32) {
> >  				pr_cont("\n");
> >  				pr_err("Table located above 4GB, disabling EFI.\n");
> > -				early_iounmap(config_tables,
> > +				early_memunmap(config_tables,
> >  					       efi.systab->nr_tables * sz);
> >  				return -EINVAL;
> >  			}
> > @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  		tablep += sz;
> >  	}
> >  	pr_cont("\n");
> > -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> > +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
> >
> >  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
> >
>
> If these two changes are really deemed necessary (there's the
> implied assumption currently in place that early_iounmap() can
> undo early_memremap() mappings), then ia64 will need a
> definition added for early_memunmap() or its build will break.

I know that early_memunmap() == early_iounmap() in general. However,
I think that it is less confusing if use relevant functions in pairs
(i.e. early_memremap() with early_memunmap(), ...) than mix them up.

We have following choices here:
  - leave early_iounmap() as is in drivers/firmware/efi/efi.c
    (arch/x86/platform/efi/efi.c:early_iounmap() -> early_memunmap()
    changes should be left as is),
  - include asm/early_ioremap.h in arch/ia64/include/asm/io.h
    (as I can see the same think is done for x86 and arm64).

I prefer second solution but I do not insist.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-23 13:54       ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: andrew.cooper3, david.vrabel, ian.campbell, stefano.stabellini,
	jeremy, matt.fleming, x86, tglx, xen-devel, boris.ostrovsky,
	konrad.wilk, eshelton, mingo, mjg59, linux-efi, linux-kernel,
	hpa, tony.luck, fenghua.yu, linux-ia64

I am CC'ing IA-64 guys.

On Mon, Jun 23, 2014 at 08:19:00AM +0100, Jan Beulich wrote:
> >>> On 20.06.14 at 23:29, <daniel.kiper@oracle.com> wrote:
> > --- a/drivers/firmware/efi/efi.c
> > +++ b/drivers/firmware/efi/efi.c
> > @@ -298,7 +298,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  			if (table64 >> 32) {
> >  				pr_cont("\n");
> >  				pr_err("Table located above 4GB, disabling EFI.\n");
> > -				early_iounmap(config_tables,
> > +				early_memunmap(config_tables,
> >  					       efi.systab->nr_tables * sz);
> >  				return -EINVAL;
> >  			}
> > @@ -314,7 +314,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
> >  		tablep += sz;
> >  	}
> >  	pr_cont("\n");
> > -	early_iounmap(config_tables, efi.systab->nr_tables * sz);
> > +	early_memunmap(config_tables, efi.systab->nr_tables * sz);
> >
> >  	set_bit(EFI_CONFIG_TABLES, &efi.flags);
> >
>
> If these two changes are really deemed necessary (there's the
> implied assumption currently in place that early_iounmap() can
> undo early_memremap() mappings), then ia64 will need a
> definition added for early_memunmap() or its build will break.

I know that early_memunmap() = early_iounmap() in general. However,
I think that it is less confusing if use relevant functions in pairs
(i.e. early_memremap() with early_memunmap(), ...) than mix them up.

We have following choices here:
  - leave early_iounmap() as is in drivers/firmware/efi/efi.c
    (arch/x86/platform/efi/efi.c:early_iounmap() -> early_memunmap()
    changes should be left as is),
  - include asm/early_ioremap.h in arch/ia64/include/asm/io.h
    (as I can see the same think is done for x86 and arm64).

I prefer second solution but I do not insist.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [Xen-devel] [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-23 13:57       ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:57 UTC (permalink / raw)
  To: David Vrabel
  Cc: linux-efi, linux-kernel, x86, xen-devel, mjg59, jeremy,
	matt.fleming, ian.campbell, andrew.cooper3, stefano.stabellini,
	mingo, jbeulich, hpa, boris.ostrovsky, tglx, eshelton

On Mon, Jun 23, 2014 at 10:57:31AM +0100, David Vrabel wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
> > This patch enables EFI usage under Xen dom0. Standard EFI Linux
> > Kernel infrastructure cannot be used because it requires direct
> > access to EFI data and code. However, in dom0 case it is not possible
> > because above mentioned EFI stuff is fully owned and controlled
> > by Xen hypervisor. In this case all calls from dom0 to EFI must
> > be requested via special hypercall which in turn executes relevant
> > EFI code in behalf of dom0.
> >
> > When dom0 kernel boots it checks for EFI availability on a machine.
> > If it is detected then artificial EFI system table is filled.
> > Native EFI callas are replaced by functions which mimics them
> > by calling relevant hypercall. Later pointer to EFI system table
> > is passed to standard EFI machinery and it continues EFI subsystem
> > initialization taking into account that there is no direct access
> > to EFI boot services, runtime, tables, structures, etc. After that
> > system runs as usual.
>
> Reviewed-by: David Vrabel <david.vrabel@citrix.com>

Thanks for this and second one.

> (With or without the change suggested by Stefano).

I am going to take into account Stefano's idea.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [Xen-devel] [PATCH v6 7/9] xen: Put EFI machinery in place
@ 2014-06-23 13:57       ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:57 UTC (permalink / raw)
  To: David Vrabel
  Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, jeremy-TSDbQ3PG+2Y,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, jbeulich-IBi9RG/b67k,
	hpa-YMNOUZJC4hwAvxtiuMwx3w,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	tglx-hfZtesqFncYOwBW4kG4KsQ, eshelton-e+AXbWqSrlAAvxtiuMwx3w

On Mon, Jun 23, 2014 at 10:57:31AM +0100, David Vrabel wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
> > This patch enables EFI usage under Xen dom0. Standard EFI Linux
> > Kernel infrastructure cannot be used because it requires direct
> > access to EFI data and code. However, in dom0 case it is not possible
> > because above mentioned EFI stuff is fully owned and controlled
> > by Xen hypervisor. In this case all calls from dom0 to EFI must
> > be requested via special hypercall which in turn executes relevant
> > EFI code in behalf of dom0.
> >
> > When dom0 kernel boots it checks for EFI availability on a machine.
> > If it is detected then artificial EFI system table is filled.
> > Native EFI callas are replaced by functions which mimics them
> > by calling relevant hypercall. Later pointer to EFI system table
> > is passed to standard EFI machinery and it continues EFI subsystem
> > initialization taking into account that there is no direct access
> > to EFI boot services, runtime, tables, structures, etc. After that
> > system runs as usual.
>
> Reviewed-by: David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org>

Thanks for this and second one.

> (With or without the change suggested by Stefano).

I am going to take into account Stefano's idea.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 7/9] xen: Put EFI machinery in place
  2014-06-23  9:57     ` David Vrabel
  (?)
  (?)
@ 2014-06-23 13:57     ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 13:57 UTC (permalink / raw)
  To: David Vrabel
  Cc: mjg59, jeremy, linux-efi, ian.campbell, stefano.stabellini,
	andrew.cooper3, x86, linux-kernel, matt.fleming, tglx, jbeulich,
	hpa, xen-devel, boris.ostrovsky, mingo, eshelton

On Mon, Jun 23, 2014 at 10:57:31AM +0100, David Vrabel wrote:
> On 20/06/14 22:29, Daniel Kiper wrote:
> > This patch enables EFI usage under Xen dom0. Standard EFI Linux
> > Kernel infrastructure cannot be used because it requires direct
> > access to EFI data and code. However, in dom0 case it is not possible
> > because above mentioned EFI stuff is fully owned and controlled
> > by Xen hypervisor. In this case all calls from dom0 to EFI must
> > be requested via special hypercall which in turn executes relevant
> > EFI code in behalf of dom0.
> >
> > When dom0 kernel boots it checks for EFI availability on a machine.
> > If it is detected then artificial EFI system table is filled.
> > Native EFI callas are replaced by functions which mimics them
> > by calling relevant hypercall. Later pointer to EFI system table
> > is passed to standard EFI machinery and it continues EFI subsystem
> > initialization taking into account that there is no direct access
> > to EFI boot services, runtime, tables, structures, etc. After that
> > system runs as usual.
>
> Reviewed-by: David Vrabel <david.vrabel@citrix.com>

Thanks for this and second one.

> (With or without the change suggested by Stefano).

I am going to take into account Stefano's idea.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23 14:13         ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 14:13 UTC (permalink / raw)
  To: Jan Beulich
  Cc: David Vrabel, x86, xen-devel, linux-efi, linux-kernel,
	andrew.cooper3, ian.campbell, stefano.stabellini, jeremy,
	matt.fleming, tglx, boris.ostrovsky, konrad.wilk, eshelton,
	mingo, mjg59, hpa

On Mon, Jun 23, 2014 at 12:00:01PM +0100, Jan Beulich wrote:
> >>> On 23.06.14 at 11:53, <david.vrabel@citrix.com> wrote:
> > On 20/06/14 22:29, Daniel Kiper wrote:
> >> Do not access EFI memory map if it is not available. At least
> >> Xen dom0 EFI implementation does not have an access to it.
> >
> > Could it make one based on the XENMEM_memory_map or
> > XENMEM_machine_memory_map hypercall?
>
> No, the correct operation to implement this and efi_mem_type()
> similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

efi_mem_attributes() is used only on IA-64 arch. So, that is why
I completely removed relevant Xen code.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
@ 2014-06-23 14:13         ` Daniel Kiper
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 14:13 UTC (permalink / raw)
  To: Jan Beulich
  Cc: David Vrabel, x86-DgEjT+Ai2ygdnm+yROfE0A,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ, jeremy-TSDbQ3PG+2Y,
	matt.fleming-ral2JQCrhuEAvxtiuMwx3w, tglx-hfZtesqFncYOwBW4kG4KsQ,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w

On Mon, Jun 23, 2014 at 12:00:01PM +0100, Jan Beulich wrote:
> >>> On 23.06.14 at 11:53, <david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org> wrote:
> > On 20/06/14 22:29, Daniel Kiper wrote:
> >> Do not access EFI memory map if it is not available. At least
> >> Xen dom0 EFI implementation does not have an access to it.
> >
> > Could it make one based on the XENMEM_memory_map or
> > XENMEM_machine_memory_map hypercall?
>
> No, the correct operation to implement this and efi_mem_type()
> similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

efi_mem_attributes() is used only on IA-64 arch. So, that is why
I completely removed relevant Xen code.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available
  2014-06-23 11:00       ` Jan Beulich
  (?)
  (?)
@ 2014-06-23 14:13       ` Daniel Kiper
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Kiper @ 2014-06-23 14:13 UTC (permalink / raw)
  To: Jan Beulich
  Cc: mjg59, jeremy, linux-efi, ian.campbell, stefano.stabellini,
	andrew.cooper3, x86, linux-kernel, matt.fleming, David Vrabel,
	hpa, xen-devel, tglx, mingo, boris.ostrovsky, eshelton

On Mon, Jun 23, 2014 at 12:00:01PM +0100, Jan Beulich wrote:
> >>> On 23.06.14 at 11:53, <david.vrabel@citrix.com> wrote:
> > On 20/06/14 22:29, Daniel Kiper wrote:
> >> Do not access EFI memory map if it is not available. At least
> >> Xen dom0 EFI implementation does not have an access to it.
> >
> > Could it make one based on the XENMEM_memory_map or
> > XENMEM_machine_memory_map hypercall?
>
> No, the correct operation to implement this and efi_mem_type()
> similar function is XEN_FW_EFI_INFO, index XEN_FW_EFI_MEM_INFO.

efi_mem_attributes() is used only on IA-64 arch. So, that is why
I completely removed relevant Xen code.

Daniel

^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-24 17:56         ` Luck, Tony
  0 siblings, 0 replies; 51+ messages in thread
From: Luck, Tony @ 2014-06-24 17:56 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: andrew.cooper3, david.vrabel, ian.campbell, stefano.stabellini,
	jeremy, Fleming, Matt, x86, tglx, xen-devel, boris.ostrovsky,
	konrad.wilk, eshelton, mingo, mjg59, linux-efi, linux-kernel,
	hpa, Yu, Fenghua, linux-ia64

> I am CC'ing IA-64 guys.

The *_unmap() functions are no-op on ia64 - because we have mappings for everything all the time
- the *_map() functions just need to compute the proper address to use to get the right attributes
(so we don't mix and match cacheable and uncachable access to the same address). But there is
nothing to tear down afterwards.

I do tend to agree with Daniel that is seems odd to setup the mapping with one class of function
and then tear it down with another.

-Tony


^ permalink raw reply	[flat|nested] 51+ messages in thread

* RE: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
@ 2014-06-24 17:56         ` Luck, Tony
  0 siblings, 0 replies; 51+ messages in thread
From: Luck, Tony @ 2014-06-24 17:56 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: andrew.cooper3-Sxgqhf6Nn4DQT0dZR+AlfA,
	david.vrabel-Sxgqhf6Nn4DQT0dZR+AlfA,
	ian.campbell-Sxgqhf6Nn4DQT0dZR+AlfA,
	stefano.stabellini-mvvWK6WmYclDPfheJLI6IQ, jeremy-TSDbQ3PG+2Y,
	Fleming, Matt, x86-DgEjT+Ai2ygdnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b,
	boris.ostrovsky-QHcLZuEGTsvQT0dZR+AlfA,
	konrad.wilk-QHcLZuEGTsvQT0dZR+AlfA,
	eshelton-e+AXbWqSrlAAvxtiuMwx3w, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	Yu, Fenghua

> I am CC'ing IA-64 guys.

The *_unmap() functions are no-op on ia64 - because we have mappings for everything all the time
- the *_map() functions just need to compute the proper address to use to get the right attributes
(so we don't mix and match cacheable and uncachable access to the same address). But there is
nothing to tear down afterwards.

I do tend to agree with Daniel that is seems odd to setup the mapping with one class of function
and then tear it down with another.

-Tony

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*()
  2014-06-23 13:54       ` Daniel Kiper
  (?)
  (?)
@ 2014-06-24 17:56       ` Luck, Tony
  -1 siblings, 0 replies; 51+ messages in thread
From: Luck, Tony @ 2014-06-24 17:56 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: mjg59, jeremy, Fleming, Matt, linux-ia64, ian.campbell,
	stefano.stabellini, linux-efi, andrew.cooper3, x86, linux-kernel,
	Yu, Fenghua, mingo, david.vrabel, hpa, xen-devel, tglx,
	boris.ostrovsky, eshelton@pobox.com

> I am CC'ing IA-64 guys.

The *_unmap() functions are no-op on ia64 - because we have mappings for everything all the time
- the *_map() functions just need to compute the proper address to use to get the right attributes
(so we don't mix and match cacheable and uncachable access to the same address). But there is
nothing to tear down afterwards.

I do tend to agree with Daniel that is seems odd to setup the mapping with one class of function
and then tear it down with another.

-Tony

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2014-06-24 17:56 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-20 21:29 [PATCH v6 0/9] xen: Add EFI support Daniel Kiper
2014-06-20 21:29 ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 1/9] efi: Use early_mem*() instead of early_io*() Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper
2014-06-23  7:19   ` Jan Beulich
2014-06-23  7:19     ` Jan Beulich
2014-06-23 13:54     ` Daniel Kiper
2014-06-23 13:54       ` Daniel Kiper
2014-06-24 17:56       ` Luck, Tony
2014-06-24 17:56         ` Luck, Tony
2014-06-24 17:56       ` Luck, Tony
2014-06-23 13:54     ` Daniel Kiper
2014-06-23  7:19   ` Jan Beulich
2014-06-20 21:29 ` [PATCH v6 2/9] arch/x86: Do not access EFI memory map if it is not available Daniel Kiper
2014-06-23  9:53   ` David Vrabel
2014-06-23  9:53     ` David Vrabel
2014-06-23 11:00     ` Jan Beulich
2014-06-23 11:00     ` Jan Beulich
2014-06-23 11:00       ` Jan Beulich
2014-06-23 14:13       ` Daniel Kiper
2014-06-23 14:13         ` Daniel Kiper
2014-06-23 14:13       ` Daniel Kiper
2014-06-23  9:53   ` David Vrabel
2014-06-20 21:29 ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 3/9] efi: Introduce EFI_PARAVIRT flag Daniel Kiper
2014-06-20 21:29 ` Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 4/9] arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 5/9] arch/x86: Remove redundant set_bit(EFI_MEMMAP) call Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 6/9] xen: Define EFI related stuff Daniel Kiper
2014-06-20 21:29 ` Daniel Kiper
2014-06-23  9:50   ` David Vrabel
2014-06-23  9:50   ` David Vrabel
2014-06-23  9:50     ` David Vrabel
2014-06-20 21:29 ` [PATCH v6 7/9] xen: Put EFI machinery in place Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper
2014-06-21 14:53   ` Stefano Stabellini
2014-06-21 14:53   ` Stefano Stabellini
2014-06-21 14:53     ` Stefano Stabellini
2014-06-23  9:57   ` [Xen-devel] " David Vrabel
2014-06-23  9:57     ` David Vrabel
2014-06-23 13:57     ` Daniel Kiper
2014-06-23 13:57       ` Daniel Kiper
2014-06-23 13:57     ` Daniel Kiper
2014-06-23  9:57   ` David Vrabel
2014-06-20 21:29 ` [PATCH v6 8/9] arch/x86: Replace plain strings with constants Daniel Kiper
2014-06-20 21:29 ` Daniel Kiper
2014-06-20 21:29 ` [PATCH v6 9/9] arch/x86: Remove efi_set_rtc_mmss() Daniel Kiper
2014-06-20 21:29   ` Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.