All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/14] kexec kernel efi runtime support
@ 2013-12-16  9:30 ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Here is the V6 patchset for supporting kexec kernel efi runtime.
Per pervious discussion I pass the 1st kernel efi runtime mapping
via setup_data to 2nd kernel. Besides of the runtime mapping
info I also pass the fw_vendor, runtime, config table, smbios
physical address in setup_data. EFI spec mentioned fw_vendor,
runtime, config table addresses will be converted to virt address
after entering virtual mode, but we will use it as physical address
in efi_init. For smbios EFI spec did not mention about the address
updating, but during my test on a HP workstation, the bios will
convert it to Virt addr, thus pass it in setup_data as well.

For fw_vendor, runtime, config table, I export them in /sys/firmware/
efi/, smbios is already in /sys/firmware/efi/systab.

For efi runtime mapping I add a new directory /sys/firmware/efi/
runtime-map/ like below
[dave@darkstar ~]$ tree /sys/firmware/efi/runtime-map/
/sys/firmware/efi/runtime-map/
|__ 0
|   |__ attribute
|   |__ num_pages
|   |__ phys_addr
|   |__ type
|   |__ virt_addr
|__ 1
[snip]

kexec-tools will assemble them as setup_data and pass to 2nd kernel.
I will send userspace patches as well.

Limitation is I only write support for x86_64, test on below machines:
Lenovo thinkpad t420
Dell inspiron 14 - 3421
HP Z420 workstation
Qemu + OVMF

The patches are based on linus tree + matt's efi master tree

Changes from v1:
add one flag in xloadflags, so kexec-tools can safely load old kernel
without efi support.
coding style fixes
function name for map phys_addr to fixed virt_addr
Add ABI documentation for sysfs files

Changes from v2:
01/09: a new patch to remove unused variables in __map_region function
       catched by Toshi Kani
09/09: a new patch to export x86 boot_params to sysfs instead of use
       debugfs files
Matt: reuse __map_region instead do same thing in another function.
      add a wrapper function efi_map_region_fixed [02/09]
      check return value of krealloc
      sysfs dir name s/efi-runtime-map/runtime-map [06/09]
      use desc_size in efi_runtime_map
      for the xloadflags defination: +&& defined(CONFIG_KEXEC)
Greg: sysfs : one file one value for fw_vendor, runtime, tables. [05/09]
      Document them in ABI testing
HPA:  Document the new xloadflag
Also there's other function cleanup and improvement for error handling.

Changes from v3:
Greg: sysfs code move to use __ATTR_RO and attr_group
Boris: comments and code alignment

Added 3 new patches below
10-print-efi-runtime-memmap.patch
  - 10/12: print only runtime ranges in case EFI_DEBUG printing
11-reserve-setup-data-late.patch
  - fix a bug of kdump kernel, move function for reserving setup data
    ranges late after parsing memmap= cmdline params because kdump kernel
    will pass exact memmap late.
12-x86-kdebugfs-use-ioremap.patch
  - fix a bug of x86/kernel/kdebugfs.c, use ioremap instead of __va for
    low mem because __va does not work for exact memmap=

Changes from V4:
 - variable efi_setup in 09/14 is changed to the physical address instead of the virtual address
because it will be not iounmapped until entering virtual mode, it's too long and could cause
leak.
 - sparse warnings fixes (Matt):
   Added 2 new patches to addressing sparse warnings:
   01/14: x86-mm-sparse-warning-fix-for-early_memremap.patch
   02/14: efi-use-early_memremap-and-early_memunmap.patch
 - krealloc fixes (Boris)
 - rebase on top of Linus tree + Matt's efi master tree (Boris)
 - a lot of documention/spelling fixes (Boris)
 - share function save_runtime_map in 1st/2nd kernel code (Matt)
 - style and other fixes detail see the patch changelog themselves.

Changes from V5:
 - add efi_runtime_map_setup() and remove the extern variables thus other
   arches can reuse the runtime_map exporting code. (Matt)
 - check efi_reuse_config return value. (Matt)
 - move parse_efi_setup to efi_$(BITS).c (Boris)
 - call efi_runtime_map_init in efisubsys_init (Boris)
 - save_runtime_map cleanup. (Boris)

To Mark Salter:
Mark, I still sent the 1/14 memremap patch here for integrity. But feel
free to take it in your series.

The patches stay in kexec-efi-testing branch of below repo for testing:
https://github.com/daveyoung/linux.git

Dave Young (14):
  x86/mm: sparse warning fix for early_memremap
  efi: Use early_memremap and early_memunmap to fix sparse warnings
  efi: remove unused variables in __map_region
  efi: add a wrapper function efi_map_region_fixed
  efi: reserve boot service fix
  efi: cleanup efi_enter_virtual_mode function
  efi: export more efi table variable to sysfs
  efi: export efi runtime memory mapping to sysfs
  efi: passing kexec necessary efi data via setup_data
  efi: only print saved efi runtime maps instead of all memmap ranges
    for kexec
  x86: add xloadflags bit for efi runtime support on kexec
  x86: export x86 boot_params to sysfs
  x86: reserve setup_data ranges late after parsing memmap cmdline
  x86: kdebugfs do not use __va for getting setup_data virt addr

 Documentation/ABI/testing/sysfs-firmware-efi       |  20 ++
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 ++
 Documentation/x86/boot.txt                         |   3 +
 arch/x86/boot/header.S                             |   9 +-
 arch/x86/include/asm/efi.h                         |  13 +
 arch/x86/include/asm/io.h                          |   3 +-
 arch/x86/include/uapi/asm/bootparam.h              |   2 +
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/kdebugfs.c                         |  35 +-
 arch/x86/kernel/ksysfs.c                           | 339 ++++++++++++++++++
 arch/x86/kernel/setup.c                            |   7 +-
 arch/x86/mm/ioremap.c                              |  10 +-
 arch/x86/platform/efi/efi.c                        | 381 ++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c                     |   3 +
 arch/x86/platform/efi/efi_64.c                     |  21 +-
 drivers/firmware/efi/Kconfig                       |  11 +
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |  51 ++-
 drivers/firmware/efi/runtime-map.c                 | 181 ++++++++++
 include/linux/efi.h                                |   8 +
 21 files changed, 1048 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c
 create mode 100644 drivers/firmware/efi/runtime-map.c

-- 
1.8.3.1


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

* [PATCH v6 00/14] kexec kernel efi runtime support
@ 2013-12-16  9:30 ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy, toshi.kani-VXdhtT5mjnY,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

Here is the V6 patchset for supporting kexec kernel efi runtime.
Per pervious discussion I pass the 1st kernel efi runtime mapping
via setup_data to 2nd kernel. Besides of the runtime mapping
info I also pass the fw_vendor, runtime, config table, smbios
physical address in setup_data. EFI spec mentioned fw_vendor,
runtime, config table addresses will be converted to virt address
after entering virtual mode, but we will use it as physical address
in efi_init. For smbios EFI spec did not mention about the address
updating, but during my test on a HP workstation, the bios will
convert it to Virt addr, thus pass it in setup_data as well.

For fw_vendor, runtime, config table, I export them in /sys/firmware/
efi/, smbios is already in /sys/firmware/efi/systab.

For efi runtime mapping I add a new directory /sys/firmware/efi/
runtime-map/ like below
[dave@darkstar ~]$ tree /sys/firmware/efi/runtime-map/
/sys/firmware/efi/runtime-map/
|__ 0
|   |__ attribute
|   |__ num_pages
|   |__ phys_addr
|   |__ type
|   |__ virt_addr
|__ 1
[snip]

kexec-tools will assemble them as setup_data and pass to 2nd kernel.
I will send userspace patches as well.

Limitation is I only write support for x86_64, test on below machines:
Lenovo thinkpad t420
Dell inspiron 14 - 3421
HP Z420 workstation
Qemu + OVMF

The patches are based on linus tree + matt's efi master tree

Changes from v1:
add one flag in xloadflags, so kexec-tools can safely load old kernel
without efi support.
coding style fixes
function name for map phys_addr to fixed virt_addr
Add ABI documentation for sysfs files

Changes from v2:
01/09: a new patch to remove unused variables in __map_region function
       catched by Toshi Kani
09/09: a new patch to export x86 boot_params to sysfs instead of use
       debugfs files
Matt: reuse __map_region instead do same thing in another function.
      add a wrapper function efi_map_region_fixed [02/09]
      check return value of krealloc
      sysfs dir name s/efi-runtime-map/runtime-map [06/09]
      use desc_size in efi_runtime_map
      for the xloadflags defination: +&& defined(CONFIG_KEXEC)
Greg: sysfs : one file one value for fw_vendor, runtime, tables. [05/09]
      Document them in ABI testing
HPA:  Document the new xloadflag
Also there's other function cleanup and improvement for error handling.

Changes from v3:
Greg: sysfs code move to use __ATTR_RO and attr_group
Boris: comments and code alignment

Added 3 new patches below
10-print-efi-runtime-memmap.patch
  - 10/12: print only runtime ranges in case EFI_DEBUG printing
11-reserve-setup-data-late.patch
  - fix a bug of kdump kernel, move function for reserving setup data
    ranges late after parsing memmap= cmdline params because kdump kernel
    will pass exact memmap late.
12-x86-kdebugfs-use-ioremap.patch
  - fix a bug of x86/kernel/kdebugfs.c, use ioremap instead of __va for
    low mem because __va does not work for exact memmap=

Changes from V4:
 - variable efi_setup in 09/14 is changed to the physical address instead of the virtual address
because it will be not iounmapped until entering virtual mode, it's too long and could cause
leak.
 - sparse warnings fixes (Matt):
   Added 2 new patches to addressing sparse warnings:
   01/14: x86-mm-sparse-warning-fix-for-early_memremap.patch
   02/14: efi-use-early_memremap-and-early_memunmap.patch
 - krealloc fixes (Boris)
 - rebase on top of Linus tree + Matt's efi master tree (Boris)
 - a lot of documention/spelling fixes (Boris)
 - share function save_runtime_map in 1st/2nd kernel code (Matt)
 - style and other fixes detail see the patch changelog themselves.

Changes from V5:
 - add efi_runtime_map_setup() and remove the extern variables thus other
   arches can reuse the runtime_map exporting code. (Matt)
 - check efi_reuse_config return value. (Matt)
 - move parse_efi_setup to efi_$(BITS).c (Boris)
 - call efi_runtime_map_init in efisubsys_init (Boris)
 - save_runtime_map cleanup. (Boris)

To Mark Salter:
Mark, I still sent the 1/14 memremap patch here for integrity. But feel
free to take it in your series.

The patches stay in kexec-efi-testing branch of below repo for testing:
https://github.com/daveyoung/linux.git

Dave Young (14):
  x86/mm: sparse warning fix for early_memremap
  efi: Use early_memremap and early_memunmap to fix sparse warnings
  efi: remove unused variables in __map_region
  efi: add a wrapper function efi_map_region_fixed
  efi: reserve boot service fix
  efi: cleanup efi_enter_virtual_mode function
  efi: export more efi table variable to sysfs
  efi: export efi runtime memory mapping to sysfs
  efi: passing kexec necessary efi data via setup_data
  efi: only print saved efi runtime maps instead of all memmap ranges
    for kexec
  x86: add xloadflags bit for efi runtime support on kexec
  x86: export x86 boot_params to sysfs
  x86: reserve setup_data ranges late after parsing memmap cmdline
  x86: kdebugfs do not use __va for getting setup_data virt addr

 Documentation/ABI/testing/sysfs-firmware-efi       |  20 ++
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 ++
 Documentation/x86/boot.txt                         |   3 +
 arch/x86/boot/header.S                             |   9 +-
 arch/x86/include/asm/efi.h                         |  13 +
 arch/x86/include/asm/io.h                          |   3 +-
 arch/x86/include/uapi/asm/bootparam.h              |   2 +
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/kdebugfs.c                         |  35 +-
 arch/x86/kernel/ksysfs.c                           | 339 ++++++++++++++++++
 arch/x86/kernel/setup.c                            |   7 +-
 arch/x86/mm/ioremap.c                              |  10 +-
 arch/x86/platform/efi/efi.c                        | 381 ++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c                     |   3 +
 arch/x86/platform/efi/efi_64.c                     |  21 +-
 drivers/firmware/efi/Kconfig                       |  11 +
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |  51 ++-
 drivers/firmware/efi/runtime-map.c                 | 181 ++++++++++
 include/linux/efi.h                                |   8 +
 21 files changed, 1048 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c
 create mode 100644 drivers/firmware/efi/runtime-map.c

-- 
1.8.3.1

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

* [PATCH v6 00/14] kexec kernel efi runtime support
@ 2013-12-16  9:30 ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Here is the V6 patchset for supporting kexec kernel efi runtime.
Per pervious discussion I pass the 1st kernel efi runtime mapping
via setup_data to 2nd kernel. Besides of the runtime mapping
info I also pass the fw_vendor, runtime, config table, smbios
physical address in setup_data. EFI spec mentioned fw_vendor,
runtime, config table addresses will be converted to virt address
after entering virtual mode, but we will use it as physical address
in efi_init. For smbios EFI spec did not mention about the address
updating, but during my test on a HP workstation, the bios will
convert it to Virt addr, thus pass it in setup_data as well.

For fw_vendor, runtime, config table, I export them in /sys/firmware/
efi/, smbios is already in /sys/firmware/efi/systab.

For efi runtime mapping I add a new directory /sys/firmware/efi/
runtime-map/ like below
[dave@darkstar ~]$ tree /sys/firmware/efi/runtime-map/
/sys/firmware/efi/runtime-map/
|__ 0
|   |__ attribute
|   |__ num_pages
|   |__ phys_addr
|   |__ type
|   |__ virt_addr
|__ 1
[snip]

kexec-tools will assemble them as setup_data and pass to 2nd kernel.
I will send userspace patches as well.

Limitation is I only write support for x86_64, test on below machines:
Lenovo thinkpad t420
Dell inspiron 14 - 3421
HP Z420 workstation
Qemu + OVMF

The patches are based on linus tree + matt's efi master tree

Changes from v1:
add one flag in xloadflags, so kexec-tools can safely load old kernel
without efi support.
coding style fixes
function name for map phys_addr to fixed virt_addr
Add ABI documentation for sysfs files

Changes from v2:
01/09: a new patch to remove unused variables in __map_region function
       catched by Toshi Kani
09/09: a new patch to export x86 boot_params to sysfs instead of use
       debugfs files
Matt: reuse __map_region instead do same thing in another function.
      add a wrapper function efi_map_region_fixed [02/09]
      check return value of krealloc
      sysfs dir name s/efi-runtime-map/runtime-map [06/09]
      use desc_size in efi_runtime_map
      for the xloadflags defination: +&& defined(CONFIG_KEXEC)
Greg: sysfs : one file one value for fw_vendor, runtime, tables. [05/09]
      Document them in ABI testing
HPA:  Document the new xloadflag
Also there's other function cleanup and improvement for error handling.

Changes from v3:
Greg: sysfs code move to use __ATTR_RO and attr_group
Boris: comments and code alignment

Added 3 new patches below
10-print-efi-runtime-memmap.patch
  - 10/12: print only runtime ranges in case EFI_DEBUG printing
11-reserve-setup-data-late.patch
  - fix a bug of kdump kernel, move function for reserving setup data
    ranges late after parsing memmap= cmdline params because kdump kernel
    will pass exact memmap late.
12-x86-kdebugfs-use-ioremap.patch
  - fix a bug of x86/kernel/kdebugfs.c, use ioremap instead of __va for
    low mem because __va does not work for exact memmap=

Changes from V4:
 - variable efi_setup in 09/14 is changed to the physical address instead of the virtual address
because it will be not iounmapped until entering virtual mode, it's too long and could cause
leak.
 - sparse warnings fixes (Matt):
   Added 2 new patches to addressing sparse warnings:
   01/14: x86-mm-sparse-warning-fix-for-early_memremap.patch
   02/14: efi-use-early_memremap-and-early_memunmap.patch
 - krealloc fixes (Boris)
 - rebase on top of Linus tree + Matt's efi master tree (Boris)
 - a lot of documention/spelling fixes (Boris)
 - share function save_runtime_map in 1st/2nd kernel code (Matt)
 - style and other fixes detail see the patch changelog themselves.

Changes from V5:
 - add efi_runtime_map_setup() and remove the extern variables thus other
   arches can reuse the runtime_map exporting code. (Matt)
 - check efi_reuse_config return value. (Matt)
 - move parse_efi_setup to efi_$(BITS).c (Boris)
 - call efi_runtime_map_init in efisubsys_init (Boris)
 - save_runtime_map cleanup. (Boris)

To Mark Salter:
Mark, I still sent the 1/14 memremap patch here for integrity. But feel
free to take it in your series.

The patches stay in kexec-efi-testing branch of below repo for testing:
https://github.com/daveyoung/linux.git

Dave Young (14):
  x86/mm: sparse warning fix for early_memremap
  efi: Use early_memremap and early_memunmap to fix sparse warnings
  efi: remove unused variables in __map_region
  efi: add a wrapper function efi_map_region_fixed
  efi: reserve boot service fix
  efi: cleanup efi_enter_virtual_mode function
  efi: export more efi table variable to sysfs
  efi: export efi runtime memory mapping to sysfs
  efi: passing kexec necessary efi data via setup_data
  efi: only print saved efi runtime maps instead of all memmap ranges
    for kexec
  x86: add xloadflags bit for efi runtime support on kexec
  x86: export x86 boot_params to sysfs
  x86: reserve setup_data ranges late after parsing memmap cmdline
  x86: kdebugfs do not use __va for getting setup_data virt addr

 Documentation/ABI/testing/sysfs-firmware-efi       |  20 ++
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 ++
 Documentation/x86/boot.txt                         |   3 +
 arch/x86/boot/header.S                             |   9 +-
 arch/x86/include/asm/efi.h                         |  13 +
 arch/x86/include/asm/io.h                          |   3 +-
 arch/x86/include/uapi/asm/bootparam.h              |   2 +
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/kdebugfs.c                         |  35 +-
 arch/x86/kernel/ksysfs.c                           | 339 ++++++++++++++++++
 arch/x86/kernel/setup.c                            |   7 +-
 arch/x86/mm/ioremap.c                              |  10 +-
 arch/x86/platform/efi/efi.c                        | 381 ++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c                     |   3 +
 arch/x86/platform/efi/efi_64.c                     |  21 +-
 drivers/firmware/efi/Kconfig                       |  11 +
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |  51 ++-
 drivers/firmware/efi/runtime-map.c                 | 181 ++++++++++
 include/linux/efi.h                                |   8 +
 21 files changed, 1048 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c
 create mode 100644 drivers/firmware/efi/runtime-map.c

-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 01/14] x86/mm: sparse warning fix for early_memremap
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

There's a lot of sparse warnings for code like below:
void *a = early_memremap(phys_addr, size);

early_memremap intend to map kernel memory with ioremap facility, the return
pointer should be a kernel ram pointer instead of iomem one.

For making the function clearer and supressing sparse warnings this patch
do below two things:
1. cast to (__force void *) for the return value of early_memremap
2. add early_memunmap function and pass (__force void __iomem *) to iounmap

>From Boris:
> Ingo told me yesterday, it makes sense too. I'd guess we can try it.
> FWIW, all callers of early_memremap use the memory they get remapped as
> normal memory so we should be safe.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/io.h |  3 ++-
 arch/x86/mm/ioremap.c     | 10 +++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 34f69cb..1db414f 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -325,9 +325,10 @@ extern void early_ioremap_init(void);
 extern void early_ioremap_reset(void);
 extern void __iomem *early_ioremap(resource_size_t phys_addr,
 				   unsigned long size);
-extern void __iomem *early_memremap(resource_size_t phys_addr,
+extern void *early_memremap(resource_size_t phys_addr,
 				    unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
+extern void early_memunmap(void *addr, unsigned long size);
 extern void fixup_early_ioremap(void);
 extern bool is_early_ioremap_ptep(pte_t *ptep);
 
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 799580c..bbb4504 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -562,10 +562,9 @@ early_ioremap(resource_size_t phys_addr, unsigned long size)
 }
 
 /* Remap memory */
-void __init __iomem *
-early_memremap(resource_size_t phys_addr, unsigned long size)
+void __init *early_memremap(resource_size_t phys_addr, unsigned long size)
 {
-	return __early_ioremap(phys_addr, size, PAGE_KERNEL);
+	return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL);
 }
 
 void __init early_iounmap(void __iomem *addr, unsigned long size)
@@ -620,3 +619,8 @@ void __init early_iounmap(void __iomem *addr, unsigned long size)
 	}
 	prev_map[slot] = NULL;
 }
+
+void __init early_memunmap(void *addr, unsigned long size)
+{
+	early_iounmap((__force void __iomem *)addr, size);
+}
-- 
1.8.3.1


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

* [PATCH v6 01/14] x86/mm: sparse warning fix for early_memremap
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

There's a lot of sparse warnings for code like below:
void *a = early_memremap(phys_addr, size);

early_memremap intend to map kernel memory with ioremap facility, the return
pointer should be a kernel ram pointer instead of iomem one.

For making the function clearer and supressing sparse warnings this patch
do below two things:
1. cast to (__force void *) for the return value of early_memremap
2. add early_memunmap function and pass (__force void __iomem *) to iounmap

From Boris:
> Ingo told me yesterday, it makes sense too. I'd guess we can try it.
> FWIW, all callers of early_memremap use the memory they get remapped as
> normal memory so we should be safe.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/io.h |  3 ++-
 arch/x86/mm/ioremap.c     | 10 +++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 34f69cb..1db414f 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -325,9 +325,10 @@ extern void early_ioremap_init(void);
 extern void early_ioremap_reset(void);
 extern void __iomem *early_ioremap(resource_size_t phys_addr,
 				   unsigned long size);
-extern void __iomem *early_memremap(resource_size_t phys_addr,
+extern void *early_memremap(resource_size_t phys_addr,
 				    unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
+extern void early_memunmap(void *addr, unsigned long size);
 extern void fixup_early_ioremap(void);
 extern bool is_early_ioremap_ptep(pte_t *ptep);
 
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 799580c..bbb4504 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -562,10 +562,9 @@ early_ioremap(resource_size_t phys_addr, unsigned long size)
 }
 
 /* Remap memory */
-void __init __iomem *
-early_memremap(resource_size_t phys_addr, unsigned long size)
+void __init *early_memremap(resource_size_t phys_addr, unsigned long size)
 {
-	return __early_ioremap(phys_addr, size, PAGE_KERNEL);
+	return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL);
 }
 
 void __init early_iounmap(void __iomem *addr, unsigned long size)
@@ -620,3 +619,8 @@ void __init early_iounmap(void __iomem *addr, unsigned long size)
 	}
 	prev_map[slot] = NULL;
 }
+
+void __init early_memunmap(void *addr, unsigned long size)
+{
+	early_iounmap((__force void __iomem *)addr, size);
+}
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 02/14] efi: Use early_memremap and early_memunmap to fix sparse warnings
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

There are a lot of sparse warnings for early_memremap and early_ioummap
in arch/x86/platform/efi/efi.c and drivers/firmware/efi/efi.c.

early_memremap is for mapping kernel memory instead of io memory, but
the early_memremap returns void __iomem pointer and early_iounmap accepts
__iomem pointer as argument. Sparse checking is not happy with the mismatch.

Also there's several early_ioremap callbacks which need to be changed to
early_memremap because they are actually mapping kernel memory.

Previous patch fixed the early_memremap function to return a normal pointer
instead of __iomem pointer. Also introduced a new function early_memunmap
which accept normal pointer as the argument.

This patch is fixing the sparse warnings as below:
1. use early_memremap instead of early_ioremap
2. use early_memunmap instead of early_iounmap

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi.c | 20 ++++++++++----------
 drivers/firmware/efi/efi.c  |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f8ec4da..ef471d5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -456,7 +456,7 @@ void __init efi_unmap_memmap(void)
 {
 	clear_bit(EFI_MEMMAP, &x86_efi_facility);
 	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;
 	}
 }
@@ -493,7 +493,7 @@ static int __init efi_systab_init(void *phys)
 		efi_system_table_64_t *systab64;
 		u64 tmp = 0;
 
-		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");
@@ -524,7 +524,7 @@ static int __init efi_systab_init(void *phys)
 		efi_systab.tables = systab64->tables;
 		tmp |= systab64->tables;
 
-		early_iounmap(systab64, sizeof(*systab64));
+		early_memunmap(systab64, sizeof(*systab64));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -534,7 +534,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");
@@ -555,7 +555,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;
@@ -586,7 +586,7 @@ static int __init efi_runtime_init(void)
 	 * address of several of the EFI runtime functions, needed to
 	 * set the firmware into virtual mode.
 	 */
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 				sizeof(efi_runtime_services_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -606,7 +606,7 @@ static int __init efi_runtime_init(void)
 	 * virtual mode.
 	 */
 	efi.get_time = phys_efi_get_time;
-	early_iounmap(runtime, sizeof(efi_runtime_services_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_t));
 
 	return 0;
 }
@@ -614,7 +614,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");
@@ -656,14 +656,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 2e2fbde..b716a66 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -253,7 +253,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;
 			}
@@ -269,6 +269,6 @@ 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);
 	return 0;
 }
-- 
1.8.3.1


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

* [PATCH v6 02/14] efi: Use early_memremap and early_memunmap to fix sparse warnings
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

There are a lot of sparse warnings for early_memremap and early_ioummap
in arch/x86/platform/efi/efi.c and drivers/firmware/efi/efi.c.

early_memremap is for mapping kernel memory instead of io memory, but
the early_memremap returns void __iomem pointer and early_iounmap accepts
__iomem pointer as argument. Sparse checking is not happy with the mismatch.

Also there's several early_ioremap callbacks which need to be changed to
early_memremap because they are actually mapping kernel memory.

Previous patch fixed the early_memremap function to return a normal pointer
instead of __iomem pointer. Also introduced a new function early_memunmap
which accept normal pointer as the argument.

This patch is fixing the sparse warnings as below:
1. use early_memremap instead of early_ioremap
2. use early_memunmap instead of early_iounmap

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi.c | 20 ++++++++++----------
 drivers/firmware/efi/efi.c  |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f8ec4da..ef471d5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -456,7 +456,7 @@ void __init efi_unmap_memmap(void)
 {
 	clear_bit(EFI_MEMMAP, &x86_efi_facility);
 	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;
 	}
 }
@@ -493,7 +493,7 @@ static int __init efi_systab_init(void *phys)
 		efi_system_table_64_t *systab64;
 		u64 tmp = 0;
 
-		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");
@@ -524,7 +524,7 @@ static int __init efi_systab_init(void *phys)
 		efi_systab.tables = systab64->tables;
 		tmp |= systab64->tables;
 
-		early_iounmap(systab64, sizeof(*systab64));
+		early_memunmap(systab64, sizeof(*systab64));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -534,7 +534,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");
@@ -555,7 +555,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;
@@ -586,7 +586,7 @@ static int __init efi_runtime_init(void)
 	 * address of several of the EFI runtime functions, needed to
 	 * set the firmware into virtual mode.
 	 */
-	runtime = early_ioremap((unsigned long)efi.systab->runtime,
+	runtime = early_memremap((unsigned long)efi.systab->runtime,
 				sizeof(efi_runtime_services_t));
 	if (!runtime) {
 		pr_err("Could not map the runtime service table!\n");
@@ -606,7 +606,7 @@ static int __init efi_runtime_init(void)
 	 * virtual mode.
 	 */
 	efi.get_time = phys_efi_get_time;
-	early_iounmap(runtime, sizeof(efi_runtime_services_t));
+	early_memunmap(runtime, sizeof(efi_runtime_services_t));
 
 	return 0;
 }
@@ -614,7 +614,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");
@@ -656,14 +656,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 2e2fbde..b716a66 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -253,7 +253,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;
 			}
@@ -269,6 +269,6 @@ 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);
 	return 0;
 }
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 03/14] efi: remove unused variables in __map_region
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

variables size and end is useless in this function, thus remove them.

Reported-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi_64.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index bf286c3..c5a6491 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -148,15 +148,11 @@ void efi_setup_page_tables(void)
 static void __init __map_region(efi_memory_desc_t *md, u64 va)
 {
 	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
-	unsigned long pf = 0, size;
-	u64 end;
+	unsigned long pf = 0;
 
 	if (!(md->attribute & EFI_MEMORY_WB))
 		pf |= _PAGE_PCD;
 
-	size = md->num_pages << PAGE_SHIFT;
-	end  = va + size;
-
 	if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf))
 		pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
 			   md->phys_addr, va);
-- 
1.8.3.1


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

* [PATCH v6 03/14] efi: remove unused variables in __map_region
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

variables size and end is useless in this function, thus remove them.

Reported-by: Toshi Kani <toshi.kani@hp.com>
Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi_64.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index bf286c3..c5a6491 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -148,15 +148,11 @@ void efi_setup_page_tables(void)
 static void __init __map_region(efi_memory_desc_t *md, u64 va)
 {
 	pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd);
-	unsigned long pf = 0, size;
-	u64 end;
+	unsigned long pf = 0;
 
 	if (!(md->attribute & EFI_MEMORY_WB))
 		pf |= _PAGE_PCD;
 
-	size = md->num_pages << PAGE_SHIFT;
-	end  = va + size;
-
 	if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf))
 		pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n",
 			   md->phys_addr, va);
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 04/14] efi: add a wrapper function efi_map_region_fixed
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Kexec kernel will use saved runtime virtual mapping, so add a
new function efi_map_region_fixed for directly mapping a md
to md->virt.

The md is passed in from 1st kernel, the virtual addr is
saved in md->virt_addr.

Matt: coding style
      reuse __map_region
Boris: Strenthen comment lines to 80 cols.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/efi.h     |  1 +
 arch/x86/platform/efi/efi_32.c |  2 ++
 arch/x86/platform/efi/efi_64.c | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 89a05b0..9fbaeb2 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -128,6 +128,7 @@ extern void efi_call_phys_epilog(void);
 extern void efi_unmap_memmap(void);
 extern void efi_memory_uc(u64 addr, unsigned long size);
 extern void __init efi_map_region(efi_memory_desc_t *md);
+extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
 extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index e94557c..7b3ec6e 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -47,6 +47,8 @@ void __init efi_map_region(efi_memory_desc_t *md)
 	old_map_region(md);
 }
 
+void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+
 void efi_call_phys_prelog(void)
 {
 	struct desc_ptr gdt_descr;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index c5a6491..ff08cb1 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -199,6 +199,16 @@ void __init efi_map_region(efi_memory_desc_t *md)
 	md->virt_addr = efi_va;
 }
 
+/*
+ * kexec kernel will use efi_map_region_fixed to map efi runtime memory ranges.
+ * md->virt_addr is the original virtual address which had been mapped in kexec
+ * 1st kernel.
+ */
+void __init efi_map_region_fixed(efi_memory_desc_t *md)
+{
+	__map_region(md, md->virt_addr);
+}
+
 void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 				 u32 type, u64 attribute)
 {
-- 
1.8.3.1


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

* [PATCH v6 04/14] efi: add a wrapper function efi_map_region_fixed
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Kexec kernel will use saved runtime virtual mapping, so add a
new function efi_map_region_fixed for directly mapping a md
to md->virt.

The md is passed in from 1st kernel, the virtual addr is
saved in md->virt_addr.

Matt: coding style
      reuse __map_region
Boris: Strenthen comment lines to 80 cols.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/efi.h     |  1 +
 arch/x86/platform/efi/efi_32.c |  2 ++
 arch/x86/platform/efi/efi_64.c | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 89a05b0..9fbaeb2 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -128,6 +128,7 @@ extern void efi_call_phys_epilog(void);
 extern void efi_unmap_memmap(void);
 extern void efi_memory_uc(u64 addr, unsigned long size);
 extern void __init efi_map_region(efi_memory_desc_t *md);
+extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
 extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index e94557c..7b3ec6e 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -47,6 +47,8 @@ void __init efi_map_region(efi_memory_desc_t *md)
 	old_map_region(md);
 }
 
+void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+
 void efi_call_phys_prelog(void)
 {
 	struct desc_ptr gdt_descr;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index c5a6491..ff08cb1 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -199,6 +199,16 @@ void __init efi_map_region(efi_memory_desc_t *md)
 	md->virt_addr = efi_va;
 }
 
+/*
+ * kexec kernel will use efi_map_region_fixed to map efi runtime memory ranges.
+ * md->virt_addr is the original virtual address which had been mapped in kexec
+ * 1st kernel.
+ */
+void __init efi_map_region_fixed(efi_memory_desc_t *md)
+{
+	__map_region(md, md->virt_addr);
+}
+
 void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 				 u32 type, u64 attribute)
 {
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 05/14] efi: reserve boot service fix
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Current code check boot service region with kernel text region by:
start+size >= __pa_symbol(_text)
The end of the above region should be start + size - 1 instead.

I see this problem in ovmf + Fedora 19 grub boot:
text start: 1000000 md start: 800000 md size: 800000

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
Acked-by: Toshi Kani <toshi.kani@hp.com>
---
 arch/x86/platform/efi/efi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ef471d5..8a88c68 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -438,7 +438,7 @@ void __init efi_reserve_boot_services(void)
 		 * - Not within any part of the kernel
 		 * - Not the bios reserved area
 		*/
-		if ((start+size >= __pa_symbol(_text)
+		if ((start + size > __pa_symbol(_text)
 				&& start <= __pa_symbol(_end)) ||
 			!e820_all_mapped(start, start+size, E820_RAM) ||
 			memblock_is_region_reserved(start, size)) {
-- 
1.8.3.1


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

* [PATCH v6 05/14] efi: reserve boot service fix
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Current code check boot service region with kernel text region by:
start+size >= __pa_symbol(_text)
The end of the above region should be start + size - 1 instead.

I see this problem in ovmf + Fedora 19 grub boot:
text start: 1000000 md start: 800000 md size: 800000

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
Acked-by: Toshi Kani <toshi.kani@hp.com>
---
 arch/x86/platform/efi/efi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ef471d5..8a88c68 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -438,7 +438,7 @@ void __init efi_reserve_boot_services(void)
 		 * - Not within any part of the kernel
 		 * - Not the bios reserved area
 		*/
-		if ((start+size >= __pa_symbol(_text)
+		if ((start + size > __pa_symbol(_text)
 				&& start <= __pa_symbol(_end)) ||
 			!e820_all_mapped(start, start+size, E820_RAM) ||
 			memblock_is_region_reserved(start, size)) {
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 06/14] efi: cleanup efi_enter_virtual_mode function
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Add two small functions:
efi_merge_regions and efi_map_regions, efi_enter_virtual_mode
calls them instead of embedding two long for loop.

v1->v2:
refresh; coding style fixes.

v2->v3:
Toshi Kani:
remove unused variable
Matt: check return value of krealloc.
v3->v4:
Boris: Stretch comment to 80 cols
fix krealloc bug.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi.c | 123 ++++++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 51 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 8a88c68..7778b5f 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -773,44 +773,12 @@ void __init old_map_region(efi_memory_desc_t *md)
 		       (unsigned long long)md->phys_addr);
 }
 
-/*
- * This function will switch the EFI runtime services to virtual mode.
- * Essentially, we look through the EFI memmap and map every region that
- * has the runtime attribute bit set in its memory descriptor into the
- * ->trampoline_pgd page table using a top-down VA allocation scheme.
- *
- * The old method which used to update that memory descriptor with the
- * virtual address obtained from ioremap() is still supported when the
- * kernel is booted with efi=old_map on its command line. Same old
- * method enabled the runtime services to be called without having to
- * thunk back into physical mode for every invocation.
- *
- * The new method does a pagetable switch in a preemption-safe manner
- * so that we're in a different address space when calling a runtime
- * function. For function arguments passing we do copy the PGDs of the
- * kernel page table into ->trampoline_pgd prior to each call.
- */
-void __init efi_enter_virtual_mode(void)
+/* Merge contiguous regions of the same type and attribute */
+static void __init efi_merge_regions(void)
 {
+	void *p;
 	efi_memory_desc_t *md, *prev_md = NULL;
-	void *p, *new_memmap = NULL;
-	unsigned long size;
-	efi_status_t status;
-	u64 end, systab;
-	int count = 0;
-
-	efi.systab = NULL;
-
-	/*
-	 * We don't do virtual mode, since we don't do runtime services, on
-	 * non-native EFI
-	 */
-	if (!efi_is_native()) {
-		efi_unmap_memmap();
-		return;
-	}
 
-	/* Merge contiguous regions of the same type and attribute */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		u64 prev_size;
 		md = p;
@@ -835,8 +803,19 @@ void __init efi_enter_virtual_mode(void)
 			continue;
 		}
 		prev_md = md;
-
 	}
+}
+
+/*
+ * Map efi memory ranges for runtime serivce and update new_memmap with virtual
+ * addresses.
+ */
+static void * __init efi_map_regions(int *count)
+{
+	efi_memory_desc_t *md;
+	void *p, *tmp, *new_memmap = NULL;
+	unsigned long size;
+	u64 end, systab;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -852,23 +831,68 @@ void __init efi_enter_virtual_mode(void)
 
 		size = md->num_pages << EFI_PAGE_SHIFT;
 		end = md->phys_addr + size;
-
-		systab = (u64) (unsigned long) efi_phys.systab;
+		systab = (u64)(unsigned long)efi_phys.systab;
 		if (md->phys_addr <= systab && systab < end) {
 			systab += md->virt_addr - md->phys_addr;
-
-			efi.systab = (efi_system_table_t *) (unsigned long) systab;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
 		}
 
-		new_memmap = krealloc(new_memmap,
-				      (count + 1) * memmap.desc_size,
-				      GFP_KERNEL);
-		if (!new_memmap)
-			goto err_out;
-
-		memcpy(new_memmap + (count * memmap.desc_size), md,
+		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
+			       GFP_KERNEL);
+		if (!tmp)
+			goto out_krealloc;
+		new_memmap = tmp;
+		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
-		count++;
+		(*count)++;
+	}
+
+	return new_memmap;
+out_krealloc:
+	kfree(new_memmap);
+	return NULL;
+}
+
+/*
+ * This function will switch the EFI runtime services to virtual mode.
+ * Essentially, we look through the EFI memmap and map every region that
+ * has the runtime attribute bit set in its memory descriptor into the
+ * ->trampoline_pgd page table using a top-down VA allocation scheme.
+ *
+ * The old method which used to update that memory descriptor with the
+ * virtual address obtained from ioremap() is still supported when the
+ * kernel is booted with efi=old_map on its command line. Same old
+ * method enabled the runtime services to be called without having to
+ * thunk back into physical mode for every invocation.
+ *
+ * The new method does a pagetable switch in a preemption-safe manner
+ * so that we're in a different address space when calling a runtime
+ * function. For function arguments passing we do copy the PGDs of the
+ * kernel page table into ->trampoline_pgd prior to each call.
+ */
+void __init efi_enter_virtual_mode(void)
+{
+	efi_status_t status;
+	void *new_memmap = NULL;
+	int count = 0;
+
+	efi.systab = NULL;
+
+	/*
+	 * We don't do virtual mode, since we don't do runtime services, on
+	 * non-native EFI
+	 */
+	if (!efi_is_native()) {
+		efi_unmap_memmap();
+		return;
+	}
+
+	efi_merge_regions();
+
+	new_memmap = efi_map_regions(&count);
+	if (!new_memmap) {
+		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+		return;
 	}
 
 	BUG_ON(!efi.systab);
@@ -922,9 +946,6 @@ void __init efi_enter_virtual_mode(void)
 			 0, NULL);
 
 	return;
-
- err_out:
-	pr_err("Error reallocating memory, EFI runtime non-functional!\n");
 }
 
 /*
-- 
1.8.3.1


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

* [PATCH v6 06/14] efi: cleanup efi_enter_virtual_mode function
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

Add two small functions:
efi_merge_regions and efi_map_regions, efi_enter_virtual_mode
calls them instead of embedding two long for loop.

v1->v2:
refresh; coding style fixes.

v2->v3:
Toshi Kani:
remove unused variable
Matt: check return value of krealloc.
v3->v4:
Boris: Stretch comment to 80 cols
fix krealloc bug.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
---
 arch/x86/platform/efi/efi.c | 123 ++++++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 51 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 8a88c68..7778b5f 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -773,44 +773,12 @@ void __init old_map_region(efi_memory_desc_t *md)
 		       (unsigned long long)md->phys_addr);
 }
 
-/*
- * This function will switch the EFI runtime services to virtual mode.
- * Essentially, we look through the EFI memmap and map every region that
- * has the runtime attribute bit set in its memory descriptor into the
- * ->trampoline_pgd page table using a top-down VA allocation scheme.
- *
- * The old method which used to update that memory descriptor with the
- * virtual address obtained from ioremap() is still supported when the
- * kernel is booted with efi=old_map on its command line. Same old
- * method enabled the runtime services to be called without having to
- * thunk back into physical mode for every invocation.
- *
- * The new method does a pagetable switch in a preemption-safe manner
- * so that we're in a different address space when calling a runtime
- * function. For function arguments passing we do copy the PGDs of the
- * kernel page table into ->trampoline_pgd prior to each call.
- */
-void __init efi_enter_virtual_mode(void)
+/* Merge contiguous regions of the same type and attribute */
+static void __init efi_merge_regions(void)
 {
+	void *p;
 	efi_memory_desc_t *md, *prev_md = NULL;
-	void *p, *new_memmap = NULL;
-	unsigned long size;
-	efi_status_t status;
-	u64 end, systab;
-	int count = 0;
-
-	efi.systab = NULL;
-
-	/*
-	 * We don't do virtual mode, since we don't do runtime services, on
-	 * non-native EFI
-	 */
-	if (!efi_is_native()) {
-		efi_unmap_memmap();
-		return;
-	}
 
-	/* Merge contiguous regions of the same type and attribute */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		u64 prev_size;
 		md = p;
@@ -835,8 +803,19 @@ void __init efi_enter_virtual_mode(void)
 			continue;
 		}
 		prev_md = md;
-
 	}
+}
+
+/*
+ * Map efi memory ranges for runtime serivce and update new_memmap with virtual
+ * addresses.
+ */
+static void * __init efi_map_regions(int *count)
+{
+	efi_memory_desc_t *md;
+	void *p, *tmp, *new_memmap = NULL;
+	unsigned long size;
+	u64 end, systab;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -852,23 +831,68 @@ void __init efi_enter_virtual_mode(void)
 
 		size = md->num_pages << EFI_PAGE_SHIFT;
 		end = md->phys_addr + size;
-
-		systab = (u64) (unsigned long) efi_phys.systab;
+		systab = (u64)(unsigned long)efi_phys.systab;
 		if (md->phys_addr <= systab && systab < end) {
 			systab += md->virt_addr - md->phys_addr;
-
-			efi.systab = (efi_system_table_t *) (unsigned long) systab;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
 		}
 
-		new_memmap = krealloc(new_memmap,
-				      (count + 1) * memmap.desc_size,
-				      GFP_KERNEL);
-		if (!new_memmap)
-			goto err_out;
-
-		memcpy(new_memmap + (count * memmap.desc_size), md,
+		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
+			       GFP_KERNEL);
+		if (!tmp)
+			goto out_krealloc;
+		new_memmap = tmp;
+		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
-		count++;
+		(*count)++;
+	}
+
+	return new_memmap;
+out_krealloc:
+	kfree(new_memmap);
+	return NULL;
+}
+
+/*
+ * This function will switch the EFI runtime services to virtual mode.
+ * Essentially, we look through the EFI memmap and map every region that
+ * has the runtime attribute bit set in its memory descriptor into the
+ * ->trampoline_pgd page table using a top-down VA allocation scheme.
+ *
+ * The old method which used to update that memory descriptor with the
+ * virtual address obtained from ioremap() is still supported when the
+ * kernel is booted with efi=old_map on its command line. Same old
+ * method enabled the runtime services to be called without having to
+ * thunk back into physical mode for every invocation.
+ *
+ * The new method does a pagetable switch in a preemption-safe manner
+ * so that we're in a different address space when calling a runtime
+ * function. For function arguments passing we do copy the PGDs of the
+ * kernel page table into ->trampoline_pgd prior to each call.
+ */
+void __init efi_enter_virtual_mode(void)
+{
+	efi_status_t status;
+	void *new_memmap = NULL;
+	int count = 0;
+
+	efi.systab = NULL;
+
+	/*
+	 * We don't do virtual mode, since we don't do runtime services, on
+	 * non-native EFI
+	 */
+	if (!efi_is_native()) {
+		efi_unmap_memmap();
+		return;
+	}
+
+	efi_merge_regions();
+
+	new_memmap = efi_map_regions(&count);
+	if (!new_memmap) {
+		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+		return;
 	}
 
 	BUG_ON(!efi.systab);
@@ -922,9 +946,6 @@ void __init efi_enter_virtual_mode(void)
 			 0, NULL);
 
 	return;
-
- err_out:
-	pr_err("Error reallocating memory, EFI runtime non-functional!\n");
 }
 
 /*
-- 
1.8.3.1

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

* [PATCH v6 06/14] efi: cleanup efi_enter_virtual_mode function
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Add two small functions:
efi_merge_regions and efi_map_regions, efi_enter_virtual_mode
calls them instead of embedding two long for loop.

v1->v2:
refresh; coding style fixes.

v2->v3:
Toshi Kani:
remove unused variable
Matt: check return value of krealloc.
v3->v4:
Boris: Stretch comment to 80 cols
fix krealloc bug.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/platform/efi/efi.c | 123 ++++++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 51 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 8a88c68..7778b5f 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -773,44 +773,12 @@ void __init old_map_region(efi_memory_desc_t *md)
 		       (unsigned long long)md->phys_addr);
 }
 
-/*
- * This function will switch the EFI runtime services to virtual mode.
- * Essentially, we look through the EFI memmap and map every region that
- * has the runtime attribute bit set in its memory descriptor into the
- * ->trampoline_pgd page table using a top-down VA allocation scheme.
- *
- * The old method which used to update that memory descriptor with the
- * virtual address obtained from ioremap() is still supported when the
- * kernel is booted with efi=old_map on its command line. Same old
- * method enabled the runtime services to be called without having to
- * thunk back into physical mode for every invocation.
- *
- * The new method does a pagetable switch in a preemption-safe manner
- * so that we're in a different address space when calling a runtime
- * function. For function arguments passing we do copy the PGDs of the
- * kernel page table into ->trampoline_pgd prior to each call.
- */
-void __init efi_enter_virtual_mode(void)
+/* Merge contiguous regions of the same type and attribute */
+static void __init efi_merge_regions(void)
 {
+	void *p;
 	efi_memory_desc_t *md, *prev_md = NULL;
-	void *p, *new_memmap = NULL;
-	unsigned long size;
-	efi_status_t status;
-	u64 end, systab;
-	int count = 0;
-
-	efi.systab = NULL;
-
-	/*
-	 * We don't do virtual mode, since we don't do runtime services, on
-	 * non-native EFI
-	 */
-	if (!efi_is_native()) {
-		efi_unmap_memmap();
-		return;
-	}
 
-	/* Merge contiguous regions of the same type and attribute */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		u64 prev_size;
 		md = p;
@@ -835,8 +803,19 @@ void __init efi_enter_virtual_mode(void)
 			continue;
 		}
 		prev_md = md;
-
 	}
+}
+
+/*
+ * Map efi memory ranges for runtime serivce and update new_memmap with virtual
+ * addresses.
+ */
+static void * __init efi_map_regions(int *count)
+{
+	efi_memory_desc_t *md;
+	void *p, *tmp, *new_memmap = NULL;
+	unsigned long size;
+	u64 end, systab;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -852,23 +831,68 @@ void __init efi_enter_virtual_mode(void)
 
 		size = md->num_pages << EFI_PAGE_SHIFT;
 		end = md->phys_addr + size;
-
-		systab = (u64) (unsigned long) efi_phys.systab;
+		systab = (u64)(unsigned long)efi_phys.systab;
 		if (md->phys_addr <= systab && systab < end) {
 			systab += md->virt_addr - md->phys_addr;
-
-			efi.systab = (efi_system_table_t *) (unsigned long) systab;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
 		}
 
-		new_memmap = krealloc(new_memmap,
-				      (count + 1) * memmap.desc_size,
-				      GFP_KERNEL);
-		if (!new_memmap)
-			goto err_out;
-
-		memcpy(new_memmap + (count * memmap.desc_size), md,
+		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
+			       GFP_KERNEL);
+		if (!tmp)
+			goto out_krealloc;
+		new_memmap = tmp;
+		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
-		count++;
+		(*count)++;
+	}
+
+	return new_memmap;
+out_krealloc:
+	kfree(new_memmap);
+	return NULL;
+}
+
+/*
+ * This function will switch the EFI runtime services to virtual mode.
+ * Essentially, we look through the EFI memmap and map every region that
+ * has the runtime attribute bit set in its memory descriptor into the
+ * ->trampoline_pgd page table using a top-down VA allocation scheme.
+ *
+ * The old method which used to update that memory descriptor with the
+ * virtual address obtained from ioremap() is still supported when the
+ * kernel is booted with efi=old_map on its command line. Same old
+ * method enabled the runtime services to be called without having to
+ * thunk back into physical mode for every invocation.
+ *
+ * The new method does a pagetable switch in a preemption-safe manner
+ * so that we're in a different address space when calling a runtime
+ * function. For function arguments passing we do copy the PGDs of the
+ * kernel page table into ->trampoline_pgd prior to each call.
+ */
+void __init efi_enter_virtual_mode(void)
+{
+	efi_status_t status;
+	void *new_memmap = NULL;
+	int count = 0;
+
+	efi.systab = NULL;
+
+	/*
+	 * We don't do virtual mode, since we don't do runtime services, on
+	 * non-native EFI
+	 */
+	if (!efi_is_native()) {
+		efi_unmap_memmap();
+		return;
+	}
+
+	efi_merge_regions();
+
+	new_memmap = efi_map_regions(&count);
+	if (!new_memmap) {
+		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+		return;
 	}
 
 	BUG_ON(!efi.systab);
@@ -922,9 +946,6 @@ void __init efi_enter_virtual_mode(void)
 			 0, NULL);
 
 	return;
-
- err_out:
-	pr_err("Error reallocating memory, EFI runtime non-functional!\n");
 }
 
 /*
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 07/14] efi: export more efi table variable to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Export fw_vendor, runtime and config table physical addresses to
/sys/firmware/efi/{fw_vendor,runtime,config_table} because kexec kernel
need them.

>From EFI spec these 3 variables will be updated to
virtual address after entering virtual mode. But
kernel startup code will need the physical address.

changelog:
Greg: add standalone sysfs files instead of add lines to systab
Document them as testing ABI
Greg: use group attrs and is_visible
Boris: align comments lines
Boris: add macros for _show functions, documentation fixes.
Matt: Documentation fixes.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 Documentation/ABI/testing/sysfs-firmware-efi | 20 ++++++++++++++
 arch/x86/platform/efi/efi.c                  |  4 +++
 drivers/firmware/efi/efi.c                   | 41 +++++++++++++++++++++++++++-
 include/linux/efi.h                          |  3 ++
 4 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi b/Documentation/ABI/testing/sysfs-firmware-efi
new file mode 100644
index 0000000..05874da
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi
@@ -0,0 +1,20 @@
+What:		/sys/firmware/efi/fw_vendor
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of firmware vendor field in the
+		EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/runtime
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of runtime service table entry in
+		the EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/config_table
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of config table entry in the EFI
+		system table.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 7778b5f..3e8b760 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -653,6 +653,10 @@ void __init efi_init(void)
 
 	set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
+	efi.config_table = (unsigned long)efi.systab->tables;
+	efi.fw_vendor	 = (unsigned long)efi.systab->fw_vendor;
+	efi.runtime	 = (unsigned long)efi.systab->runtime;
+
 	/*
 	 * Show what we know for posterity
 	 */
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index b716a66..6d0bc52 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -32,6 +32,9 @@ struct efi __read_mostly efi = {
 	.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,
 };
 EXPORT_SYMBOL(efi);
 
@@ -71,13 +74,49 @@ static ssize_t systab_show(struct kobject *kobj,
 static struct kobj_attribute efi_attr_systab =
 			__ATTR(systab, 0400, systab_show, NULL);
 
+#define EFI_FIELD(var) efi.var
+
+#define EFI_ATTR_SHOW(name) \
+static ssize_t name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+{ \
+	return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
+}
+
+EFI_ATTR_SHOW(fw_vendor);
+EFI_ATTR_SHOW(runtime);
+EFI_ATTR_SHOW(config_table);
+
+static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
+static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
+static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
+
 static struct attribute *efi_subsys_attrs[] = {
 	&efi_attr_systab.attr,
-	NULL,	/* maybe more in the future? */
+	&efi_attr_fw_vendor.attr,
+	&efi_attr_runtime.attr,
+	&efi_attr_config_table.attr,
+	NULL,
 };
 
+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;
+
+	return mode;
+}
+
 static struct attribute_group efi_subsys_attr_group = {
 	.attrs = efi_subsys_attrs,
+	.is_visible = efi_attr_is_visible,
 };
 
 static struct efivars generic_efivars;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 49ece2c..988af61 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -556,6 +556,9 @@ extern struct efi {
 	unsigned long hcdp;		/* HCDP table */
 	unsigned long uga;		/* UGA table */
 	unsigned long uv_systab;	/* UV system table */
+	unsigned long fw_vendor;	/* fw_vendor */
+	unsigned long runtime;		/* runtime table */
+	unsigned long config_table;	/* config tables */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
-- 
1.8.3.1


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

* [PATCH v6 07/14] efi: export more efi table variable to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

Export fw_vendor, runtime and config table physical addresses to
/sys/firmware/efi/{fw_vendor,runtime,config_table} because kexec kernel
need them.

>From EFI spec these 3 variables will be updated to
virtual address after entering virtual mode. But
kernel startup code will need the physical address.

changelog:
Greg: add standalone sysfs files instead of add lines to systab
Document them as testing ABI
Greg: use group attrs and is_visible
Boris: align comments lines
Boris: add macros for _show functions, documentation fixes.
Matt: Documentation fixes.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 Documentation/ABI/testing/sysfs-firmware-efi | 20 ++++++++++++++
 arch/x86/platform/efi/efi.c                  |  4 +++
 drivers/firmware/efi/efi.c                   | 41 +++++++++++++++++++++++++++-
 include/linux/efi.h                          |  3 ++
 4 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi b/Documentation/ABI/testing/sysfs-firmware-efi
new file mode 100644
index 0000000..05874da
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi
@@ -0,0 +1,20 @@
+What:		/sys/firmware/efi/fw_vendor
+Date:		December 2013
+Contact:	Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+Description:	It shows the physical address of firmware vendor field in the
+		EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/runtime
+Date:		December 2013
+Contact:	Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+Description:	It shows the physical address of runtime service table entry in
+		the EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/config_table
+Date:		December 2013
+Contact:	Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+Description:	It shows the physical address of config table entry in the EFI
+		system table.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 7778b5f..3e8b760 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -653,6 +653,10 @@ void __init efi_init(void)
 
 	set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
+	efi.config_table = (unsigned long)efi.systab->tables;
+	efi.fw_vendor	 = (unsigned long)efi.systab->fw_vendor;
+	efi.runtime	 = (unsigned long)efi.systab->runtime;
+
 	/*
 	 * Show what we know for posterity
 	 */
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index b716a66..6d0bc52 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -32,6 +32,9 @@ struct efi __read_mostly efi = {
 	.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,
 };
 EXPORT_SYMBOL(efi);
 
@@ -71,13 +74,49 @@ static ssize_t systab_show(struct kobject *kobj,
 static struct kobj_attribute efi_attr_systab =
 			__ATTR(systab, 0400, systab_show, NULL);
 
+#define EFI_FIELD(var) efi.var
+
+#define EFI_ATTR_SHOW(name) \
+static ssize_t name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+{ \
+	return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
+}
+
+EFI_ATTR_SHOW(fw_vendor);
+EFI_ATTR_SHOW(runtime);
+EFI_ATTR_SHOW(config_table);
+
+static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
+static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
+static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
+
 static struct attribute *efi_subsys_attrs[] = {
 	&efi_attr_systab.attr,
-	NULL,	/* maybe more in the future? */
+	&efi_attr_fw_vendor.attr,
+	&efi_attr_runtime.attr,
+	&efi_attr_config_table.attr,
+	NULL,
 };
 
+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;
+
+	return mode;
+}
+
 static struct attribute_group efi_subsys_attr_group = {
 	.attrs = efi_subsys_attrs,
+	.is_visible = efi_attr_is_visible,
 };
 
 static struct efivars generic_efivars;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 49ece2c..988af61 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -556,6 +556,9 @@ extern struct efi {
 	unsigned long hcdp;		/* HCDP table */
 	unsigned long uga;		/* UGA table */
 	unsigned long uv_systab;	/* UV system table */
+	unsigned long fw_vendor;	/* fw_vendor */
+	unsigned long runtime;		/* runtime table */
+	unsigned long config_table;	/* config tables */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
-- 
1.8.3.1

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

* [PATCH v6 07/14] efi: export more efi table variable to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Export fw_vendor, runtime and config table physical addresses to
/sys/firmware/efi/{fw_vendor,runtime,config_table} because kexec kernel
need them.

From EFI spec these 3 variables will be updated to
virtual address after entering virtual mode. But
kernel startup code will need the physical address.

changelog:
Greg: add standalone sysfs files instead of add lines to systab
Document them as testing ABI
Greg: use group attrs and is_visible
Boris: align comments lines
Boris: add macros for _show functions, documentation fixes.
Matt: Documentation fixes.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 Documentation/ABI/testing/sysfs-firmware-efi | 20 ++++++++++++++
 arch/x86/platform/efi/efi.c                  |  4 +++
 drivers/firmware/efi/efi.c                   | 41 +++++++++++++++++++++++++++-
 include/linux/efi.h                          |  3 ++
 4 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi b/Documentation/ABI/testing/sysfs-firmware-efi
new file mode 100644
index 0000000..05874da
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi
@@ -0,0 +1,20 @@
+What:		/sys/firmware/efi/fw_vendor
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of firmware vendor field in the
+		EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/runtime
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of runtime service table entry in
+		the EFI system table.
+Users:		Kexec
+
+What:		/sys/firmware/efi/config_table
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	It shows the physical address of config table entry in the EFI
+		system table.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 7778b5f..3e8b760 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -653,6 +653,10 @@ void __init efi_init(void)
 
 	set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
+	efi.config_table = (unsigned long)efi.systab->tables;
+	efi.fw_vendor	 = (unsigned long)efi.systab->fw_vendor;
+	efi.runtime	 = (unsigned long)efi.systab->runtime;
+
 	/*
 	 * Show what we know for posterity
 	 */
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index b716a66..6d0bc52 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -32,6 +32,9 @@ struct efi __read_mostly efi = {
 	.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,
 };
 EXPORT_SYMBOL(efi);
 
@@ -71,13 +74,49 @@ static ssize_t systab_show(struct kobject *kobj,
 static struct kobj_attribute efi_attr_systab =
 			__ATTR(systab, 0400, systab_show, NULL);
 
+#define EFI_FIELD(var) efi.var
+
+#define EFI_ATTR_SHOW(name) \
+static ssize_t name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+{ \
+	return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
+}
+
+EFI_ATTR_SHOW(fw_vendor);
+EFI_ATTR_SHOW(runtime);
+EFI_ATTR_SHOW(config_table);
+
+static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
+static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
+static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
+
 static struct attribute *efi_subsys_attrs[] = {
 	&efi_attr_systab.attr,
-	NULL,	/* maybe more in the future? */
+	&efi_attr_fw_vendor.attr,
+	&efi_attr_runtime.attr,
+	&efi_attr_config_table.attr,
+	NULL,
 };
 
+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;
+
+	return mode;
+}
+
 static struct attribute_group efi_subsys_attr_group = {
 	.attrs = efi_subsys_attrs,
+	.is_visible = efi_attr_is_visible,
 };
 
 static struct efivars generic_efivars;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 49ece2c..988af61 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -556,6 +556,9 @@ extern struct efi {
 	unsigned long hcdp;		/* HCDP table */
 	unsigned long uga;		/* UGA table */
 	unsigned long uv_systab;	/* UV system table */
+	unsigned long fw_vendor;	/* fw_vendor */
+	unsigned long runtime;		/* runtime table */
+	unsigned long config_table;	/* config tables */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
  2013-12-16  9:30 ` Dave Young
@ 2013-12-16  9:30   ` Dave Young
  -1 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

kexec kernel will need exactly same mapping for
efi runtime memory ranges. Thus here export the
runtime ranges mapping to sysfs, kexec-tools
will assemble them and pass to 2nd kernel via
setup_data.

Introducing a new directory /sys/firmware/efi/runtime-map
Just like /sys/firmware/memmap. Containing below attribute
in each file of that directory:
attribute  num_pages  phys_addr  type  virt_addr

Changelog:
 - Cleaup code, add function efi_save_runtime_map
 - Improve err handling
 - Add macros for sysfs _show functions
 - Remove forward declarations.
 Matt:
 - s/efi-runtime-map.c/runtime-map.c
 - Change dir name to runtime-map
 - Changelog and documentation fixes.
 - Documentation fixes.
 - Update to use desc_size in efi_runtime_map
 - Kconfig EFI_RUNTIME_MAP depends on X86 && KEXEC && EFI
 Boris:
 - Documentation grammar/spelling fix
 - krealloc fix.
 - Move efi_runtime_map_init to efisubsys_initcall.
 - Remove 'if EXPERT' for EFI_RUNTIME_MAP Kconfig option
 - save_runtime_map: move error handling code into the function itself.
 - other code improvement.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++++
 arch/x86/platform/efi/efi.c                        |  38 ++++-
 drivers/firmware/efi/Kconfig                       |  11 ++
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |   6 +
 drivers/firmware/efi/runtime-map.c                 | 181 +++++++++++++++++++++
 include/linux/efi.h                                |   5 +
 7 files changed, 274 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 drivers/firmware/efi/runtime-map.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
new file mode 100644
index 0000000..c61b9b3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
@@ -0,0 +1,34 @@
+What:		/sys/firmware/efi/runtime-map/
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	Switching efi runtime services to virtual mode requires
+		that all efi memory ranges which have the runtime attribute
+		bit set to be mapped to virtual addresses.
+
+		The efi runtime services can only be switched to virtual
+		mode once without rebooting. The kexec kernel must maintain
+		the same physical to virtual address mappings as the first
+		kernel. The mappings are exported to sysfs so userspace tools
+		can reassemble them and pass them into the kexec kernel.
+
+		/sys/firmware/efi/runtime-map/ is the directory the kernel
+		exports that information in.
+
+		subdirectories are named with the number of the memory range:
+
+			/sys/firmware/efi/runtime-map/0
+			/sys/firmware/efi/runtime-map/1
+			/sys/firmware/efi/runtime-map/2
+			/sys/firmware/efi/runtime-map/3
+			...
+
+		Each subdirectory contains five files:
+
+		attribute : The attributes of the memory range.
+		num_pages : The size of the memory range in pages.
+		phys_addr : The physical address of the memory range.
+		type      : The type of the memory range.
+		virt_addr : The virtual address of the memory range.
+
+		Above values are all hexadecimal numbers with the '0x' prefix.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3e8b760..11b110f9 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 	{NULL_GUID, NULL, NULL},
 };
 
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -810,6 +813,24 @@ static void __init efi_merge_regions(void)
 	}
 }
 
+static int __init save_runtime_map(efi_memory_desc_t *md, int idx)
+{
+	void *p;
+	p = krealloc(efi_runtime_map, (idx + 1) * memmap.desc_size, GFP_KERNEL);
+	if (!p)
+		goto out;
+
+	efi_runtime_map = p;
+	memcpy(efi_runtime_map + idx * memmap.desc_size, md, memmap.desc_size);
+
+	return 0;
+out:
+	kfree(efi_runtime_map);
+	efi_runtime_map = NULL;
+	nr_efi_runtime_map = 0;
+	return -ENOMEM;
+}
+
 /*
  * Map efi memory ranges for runtime serivce and update new_memmap with virtual
  * addresses.
@@ -820,6 +841,7 @@ static void * __init efi_map_regions(int *count)
 	void *p, *tmp, *new_memmap = NULL;
 	unsigned long size;
 	u64 end, systab;
+	int err = 0;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -844,15 +866,22 @@ static void * __init efi_map_regions(int *count)
 		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
 			       GFP_KERNEL);
 		if (!tmp)
-			goto out_krealloc;
+			goto out;
 		new_memmap = tmp;
 		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA) {
+			err = save_runtime_map(md, nr_efi_runtime_map);
+			if (err)
+				goto out;
+			nr_efi_runtime_map++;
+		}
 		(*count)++;
 	}
 
 	return new_memmap;
-out_krealloc:
+out:
 	kfree(new_memmap);
 	return NULL;
 }
@@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
+			      boot_params.efi_info.efi_memdesc_size);
+#endif
+
 	BUG_ON(!efi.systab);
 
 	efi_setup_page_tables();
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..730f5f2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -39,4 +39,15 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
 config UEFI_CPER
 	def_bool n
 
+config EFI_RUNTIME_MAP
+	bool "Export efi runtime maps to sysfs"
+	depends on X86 && EFI && KEXEC
+	default y
+	help
+	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
+	  That memory map is used for example by kexec to set up efi virtual
+	  mapping the 2nd kernel, but can also be used for debugging purposes.
+
+	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..a58e0f1 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -5,3 +5,4 @@ obj-y					+= efi.o vars.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
+obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 6d0bc52..0527908 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+	error = efi_runtime_map_init(efi_kobj);
+	if (error)
+		goto err_remove_group;
+#endif
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
new file mode 100644
index 0000000..97cdd16
--- /dev/null
+++ b/drivers/firmware/efi/runtime-map.c
@@ -0,0 +1,181 @@
+/*
+ * linux/drivers/efi/runtime-map.c
+ * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+static u32 efi_memdesc_size;
+
+struct efi_runtime_map_entry {
+	efi_memory_desc_t md;
+	struct kobject kobj;   /* kobject for each entry */
+};
+
+static struct efi_runtime_map_entry **map_entries;
+
+struct map_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
+};
+
+static inline struct map_attribute *to_map_attr(struct attribute *attr)
+{
+	return container_of(attr, struct map_attribute, attr);
+}
+
+static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
+}
+
+#define EFI_RUNTIME_FIELD(var) entry->md.var
+
+#define EFI_RUNTIME_U64_ATTR_SHOW(name) \
+static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
+{ \
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
+}
+
+EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
+EFI_RUNTIME_U64_ATTR_SHOW(attribute);
+
+static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct efi_runtime_map_entry, kobj);
+}
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *buf)
+{
+	struct efi_runtime_map_entry *entry = to_map_entry(kobj);
+	struct map_attribute *map_attr = to_map_attr(attr);
+
+	return map_attr->show(entry, buf);
+}
+
+static struct map_attribute map_type_attr = __ATTR_RO(type);
+static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
+static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
+static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
+static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&map_type_attr.attr,
+	&map_phys_addr_attr.attr,
+	&map_virt_addr_attr.attr,
+	&map_num_pages_attr.attr,
+	&map_attribute_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops map_attr_ops = {
+	.show = map_attr_show,
+};
+
+static void map_release(struct kobject *kobj)
+{
+	struct efi_runtime_map_entry *entry;
+
+	entry = to_map_entry(kobj);
+	kfree(entry);
+}
+
+static struct kobj_type __refdata map_ktype = {
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= def_attrs,
+	.release	= map_release,
+};
+
+static struct kset *map_kset;
+
+static struct efi_runtime_map_entry *
+add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
+{
+	int ret;
+	struct efi_runtime_map_entry *entry;
+
+	if (!map_kset) {
+		map_kset = kset_create_and_add("runtime-map", NULL, kobj);
+		if (!map_kset)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		kset_unregister(map_kset);
+		return entry;
+	}
+
+	memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
+	       sizeof(efi_memory_desc_t));
+
+	kobject_init(&entry->kobj, &map_ktype);
+	entry->kobj.kset = map_kset;
+	ret = kobject_add(&entry->kobj, NULL, "%d", nr);
+	if (ret) {
+		kobject_put(&entry->kobj);
+		kset_unregister(map_kset);
+		return ERR_PTR(ret);
+	}
+
+	return entry;
+}
+
+void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
+{
+	efi_runtime_map = map;
+	nr_efi_runtime_map = nr_entries;
+	efi_memdesc_size = desc_size;
+}
+
+int __init efi_runtime_map_init(struct kobject *efi_kobj)
+{
+	int i, j, ret = 0;
+	struct efi_runtime_map_entry *entry;
+
+	if (!efi_runtime_map)
+		return 0;
+
+	map_entries = kzalloc(nr_efi_runtime_map * sizeof(entry), GFP_KERNEL);
+	if (!map_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < nr_efi_runtime_map; i++) {
+		entry = add_sysfs_runtime_map_entry(efi_kobj, i);
+		if (IS_ERR(entry)) {
+			ret = PTR_ERR(entry);
+			goto out_add_entry;
+		}
+		*(map_entries + i) = entry;
+	}
+
+	return 0;
+out_add_entry:
+	for (j = i - 1; j > 0; j--) {
+		entry = *(map_entries + j);
+		kobject_put(&entry->kobj);
+	}
+	if (map_kset)
+		kset_unregister(map_kset);
+out:
+	return ret;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 988af61..0a3fa38 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
 
 #endif /* CONFIG_EFI_VARS */
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+int efi_runtime_map_init(struct kobject *);
+void efi_runtime_map_setup(void *, int, u32);
+#endif
+
 #endif /* _LINUX_EFI_H */
-- 
1.8.3.1


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

* [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

kexec kernel will need exactly same mapping for
efi runtime memory ranges. Thus here export the
runtime ranges mapping to sysfs, kexec-tools
will assemble them and pass to 2nd kernel via
setup_data.

Introducing a new directory /sys/firmware/efi/runtime-map
Just like /sys/firmware/memmap. Containing below attribute
in each file of that directory:
attribute  num_pages  phys_addr  type  virt_addr

Changelog:
 - Cleaup code, add function efi_save_runtime_map
 - Improve err handling
 - Add macros for sysfs _show functions
 - Remove forward declarations.
 Matt:
 - s/efi-runtime-map.c/runtime-map.c
 - Change dir name to runtime-map
 - Changelog and documentation fixes.
 - Documentation fixes.
 - Update to use desc_size in efi_runtime_map
 - Kconfig EFI_RUNTIME_MAP depends on X86 && KEXEC && EFI
 Boris:
 - Documentation grammar/spelling fix
 - krealloc fix.
 - Move efi_runtime_map_init to efisubsys_initcall.
 - Remove 'if EXPERT' for EFI_RUNTIME_MAP Kconfig option
 - save_runtime_map: move error handling code into the function itself.
 - other code improvement.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++++
 arch/x86/platform/efi/efi.c                        |  38 ++++-
 drivers/firmware/efi/Kconfig                       |  11 ++
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |   6 +
 drivers/firmware/efi/runtime-map.c                 | 181 +++++++++++++++++++++
 include/linux/efi.h                                |   5 +
 7 files changed, 274 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 drivers/firmware/efi/runtime-map.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
new file mode 100644
index 0000000..c61b9b3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
@@ -0,0 +1,34 @@
+What:		/sys/firmware/efi/runtime-map/
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	Switching efi runtime services to virtual mode requires
+		that all efi memory ranges which have the runtime attribute
+		bit set to be mapped to virtual addresses.
+
+		The efi runtime services can only be switched to virtual
+		mode once without rebooting. The kexec kernel must maintain
+		the same physical to virtual address mappings as the first
+		kernel. The mappings are exported to sysfs so userspace tools
+		can reassemble them and pass them into the kexec kernel.
+
+		/sys/firmware/efi/runtime-map/ is the directory the kernel
+		exports that information in.
+
+		subdirectories are named with the number of the memory range:
+
+			/sys/firmware/efi/runtime-map/0
+			/sys/firmware/efi/runtime-map/1
+			/sys/firmware/efi/runtime-map/2
+			/sys/firmware/efi/runtime-map/3
+			...
+
+		Each subdirectory contains five files:
+
+		attribute : The attributes of the memory range.
+		num_pages : The size of the memory range in pages.
+		phys_addr : The physical address of the memory range.
+		type      : The type of the memory range.
+		virt_addr : The virtual address of the memory range.
+
+		Above values are all hexadecimal numbers with the '0x' prefix.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3e8b760..11b110f9 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 	{NULL_GUID, NULL, NULL},
 };
 
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -810,6 +813,24 @@ static void __init efi_merge_regions(void)
 	}
 }
 
+static int __init save_runtime_map(efi_memory_desc_t *md, int idx)
+{
+	void *p;
+	p = krealloc(efi_runtime_map, (idx + 1) * memmap.desc_size, GFP_KERNEL);
+	if (!p)
+		goto out;
+
+	efi_runtime_map = p;
+	memcpy(efi_runtime_map + idx * memmap.desc_size, md, memmap.desc_size);
+
+	return 0;
+out:
+	kfree(efi_runtime_map);
+	efi_runtime_map = NULL;
+	nr_efi_runtime_map = 0;
+	return -ENOMEM;
+}
+
 /*
  * Map efi memory ranges for runtime serivce and update new_memmap with virtual
  * addresses.
@@ -820,6 +841,7 @@ static void * __init efi_map_regions(int *count)
 	void *p, *tmp, *new_memmap = NULL;
 	unsigned long size;
 	u64 end, systab;
+	int err = 0;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -844,15 +866,22 @@ static void * __init efi_map_regions(int *count)
 		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
 			       GFP_KERNEL);
 		if (!tmp)
-			goto out_krealloc;
+			goto out;
 		new_memmap = tmp;
 		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA) {
+			err = save_runtime_map(md, nr_efi_runtime_map);
+			if (err)
+				goto out;
+			nr_efi_runtime_map++;
+		}
 		(*count)++;
 	}
 
 	return new_memmap;
-out_krealloc:
+out:
 	kfree(new_memmap);
 	return NULL;
 }
@@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
+			      boot_params.efi_info.efi_memdesc_size);
+#endif
+
 	BUG_ON(!efi.systab);
 
 	efi_setup_page_tables();
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..730f5f2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -39,4 +39,15 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
 config UEFI_CPER
 	def_bool n
 
+config EFI_RUNTIME_MAP
+	bool "Export efi runtime maps to sysfs"
+	depends on X86 && EFI && KEXEC
+	default y
+	help
+	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
+	  That memory map is used for example by kexec to set up efi virtual
+	  mapping the 2nd kernel, but can also be used for debugging purposes.
+
+	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..a58e0f1 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -5,3 +5,4 @@ obj-y					+= efi.o vars.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
+obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 6d0bc52..0527908 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+	error = efi_runtime_map_init(efi_kobj);
+	if (error)
+		goto err_remove_group;
+#endif
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
new file mode 100644
index 0000000..97cdd16
--- /dev/null
+++ b/drivers/firmware/efi/runtime-map.c
@@ -0,0 +1,181 @@
+/*
+ * linux/drivers/efi/runtime-map.c
+ * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+static u32 efi_memdesc_size;
+
+struct efi_runtime_map_entry {
+	efi_memory_desc_t md;
+	struct kobject kobj;   /* kobject for each entry */
+};
+
+static struct efi_runtime_map_entry **map_entries;
+
+struct map_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
+};
+
+static inline struct map_attribute *to_map_attr(struct attribute *attr)
+{
+	return container_of(attr, struct map_attribute, attr);
+}
+
+static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
+}
+
+#define EFI_RUNTIME_FIELD(var) entry->md.var
+
+#define EFI_RUNTIME_U64_ATTR_SHOW(name) \
+static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
+{ \
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
+}
+
+EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
+EFI_RUNTIME_U64_ATTR_SHOW(attribute);
+
+static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct efi_runtime_map_entry, kobj);
+}
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *buf)
+{
+	struct efi_runtime_map_entry *entry = to_map_entry(kobj);
+	struct map_attribute *map_attr = to_map_attr(attr);
+
+	return map_attr->show(entry, buf);
+}
+
+static struct map_attribute map_type_attr = __ATTR_RO(type);
+static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
+static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
+static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
+static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&map_type_attr.attr,
+	&map_phys_addr_attr.attr,
+	&map_virt_addr_attr.attr,
+	&map_num_pages_attr.attr,
+	&map_attribute_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops map_attr_ops = {
+	.show = map_attr_show,
+};
+
+static void map_release(struct kobject *kobj)
+{
+	struct efi_runtime_map_entry *entry;
+
+	entry = to_map_entry(kobj);
+	kfree(entry);
+}
+
+static struct kobj_type __refdata map_ktype = {
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= def_attrs,
+	.release	= map_release,
+};
+
+static struct kset *map_kset;
+
+static struct efi_runtime_map_entry *
+add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
+{
+	int ret;
+	struct efi_runtime_map_entry *entry;
+
+	if (!map_kset) {
+		map_kset = kset_create_and_add("runtime-map", NULL, kobj);
+		if (!map_kset)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		kset_unregister(map_kset);
+		return entry;
+	}
+
+	memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
+	       sizeof(efi_memory_desc_t));
+
+	kobject_init(&entry->kobj, &map_ktype);
+	entry->kobj.kset = map_kset;
+	ret = kobject_add(&entry->kobj, NULL, "%d", nr);
+	if (ret) {
+		kobject_put(&entry->kobj);
+		kset_unregister(map_kset);
+		return ERR_PTR(ret);
+	}
+
+	return entry;
+}
+
+void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
+{
+	efi_runtime_map = map;
+	nr_efi_runtime_map = nr_entries;
+	efi_memdesc_size = desc_size;
+}
+
+int __init efi_runtime_map_init(struct kobject *efi_kobj)
+{
+	int i, j, ret = 0;
+	struct efi_runtime_map_entry *entry;
+
+	if (!efi_runtime_map)
+		return 0;
+
+	map_entries = kzalloc(nr_efi_runtime_map * sizeof(entry), GFP_KERNEL);
+	if (!map_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < nr_efi_runtime_map; i++) {
+		entry = add_sysfs_runtime_map_entry(efi_kobj, i);
+		if (IS_ERR(entry)) {
+			ret = PTR_ERR(entry);
+			goto out_add_entry;
+		}
+		*(map_entries + i) = entry;
+	}
+
+	return 0;
+out_add_entry:
+	for (j = i - 1; j > 0; j--) {
+		entry = *(map_entries + j);
+		kobject_put(&entry->kobj);
+	}
+	if (map_kset)
+		kset_unregister(map_kset);
+out:
+	return ret;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 988af61..0a3fa38 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
 
 #endif /* CONFIG_EFI_VARS */
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+int efi_runtime_map_init(struct kobject *);
+void efi_runtime_map_setup(void *, int, u32);
+#endif
+
 #endif /* _LINUX_EFI_H */
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/efi.h            |  12 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 192 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   5 +
 6 files changed, 190 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..4f81328 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern void parse_efi_setup(u64 phys_addr);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..b2b54cd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 11b110f9..e8739aa 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,7 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup; /* efi setup_data physical address */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +116,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +494,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +529,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +646,81 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void __init efi_setup_init(void)
+{
+	struct setup_data *sd;
+
+	if (!efi_setup)
+		return;
+
+	sd = early_memremap(efi_setup, sizeof(struct setup_data));
+	if (!sd) {
+		pr_warn("early_memremap setup_data failed\n");
+		efi_setup = 0;
+		return;
+	}
+	efi_setup += sizeof(struct setup_data);
+	nr_efi_runtime_map = (sd->len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+	early_memunmap(sd, sizeof(struct setup_data));
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +728,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	efi_setup_init();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +767,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +981,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1033,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1055,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 #ifdef CONFIG_EFI_RUNTIME_MAP
@@ -938,16 +1080,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..cb84fef 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..1d6835a 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,8 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr)
+{
+	efi_setup = phys_addr;
+}
-- 
1.8.3.1


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

* [PATCH v6 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/include/asm/efi.h            |  12 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 192 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   5 +
 6 files changed, 190 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..4f81328 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern void parse_efi_setup(u64 phys_addr);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..b2b54cd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 11b110f9..e8739aa 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,7 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup; /* efi setup_data physical address */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +116,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +494,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +529,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +646,81 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void __init efi_setup_init(void)
+{
+	struct setup_data *sd;
+
+	if (!efi_setup)
+		return;
+
+	sd = early_memremap(efi_setup, sizeof(struct setup_data));
+	if (!sd) {
+		pr_warn("early_memremap setup_data failed\n");
+		efi_setup = 0;
+		return;
+	}
+	efi_setup += sizeof(struct setup_data);
+	nr_efi_runtime_map = (sd->len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+	early_memunmap(sd, sizeof(struct setup_data));
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +728,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	efi_setup_init();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +767,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +981,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1033,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1055,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 #ifdef CONFIG_EFI_RUNTIME_MAP
@@ -938,16 +1080,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..cb84fef 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..1d6835a 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,8 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr)
+{
+	efi_setup = phys_addr;
+}
-- 
1.8.3.1

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

* [PATCH v6 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/efi.h            |  12 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 192 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   5 +
 6 files changed, 190 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..4f81328 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,18 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern void parse_efi_setup(u64 phys_addr);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..b2b54cd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 11b110f9..e8739aa 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,7 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup; /* efi setup_data physical address */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +116,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +494,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +529,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +646,81 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void __init efi_setup_init(void)
+{
+	struct setup_data *sd;
+
+	if (!efi_setup)
+		return;
+
+	sd = early_memremap(efi_setup, sizeof(struct setup_data));
+	if (!sd) {
+		pr_warn("early_memremap setup_data failed\n");
+		efi_setup = 0;
+		return;
+	}
+	efi_setup += sizeof(struct setup_data);
+	nr_efi_runtime_map = (sd->len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+	early_memunmap(sd, sizeof(struct setup_data));
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +728,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	efi_setup_init();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +767,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +981,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1033,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1055,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 #ifdef CONFIG_EFI_RUNTIME_MAP
@@ -938,16 +1080,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..cb84fef 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..1d6835a 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,8 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr)
+{
+	efi_setup = phys_addr;
+}
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

For kexec/kdump kernel efi runtime mappings are saved, printing original whole
memmap ranges does not make sense anymore. So introduce a new function to only
print runtime maps in case kexec/kdump kernel is used.

changelog:
Matt: use efi_setup instead of esdata
      share function print_efi_memmap for both normal and kexec boot.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e8739aa..62bfb57 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -403,19 +403,16 @@ int __init efi_memblock_x86_reserve_range(void)
 	return 0;
 }
 
-static void __init print_efi_memmap(void)
+static void __init print_efi_memmap(void *map, int nr_map, int md_size)
 {
 #ifdef EFI_DEBUG
 	efi_memory_desc_t *md;
 	void *p;
 	int i;
 
-	for (p = memmap.map, i = 0;
-	     p < memmap.map_end;
-	     p += memmap.desc_size, i++) {
+	for (p = map, i = 0; i < nr_map; p += md_size, i++) {
 		md = p;
-		pr_info("mem%02u: type=%u, attr=0x%llx, "
-			"range=[0x%016llx-0x%016llx) (%lluMB)\n",
+		pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n",
 			i, md->type, md->attribute, md->phys_addr,
 			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 			(md->num_pages >> (20 - EFI_PAGE_SHIFT)));
@@ -799,7 +796,20 @@ void __init efi_init(void)
 		x86_platform.set_wallclock = efi_set_rtc_mmss;
 	}
 #endif
-	print_efi_memmap();
+	if (efi_setup) {
+		int s;
+		struct efi_setup_data *data;
+
+		s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+		data = early_memremap(efi_setup, s);
+		if (!data)
+			return;
+		print_efi_memmap(data->map, nr_efi_runtime_map,
+				 sizeof(data->map[0]));
+		early_memunmap(data, s);
+	} else {
+		print_efi_memmap(memmap.map, memmap.nr_map, memmap.desc_size);
+	}
 }
 
 void __init efi_late_init(void)
-- 
1.8.3.1


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

* [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

For kexec/kdump kernel efi runtime mappings are saved, printing original whole
memmap ranges does not make sense anymore. So introduce a new function to only
print runtime maps in case kexec/kdump kernel is used.

changelog:
Matt: use efi_setup instead of esdata
      share function print_efi_memmap for both normal and kexec boot.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e8739aa..62bfb57 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -403,19 +403,16 @@ int __init efi_memblock_x86_reserve_range(void)
 	return 0;
 }
 
-static void __init print_efi_memmap(void)
+static void __init print_efi_memmap(void *map, int nr_map, int md_size)
 {
 #ifdef EFI_DEBUG
 	efi_memory_desc_t *md;
 	void *p;
 	int i;
 
-	for (p = memmap.map, i = 0;
-	     p < memmap.map_end;
-	     p += memmap.desc_size, i++) {
+	for (p = map, i = 0; i < nr_map; p += md_size, i++) {
 		md = p;
-		pr_info("mem%02u: type=%u, attr=0x%llx, "
-			"range=[0x%016llx-0x%016llx) (%lluMB)\n",
+		pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n",
 			i, md->type, md->attribute, md->phys_addr,
 			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 			(md->num_pages >> (20 - EFI_PAGE_SHIFT)));
@@ -799,7 +796,20 @@ void __init efi_init(void)
 		x86_platform.set_wallclock = efi_set_rtc_mmss;
 	}
 #endif
-	print_efi_memmap();
+	if (efi_setup) {
+		int s;
+		struct efi_setup_data *data;
+
+		s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+		data = early_memremap(efi_setup, s);
+		if (!data)
+			return;
+		print_efi_memmap(data->map, nr_efi_runtime_map,
+				 sizeof(data->map[0]));
+		early_memunmap(data, s);
+	} else {
+		print_efi_memmap(memmap.map, memmap.nr_map, memmap.desc_size);
+	}
 }
 
 void __init efi_late_init(void)
-- 
1.8.3.1

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

* [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

For kexec/kdump kernel efi runtime mappings are saved, printing original whole
memmap ranges does not make sense anymore. So introduce a new function to only
print runtime maps in case kexec/kdump kernel is used.

changelog:
Matt: use efi_setup instead of esdata
      share function print_efi_memmap for both normal and kexec boot.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e8739aa..62bfb57 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -403,19 +403,16 @@ int __init efi_memblock_x86_reserve_range(void)
 	return 0;
 }
 
-static void __init print_efi_memmap(void)
+static void __init print_efi_memmap(void *map, int nr_map, int md_size)
 {
 #ifdef EFI_DEBUG
 	efi_memory_desc_t *md;
 	void *p;
 	int i;
 
-	for (p = memmap.map, i = 0;
-	     p < memmap.map_end;
-	     p += memmap.desc_size, i++) {
+	for (p = map, i = 0; i < nr_map; p += md_size, i++) {
 		md = p;
-		pr_info("mem%02u: type=%u, attr=0x%llx, "
-			"range=[0x%016llx-0x%016llx) (%lluMB)\n",
+		pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n",
 			i, md->type, md->attribute, md->phys_addr,
 			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 			(md->num_pages >> (20 - EFI_PAGE_SHIFT)));
@@ -799,7 +796,20 @@ void __init efi_init(void)
 		x86_platform.set_wallclock = efi_set_rtc_mmss;
 	}
 #endif
-	print_efi_memmap();
+	if (efi_setup) {
+		int s;
+		struct efi_setup_data *data;
+
+		s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+		data = early_memremap(efi_setup, s);
+		if (!data)
+			return;
+		print_efi_memmap(data->map, nr_efi_runtime_map,
+				 sizeof(data->map[0]));
+		early_memunmap(data, s);
+	} else {
+		print_efi_memmap(memmap.map, memmap.nr_map, memmap.desc_size);
+	}
 }
 
 void __init efi_late_init(void)
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 11/14] x86: add xloadflags bit for efi runtime support on kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Old kexec-tools can not load new kernel. The reason is kexec-tools do not fill
efi_info in x86 setup header previously, thus efi failed to initialize.
In new kexec-tools it will by default fill efi_info and pass other efi required
infomation to 2nd kernel so kexec kernel efi initialization can succeed finally.

To prevent from breaking userspace, add a new xloadflags bit so kexec-tools
can check the flag and switch to old logic.

changelog:
Matt: +&& defined(CONFIG_KEXEC)
      improve patch description.
HPA: document the flag.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 Documentation/x86/boot.txt            | 3 +++
 arch/x86/boot/header.S                | 9 ++++++++-
 arch/x86/include/uapi/asm/bootparam.h | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index f4f268c..cb81741d 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -608,6 +608,9 @@ Protocol:       2.12+
 	- If 1, the kernel supports the 64-bit EFI handoff entry point
           given at handover_offset + 0x200.
 
+  Bit 4 (read): XLF_EFI_KEXEC
+	- If 1, the kernel supports kexec EFI boot with EFI runtime support.
+
 Field name:	cmdline_size
 Type:		read
 Offset/size:	0x238/4
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 9ec06a1..ec3b8ba 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -391,7 +391,14 @@ xloadflags:
 #else
 # define XLF23 0
 #endif
-			.word XLF0 | XLF1 | XLF23
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC)
+# define XLF4 XLF_EFI_KEXEC
+#else
+# define XLF4 0
+#endif
+
+			.word XLF0 | XLF1 | XLF23 | XLF4
 
 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
                                                 #added with boot protocol
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 64fe421..225b098 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -24,6 +24,7 @@
 #define XLF_CAN_BE_LOADED_ABOVE_4G	(1<<1)
 #define XLF_EFI_HANDOVER_32		(1<<2)
 #define XLF_EFI_HANDOVER_64		(1<<3)
+#define XLF_EFI_KEXEC			(1<<4)
 
 #ifndef __ASSEMBLY__
 
-- 
1.8.3.1


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

* [PATCH v6 11/14] x86: add xloadflags bit for efi runtime support on kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

Old kexec-tools can not load new kernel. The reason is kexec-tools do not fill
efi_info in x86 setup header previously, thus efi failed to initialize.
In new kexec-tools it will by default fill efi_info and pass other efi required
infomation to 2nd kernel so kexec kernel efi initialization can succeed finally.

To prevent from breaking userspace, add a new xloadflags bit so kexec-tools
can check the flag and switch to old logic.

changelog:
Matt: +&& defined(CONFIG_KEXEC)
      improve patch description.
HPA: document the flag.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
---
 Documentation/x86/boot.txt            | 3 +++
 arch/x86/boot/header.S                | 9 ++++++++-
 arch/x86/include/uapi/asm/bootparam.h | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index f4f268c..cb81741d 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -608,6 +608,9 @@ Protocol:       2.12+
 	- If 1, the kernel supports the 64-bit EFI handoff entry point
           given at handover_offset + 0x200.
 
+  Bit 4 (read): XLF_EFI_KEXEC
+	- If 1, the kernel supports kexec EFI boot with EFI runtime support.
+
 Field name:	cmdline_size
 Type:		read
 Offset/size:	0x238/4
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 9ec06a1..ec3b8ba 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -391,7 +391,14 @@ xloadflags:
 #else
 # define XLF23 0
 #endif
-			.word XLF0 | XLF1 | XLF23
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC)
+# define XLF4 XLF_EFI_KEXEC
+#else
+# define XLF4 0
+#endif
+
+			.word XLF0 | XLF1 | XLF23 | XLF4
 
 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
                                                 #added with boot protocol
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 64fe421..225b098 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -24,6 +24,7 @@
 #define XLF_CAN_BE_LOADED_ABOVE_4G	(1<<1)
 #define XLF_EFI_HANDOVER_32		(1<<2)
 #define XLF_EFI_HANDOVER_64		(1<<3)
+#define XLF_EFI_KEXEC			(1<<4)
 
 #ifndef __ASSEMBLY__
 
-- 
1.8.3.1

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

* [PATCH v6 11/14] x86: add xloadflags bit for efi runtime support on kexec
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Old kexec-tools can not load new kernel. The reason is kexec-tools do not fill
efi_info in x86 setup header previously, thus efi failed to initialize.
In new kexec-tools it will by default fill efi_info and pass other efi required
infomation to 2nd kernel so kexec kernel efi initialization can succeed finally.

To prevent from breaking userspace, add a new xloadflags bit so kexec-tools
can check the flag and switch to old logic.

changelog:
Matt: +&& defined(CONFIG_KEXEC)
      improve patch description.
HPA: document the flag.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 Documentation/x86/boot.txt            | 3 +++
 arch/x86/boot/header.S                | 9 ++++++++-
 arch/x86/include/uapi/asm/bootparam.h | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index f4f268c..cb81741d 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -608,6 +608,9 @@ Protocol:       2.12+
 	- If 1, the kernel supports the 64-bit EFI handoff entry point
           given at handover_offset + 0x200.
 
+  Bit 4 (read): XLF_EFI_KEXEC
+	- If 1, the kernel supports kexec EFI boot with EFI runtime support.
+
 Field name:	cmdline_size
 Type:		read
 Offset/size:	0x238/4
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 9ec06a1..ec3b8ba 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -391,7 +391,14 @@ xloadflags:
 #else
 # define XLF23 0
 #endif
-			.word XLF0 | XLF1 | XLF23
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC)
+# define XLF4 XLF_EFI_KEXEC
+#else
+# define XLF4 0
+#endif
+
+			.word XLF0 | XLF1 | XLF23 | XLF4
 
 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
                                                 #added with boot protocol
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 64fe421..225b098 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -24,6 +24,7 @@
 #define XLF_CAN_BE_LOADED_ABOVE_4G	(1<<1)
 #define XLF_EFI_HANDOVER_32		(1<<2)
 #define XLF_EFI_HANDOVER_64		(1<<3)
+#define XLF_EFI_KEXEC			(1<<4)
 
 #ifndef __ASSEMBLY__
 
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 12/14] x86: export x86 boot_params to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

kexec-tools use boot_params for getting the 1st kernel hardware_subarch,
the kexec kernel efi runtime support also need read the old efi_info from
boot_params. Currently it exists in debugfs which is not a good place for
such infomation. Per HPA, we should avoid of "sploit debugfs".

In this patch /sys/kernel/boot_params are exported, also the setup_data is
exported as a subdirectory. kexec-tools is using debugfs for hardware_subarch
for a long time now so we're not removing it yet.

Structure is like below:

/sys/kernel/boot_params
|__ data                /* boot_params in binary*/
|__ setup_data
|   |__ 0               /* the first setup_data node */
|   |   |__ data        /* setup_data node 0 in binary*/
|   |   |__ type        /* setup_data type of setup_data node 0, hex string */
[snip]
|__ version             /* boot protocal version (in hex, "0x" prefixed)*/

Changelog:
Greg: use __ATTR_RO() and group attr.
Matt and Boris: Documentation improvement, code indentation.
Documentation fix.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 +++
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/ksysfs.c                           | 339 +++++++++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c

diff --git a/Documentation/ABI/testing/sysfs-kernel-boot_params b/Documentation/ABI/testing/sysfs-kernel-boot_params
new file mode 100644
index 0000000..eca38ce
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-boot_params
@@ -0,0 +1,38 @@
+What:		/sys/kernel/boot_params
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	The /sys/kernel/boot_params directory contains two
+		files: "data" and "version" and one subdirectory "setup_data".
+		It is used to export the kernel boot parameters of an x86
+		platform to userspace for kexec and debugging purpose.
+
+		If there's no setup_data in boot_params the subdirectory will
+		not be created.
+
+		"data" file is the binary representation of struct boot_params.
+
+		"version" file is the string representation of boot
+		protocol version.
+
+		"setup_data" subdirectory contains the setup_data data
+		structure in boot_params. setup_data is maintained in kernel
+		as a link list. In "setup_data" subdirectory there's one
+		subdirectory for each link list node named with the number
+		of the list nodes. The list node subdirectory contains two
+		files "type" and "data". "type" file is the string
+		representation of setup_data type. "data" file is the binary
+		representation of setup_data payload.
+
+		The whole boot_params directory structure is like below:
+		/sys/kernel/boot_params
+		|__ data
+		|__ setup_data
+		|   |__ 0
+		|   |   |__ data
+		|   |   |__ type
+		|   |__ 1
+		|       |__ data
+		|       |__ type
+		|__ version
+
+Users:		Kexec
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9b0a34e..510cca5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-y			+= syscall_$(BITS).o
 obj-$(CONFIG_X86_64)	+= vsyscall_64.o
 obj-$(CONFIG_X86_64)	+= vsyscall_emu_64.o
+obj-$(CONFIG_SYSFS)	+= ksysfs.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
new file mode 100644
index 0000000..eb53d15
--- /dev/null
+++ b/arch/x86/kernel/ksysfs.c
@@ -0,0 +1,339 @@
+/*
+ * Architecture specific sysfs attributes in /sys/kernel
+ *
+ * Copyright (C) 2007, Intel Corp.
+ *      Huang Ying <ying.huang@intel.com>
+ * Copyright (C) 2013, 2013 Red Hat, Inc.
+ *      Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include <asm/setup.h>
+
+static ssize_t version_show(struct kobject *kobj,
+			    struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%04x\n", boot_params.hdr.version);
+}
+
+static struct kobj_attribute boot_params_version_attr = __ATTR_RO(version);
+
+static ssize_t boot_params_data_read(struct file *fp, struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *buf, loff_t off, size_t count)
+{
+	memcpy(buf, (void *)&boot_params + off, count);
+	return count;
+}
+
+static struct bin_attribute boot_params_data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = boot_params_data_read,
+	.size = sizeof(boot_params),
+};
+
+static struct attribute *boot_params_version_attrs[] = {
+	&boot_params_version_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *boot_params_data_attrs[] = {
+	&boot_params_data_attr,
+	NULL,
+};
+
+static struct attribute_group boot_params_attr_group = {
+	.attrs = boot_params_version_attrs,
+	.bin_attrs = boot_params_data_attrs,
+};
+
+static int kobj_to_setup_data_nr(struct kobject *kobj, int *nr)
+{
+	const char *name;
+
+	name = kobject_name(kobj);
+	return kstrtoint(name, 10, nr);
+}
+
+static int get_setup_data_paddr(int nr, u64 *paddr)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		if (nr == i) {
+			*paddr = pa_data;
+			return 0;
+		}
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static int __init get_setup_data_size(int nr, size_t *size)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+		if (nr == i) {
+			*size = data->len;
+			iounmap(data);
+			return 0;
+		}
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static ssize_t type_show(struct kobject *kobj,
+			 struct kobj_attribute *attr, char *buf)
+{
+	int nr, ret;
+	u64 paddr;
+	struct setup_data *data;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	ret = sprintf(buf, "0x%x\n", data->type);
+	iounmap(data);
+	return ret;
+}
+
+static ssize_t setup_data_data_read(struct file *fp,
+				    struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buf,
+				    loff_t off, size_t count)
+{
+	int nr, ret = 0;
+	u64 paddr;
+	struct setup_data *data;
+	void *p;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	if (off > data->len) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (count > data->len - off)
+		count = data->len - off;
+
+	if (!count)
+		goto out;
+
+	ret = count;
+	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	if (!p) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(buf, p + off, count);
+	iounmap(p);
+out:
+	iounmap(data);
+	return ret;
+}
+
+static struct kobj_attribute type_attr = __ATTR_RO(type);
+
+static struct bin_attribute data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = setup_data_data_read,
+};
+
+static struct attribute *setup_data_type_attrs[] = {
+	&type_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *setup_data_data_attrs[] = {
+	&data_attr,
+	NULL,
+};
+
+static struct attribute_group setup_data_attr_group = {
+	.attrs = setup_data_type_attrs,
+	.bin_attrs = setup_data_data_attrs,
+};
+
+static int __init create_setup_data_node(struct kobject *parent,
+					 struct kobject **kobjp, int nr)
+{
+	int ret = 0;
+	size_t size;
+	struct kobject *kobj;
+	char name[16]; /* should be enough for setup_data nodes numbers */
+	snprintf(name, 16, "%d", nr);
+
+	kobj = kobject_create_and_add(name, parent);
+	if (!kobj)
+		return -ENOMEM;
+
+	ret = get_setup_data_size(nr, &size);
+	if (ret)
+		goto out_kobj;
+
+	data_attr.size = size;
+	ret = sysfs_create_group(kobj, &setup_data_attr_group);
+	if (ret)
+		goto out_kobj;
+	*kobjp = kobj;
+
+	return 0;
+out_kobj:
+	kobject_put(kobj);
+	return ret;
+}
+
+static void __init cleanup_setup_data_node(struct kobject *kobj)
+{
+	sysfs_remove_group(kobj, &setup_data_attr_group);
+	kobject_put(kobj);
+}
+
+static int __init get_setup_data_total_num(u64 pa_data, int *nr)
+{
+	int ret = 0;
+	struct setup_data *data;
+
+	*nr = 0;
+	while (pa_data) {
+		*nr += 1;
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		pa_data = data->next;
+		iounmap(data);
+	}
+
+out:
+	return ret;
+}
+
+static int __init create_setup_data_nodes(struct kobject *parent)
+{
+	struct kobject *setup_data_kobj, **kobjp;
+	u64 pa_data;
+	int i, j, nr, ret = 0;
+
+	pa_data = boot_params.hdr.setup_data;
+	if (!pa_data)
+		return 0;
+
+	setup_data_kobj = kobject_create_and_add("setup_data", parent);
+	if (!setup_data_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = get_setup_data_total_num(pa_data, &nr);
+	if (ret)
+		goto out_setup_data_kobj;
+
+	kobjp = kmalloc(sizeof(*kobjp) * nr, GFP_KERNEL);
+	if (!kobjp) {
+		ret = -ENOMEM;
+		goto out_setup_data_kobj;
+	}
+
+	for (i = 0; i < nr; i++) {
+		ret = create_setup_data_node(setup_data_kobj, kobjp + i, i);
+		if (ret)
+			goto out_clean_nodes;
+	}
+
+	kfree(kobjp);
+	return 0;
+
+out_clean_nodes:
+	for (j = i - 1; j > 0; j--)
+		cleanup_setup_data_node(*(kobjp + j));
+	kfree(kobjp);
+out_setup_data_kobj:
+	kobject_put(setup_data_kobj);
+out:
+	return ret;
+}
+
+static int __init boot_params_ksysfs_init(void)
+{
+	int ret;
+	struct kobject *boot_params_kobj;
+
+	boot_params_kobj = kobject_create_and_add("boot_params",
+						  kernel_kobj);
+	if (!boot_params_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sysfs_create_group(boot_params_kobj, &boot_params_attr_group);
+	if (ret)
+		goto out_boot_params_kobj;
+
+	ret = create_setup_data_nodes(boot_params_kobj);
+	if (ret)
+		goto out_create_group;
+
+	return 0;
+out_create_group:
+	sysfs_remove_group(boot_params_kobj, &boot_params_attr_group);
+out_boot_params_kobj:
+	kobject_put(boot_params_kobj);
+out:
+	return ret;
+}
+
+arch_initcall(boot_params_ksysfs_init);
-- 
1.8.3.1


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

* [PATCH v6 12/14] x86: export x86 boot_params to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

kexec-tools use boot_params for getting the 1st kernel hardware_subarch,
the kexec kernel efi runtime support also need read the old efi_info from
boot_params. Currently it exists in debugfs which is not a good place for
such infomation. Per HPA, we should avoid of "sploit debugfs".

In this patch /sys/kernel/boot_params are exported, also the setup_data is
exported as a subdirectory. kexec-tools is using debugfs for hardware_subarch
for a long time now so we're not removing it yet.

Structure is like below:

/sys/kernel/boot_params
|__ data                /* boot_params in binary*/
|__ setup_data
|   |__ 0               /* the first setup_data node */
|   |   |__ data        /* setup_data node 0 in binary*/
|   |   |__ type        /* setup_data type of setup_data node 0, hex string */
[snip]
|__ version             /* boot protocal version (in hex, "0x" prefixed)*/

Changelog:
Greg: use __ATTR_RO() and group attr.
Matt and Boris: Documentation improvement, code indentation.
Documentation fix.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
---
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 +++
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/ksysfs.c                           | 339 +++++++++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c

diff --git a/Documentation/ABI/testing/sysfs-kernel-boot_params b/Documentation/ABI/testing/sysfs-kernel-boot_params
new file mode 100644
index 0000000..eca38ce
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-boot_params
@@ -0,0 +1,38 @@
+What:		/sys/kernel/boot_params
+Date:		December 2013
+Contact:	Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+Description:	The /sys/kernel/boot_params directory contains two
+		files: "data" and "version" and one subdirectory "setup_data".
+		It is used to export the kernel boot parameters of an x86
+		platform to userspace for kexec and debugging purpose.
+
+		If there's no setup_data in boot_params the subdirectory will
+		not be created.
+
+		"data" file is the binary representation of struct boot_params.
+
+		"version" file is the string representation of boot
+		protocol version.
+
+		"setup_data" subdirectory contains the setup_data data
+		structure in boot_params. setup_data is maintained in kernel
+		as a link list. In "setup_data" subdirectory there's one
+		subdirectory for each link list node named with the number
+		of the list nodes. The list node subdirectory contains two
+		files "type" and "data". "type" file is the string
+		representation of setup_data type. "data" file is the binary
+		representation of setup_data payload.
+
+		The whole boot_params directory structure is like below:
+		/sys/kernel/boot_params
+		|__ data
+		|__ setup_data
+		|   |__ 0
+		|   |   |__ data
+		|   |   |__ type
+		|   |__ 1
+		|       |__ data
+		|       |__ type
+		|__ version
+
+Users:		Kexec
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9b0a34e..510cca5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-y			+= syscall_$(BITS).o
 obj-$(CONFIG_X86_64)	+= vsyscall_64.o
 obj-$(CONFIG_X86_64)	+= vsyscall_emu_64.o
+obj-$(CONFIG_SYSFS)	+= ksysfs.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
new file mode 100644
index 0000000..eb53d15
--- /dev/null
+++ b/arch/x86/kernel/ksysfs.c
@@ -0,0 +1,339 @@
+/*
+ * Architecture specific sysfs attributes in /sys/kernel
+ *
+ * Copyright (C) 2007, Intel Corp.
+ *      Huang Ying <ying.huang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
+ * Copyright (C) 2013, 2013 Red Hat, Inc.
+ *      Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include <asm/setup.h>
+
+static ssize_t version_show(struct kobject *kobj,
+			    struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%04x\n", boot_params.hdr.version);
+}
+
+static struct kobj_attribute boot_params_version_attr = __ATTR_RO(version);
+
+static ssize_t boot_params_data_read(struct file *fp, struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *buf, loff_t off, size_t count)
+{
+	memcpy(buf, (void *)&boot_params + off, count);
+	return count;
+}
+
+static struct bin_attribute boot_params_data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = boot_params_data_read,
+	.size = sizeof(boot_params),
+};
+
+static struct attribute *boot_params_version_attrs[] = {
+	&boot_params_version_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *boot_params_data_attrs[] = {
+	&boot_params_data_attr,
+	NULL,
+};
+
+static struct attribute_group boot_params_attr_group = {
+	.attrs = boot_params_version_attrs,
+	.bin_attrs = boot_params_data_attrs,
+};
+
+static int kobj_to_setup_data_nr(struct kobject *kobj, int *nr)
+{
+	const char *name;
+
+	name = kobject_name(kobj);
+	return kstrtoint(name, 10, nr);
+}
+
+static int get_setup_data_paddr(int nr, u64 *paddr)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		if (nr == i) {
+			*paddr = pa_data;
+			return 0;
+		}
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static int __init get_setup_data_size(int nr, size_t *size)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+		if (nr == i) {
+			*size = data->len;
+			iounmap(data);
+			return 0;
+		}
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static ssize_t type_show(struct kobject *kobj,
+			 struct kobj_attribute *attr, char *buf)
+{
+	int nr, ret;
+	u64 paddr;
+	struct setup_data *data;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	ret = sprintf(buf, "0x%x\n", data->type);
+	iounmap(data);
+	return ret;
+}
+
+static ssize_t setup_data_data_read(struct file *fp,
+				    struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buf,
+				    loff_t off, size_t count)
+{
+	int nr, ret = 0;
+	u64 paddr;
+	struct setup_data *data;
+	void *p;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	if (off > data->len) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (count > data->len - off)
+		count = data->len - off;
+
+	if (!count)
+		goto out;
+
+	ret = count;
+	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	if (!p) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(buf, p + off, count);
+	iounmap(p);
+out:
+	iounmap(data);
+	return ret;
+}
+
+static struct kobj_attribute type_attr = __ATTR_RO(type);
+
+static struct bin_attribute data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = setup_data_data_read,
+};
+
+static struct attribute *setup_data_type_attrs[] = {
+	&type_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *setup_data_data_attrs[] = {
+	&data_attr,
+	NULL,
+};
+
+static struct attribute_group setup_data_attr_group = {
+	.attrs = setup_data_type_attrs,
+	.bin_attrs = setup_data_data_attrs,
+};
+
+static int __init create_setup_data_node(struct kobject *parent,
+					 struct kobject **kobjp, int nr)
+{
+	int ret = 0;
+	size_t size;
+	struct kobject *kobj;
+	char name[16]; /* should be enough for setup_data nodes numbers */
+	snprintf(name, 16, "%d", nr);
+
+	kobj = kobject_create_and_add(name, parent);
+	if (!kobj)
+		return -ENOMEM;
+
+	ret = get_setup_data_size(nr, &size);
+	if (ret)
+		goto out_kobj;
+
+	data_attr.size = size;
+	ret = sysfs_create_group(kobj, &setup_data_attr_group);
+	if (ret)
+		goto out_kobj;
+	*kobjp = kobj;
+
+	return 0;
+out_kobj:
+	kobject_put(kobj);
+	return ret;
+}
+
+static void __init cleanup_setup_data_node(struct kobject *kobj)
+{
+	sysfs_remove_group(kobj, &setup_data_attr_group);
+	kobject_put(kobj);
+}
+
+static int __init get_setup_data_total_num(u64 pa_data, int *nr)
+{
+	int ret = 0;
+	struct setup_data *data;
+
+	*nr = 0;
+	while (pa_data) {
+		*nr += 1;
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		pa_data = data->next;
+		iounmap(data);
+	}
+
+out:
+	return ret;
+}
+
+static int __init create_setup_data_nodes(struct kobject *parent)
+{
+	struct kobject *setup_data_kobj, **kobjp;
+	u64 pa_data;
+	int i, j, nr, ret = 0;
+
+	pa_data = boot_params.hdr.setup_data;
+	if (!pa_data)
+		return 0;
+
+	setup_data_kobj = kobject_create_and_add("setup_data", parent);
+	if (!setup_data_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = get_setup_data_total_num(pa_data, &nr);
+	if (ret)
+		goto out_setup_data_kobj;
+
+	kobjp = kmalloc(sizeof(*kobjp) * nr, GFP_KERNEL);
+	if (!kobjp) {
+		ret = -ENOMEM;
+		goto out_setup_data_kobj;
+	}
+
+	for (i = 0; i < nr; i++) {
+		ret = create_setup_data_node(setup_data_kobj, kobjp + i, i);
+		if (ret)
+			goto out_clean_nodes;
+	}
+
+	kfree(kobjp);
+	return 0;
+
+out_clean_nodes:
+	for (j = i - 1; j > 0; j--)
+		cleanup_setup_data_node(*(kobjp + j));
+	kfree(kobjp);
+out_setup_data_kobj:
+	kobject_put(setup_data_kobj);
+out:
+	return ret;
+}
+
+static int __init boot_params_ksysfs_init(void)
+{
+	int ret;
+	struct kobject *boot_params_kobj;
+
+	boot_params_kobj = kobject_create_and_add("boot_params",
+						  kernel_kobj);
+	if (!boot_params_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sysfs_create_group(boot_params_kobj, &boot_params_attr_group);
+	if (ret)
+		goto out_boot_params_kobj;
+
+	ret = create_setup_data_nodes(boot_params_kobj);
+	if (ret)
+		goto out_create_group;
+
+	return 0;
+out_create_group:
+	sysfs_remove_group(boot_params_kobj, &boot_params_attr_group);
+out_boot_params_kobj:
+	kobject_put(boot_params_kobj);
+out:
+	return ret;
+}
+
+arch_initcall(boot_params_ksysfs_init);
-- 
1.8.3.1

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

* [PATCH v6 12/14] x86: export x86 boot_params to sysfs
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

kexec-tools use boot_params for getting the 1st kernel hardware_subarch,
the kexec kernel efi runtime support also need read the old efi_info from
boot_params. Currently it exists in debugfs which is not a good place for
such infomation. Per HPA, we should avoid of "sploit debugfs".

In this patch /sys/kernel/boot_params are exported, also the setup_data is
exported as a subdirectory. kexec-tools is using debugfs for hardware_subarch
for a long time now so we're not removing it yet.

Structure is like below:

/sys/kernel/boot_params
|__ data                /* boot_params in binary*/
|__ setup_data
|   |__ 0               /* the first setup_data node */
|   |   |__ data        /* setup_data node 0 in binary*/
|   |   |__ type        /* setup_data type of setup_data node 0, hex string */
[snip]
|__ version             /* boot protocal version (in hex, "0x" prefixed)*/

Changelog:
Greg: use __ATTR_RO() and group attr.
Matt and Boris: Documentation improvement, code indentation.
Documentation fix.

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 Documentation/ABI/testing/sysfs-kernel-boot_params |  38 +++
 arch/x86/kernel/Makefile                           |   1 +
 arch/x86/kernel/ksysfs.c                           | 339 +++++++++++++++++++++
 3 files changed, 378 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-boot_params
 create mode 100644 arch/x86/kernel/ksysfs.c

diff --git a/Documentation/ABI/testing/sysfs-kernel-boot_params b/Documentation/ABI/testing/sysfs-kernel-boot_params
new file mode 100644
index 0000000..eca38ce
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-boot_params
@@ -0,0 +1,38 @@
+What:		/sys/kernel/boot_params
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	The /sys/kernel/boot_params directory contains two
+		files: "data" and "version" and one subdirectory "setup_data".
+		It is used to export the kernel boot parameters of an x86
+		platform to userspace for kexec and debugging purpose.
+
+		If there's no setup_data in boot_params the subdirectory will
+		not be created.
+
+		"data" file is the binary representation of struct boot_params.
+
+		"version" file is the string representation of boot
+		protocol version.
+
+		"setup_data" subdirectory contains the setup_data data
+		structure in boot_params. setup_data is maintained in kernel
+		as a link list. In "setup_data" subdirectory there's one
+		subdirectory for each link list node named with the number
+		of the list nodes. The list node subdirectory contains two
+		files "type" and "data". "type" file is the string
+		representation of setup_data type. "data" file is the binary
+		representation of setup_data payload.
+
+		The whole boot_params directory structure is like below:
+		/sys/kernel/boot_params
+		|__ data
+		|__ setup_data
+		|   |__ 0
+		|   |   |__ data
+		|   |   |__ type
+		|   |__ 1
+		|       |__ data
+		|       |__ type
+		|__ version
+
+Users:		Kexec
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9b0a34e..510cca5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-y			+= syscall_$(BITS).o
 obj-$(CONFIG_X86_64)	+= vsyscall_64.o
 obj-$(CONFIG_X86_64)	+= vsyscall_emu_64.o
+obj-$(CONFIG_SYSFS)	+= ksysfs.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
new file mode 100644
index 0000000..eb53d15
--- /dev/null
+++ b/arch/x86/kernel/ksysfs.c
@@ -0,0 +1,339 @@
+/*
+ * Architecture specific sysfs attributes in /sys/kernel
+ *
+ * Copyright (C) 2007, Intel Corp.
+ *      Huang Ying <ying.huang@intel.com>
+ * Copyright (C) 2013, 2013 Red Hat, Inc.
+ *      Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2
+ */
+
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include <asm/setup.h>
+
+static ssize_t version_show(struct kobject *kobj,
+			    struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%04x\n", boot_params.hdr.version);
+}
+
+static struct kobj_attribute boot_params_version_attr = __ATTR_RO(version);
+
+static ssize_t boot_params_data_read(struct file *fp, struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *buf, loff_t off, size_t count)
+{
+	memcpy(buf, (void *)&boot_params + off, count);
+	return count;
+}
+
+static struct bin_attribute boot_params_data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = boot_params_data_read,
+	.size = sizeof(boot_params),
+};
+
+static struct attribute *boot_params_version_attrs[] = {
+	&boot_params_version_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *boot_params_data_attrs[] = {
+	&boot_params_data_attr,
+	NULL,
+};
+
+static struct attribute_group boot_params_attr_group = {
+	.attrs = boot_params_version_attrs,
+	.bin_attrs = boot_params_data_attrs,
+};
+
+static int kobj_to_setup_data_nr(struct kobject *kobj, int *nr)
+{
+	const char *name;
+
+	name = kobject_name(kobj);
+	return kstrtoint(name, 10, nr);
+}
+
+static int get_setup_data_paddr(int nr, u64 *paddr)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		if (nr == i) {
+			*paddr = pa_data;
+			return 0;
+		}
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static int __init get_setup_data_size(int nr, size_t *size)
+{
+	int i = 0;
+	struct setup_data *data;
+	u64 pa_data = boot_params.hdr.setup_data;
+
+	while (pa_data) {
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data)
+			return -ENOMEM;
+		if (nr == i) {
+			*size = data->len;
+			iounmap(data);
+			return 0;
+		}
+
+		pa_data = data->next;
+		iounmap(data);
+		i++;
+	}
+	return -EINVAL;
+}
+
+static ssize_t type_show(struct kobject *kobj,
+			 struct kobj_attribute *attr, char *buf)
+{
+	int nr, ret;
+	u64 paddr;
+	struct setup_data *data;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	ret = sprintf(buf, "0x%x\n", data->type);
+	iounmap(data);
+	return ret;
+}
+
+static ssize_t setup_data_data_read(struct file *fp,
+				    struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buf,
+				    loff_t off, size_t count)
+{
+	int nr, ret = 0;
+	u64 paddr;
+	struct setup_data *data;
+	void *p;
+
+	ret = kobj_to_setup_data_nr(kobj, &nr);
+	if (ret)
+		return ret;
+
+	ret = get_setup_data_paddr(nr, &paddr);
+	if (ret)
+		return ret;
+	data = ioremap_cache(paddr, sizeof(*data));
+	if (!data)
+		return -ENOMEM;
+
+	if (off > data->len) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (count > data->len - off)
+		count = data->len - off;
+
+	if (!count)
+		goto out;
+
+	ret = count;
+	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	if (!p) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	memcpy(buf, p + off, count);
+	iounmap(p);
+out:
+	iounmap(data);
+	return ret;
+}
+
+static struct kobj_attribute type_attr = __ATTR_RO(type);
+
+static struct bin_attribute data_attr = {
+	.attr = {
+		.name = "data",
+		.mode = S_IRUGO,
+	},
+	.read = setup_data_data_read,
+};
+
+static struct attribute *setup_data_type_attrs[] = {
+	&type_attr.attr,
+	NULL,
+};
+
+static struct bin_attribute *setup_data_data_attrs[] = {
+	&data_attr,
+	NULL,
+};
+
+static struct attribute_group setup_data_attr_group = {
+	.attrs = setup_data_type_attrs,
+	.bin_attrs = setup_data_data_attrs,
+};
+
+static int __init create_setup_data_node(struct kobject *parent,
+					 struct kobject **kobjp, int nr)
+{
+	int ret = 0;
+	size_t size;
+	struct kobject *kobj;
+	char name[16]; /* should be enough for setup_data nodes numbers */
+	snprintf(name, 16, "%d", nr);
+
+	kobj = kobject_create_and_add(name, parent);
+	if (!kobj)
+		return -ENOMEM;
+
+	ret = get_setup_data_size(nr, &size);
+	if (ret)
+		goto out_kobj;
+
+	data_attr.size = size;
+	ret = sysfs_create_group(kobj, &setup_data_attr_group);
+	if (ret)
+		goto out_kobj;
+	*kobjp = kobj;
+
+	return 0;
+out_kobj:
+	kobject_put(kobj);
+	return ret;
+}
+
+static void __init cleanup_setup_data_node(struct kobject *kobj)
+{
+	sysfs_remove_group(kobj, &setup_data_attr_group);
+	kobject_put(kobj);
+}
+
+static int __init get_setup_data_total_num(u64 pa_data, int *nr)
+{
+	int ret = 0;
+	struct setup_data *data;
+
+	*nr = 0;
+	while (pa_data) {
+		*nr += 1;
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		pa_data = data->next;
+		iounmap(data);
+	}
+
+out:
+	return ret;
+}
+
+static int __init create_setup_data_nodes(struct kobject *parent)
+{
+	struct kobject *setup_data_kobj, **kobjp;
+	u64 pa_data;
+	int i, j, nr, ret = 0;
+
+	pa_data = boot_params.hdr.setup_data;
+	if (!pa_data)
+		return 0;
+
+	setup_data_kobj = kobject_create_and_add("setup_data", parent);
+	if (!setup_data_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = get_setup_data_total_num(pa_data, &nr);
+	if (ret)
+		goto out_setup_data_kobj;
+
+	kobjp = kmalloc(sizeof(*kobjp) * nr, GFP_KERNEL);
+	if (!kobjp) {
+		ret = -ENOMEM;
+		goto out_setup_data_kobj;
+	}
+
+	for (i = 0; i < nr; i++) {
+		ret = create_setup_data_node(setup_data_kobj, kobjp + i, i);
+		if (ret)
+			goto out_clean_nodes;
+	}
+
+	kfree(kobjp);
+	return 0;
+
+out_clean_nodes:
+	for (j = i - 1; j > 0; j--)
+		cleanup_setup_data_node(*(kobjp + j));
+	kfree(kobjp);
+out_setup_data_kobj:
+	kobject_put(setup_data_kobj);
+out:
+	return ret;
+}
+
+static int __init boot_params_ksysfs_init(void)
+{
+	int ret;
+	struct kobject *boot_params_kobj;
+
+	boot_params_kobj = kobject_create_and_add("boot_params",
+						  kernel_kobj);
+	if (!boot_params_kobj) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sysfs_create_group(boot_params_kobj, &boot_params_attr_group);
+	if (ret)
+		goto out_boot_params_kobj;
+
+	ret = create_setup_data_nodes(boot_params_kobj);
+	if (ret)
+		goto out_create_group;
+
+	return 0;
+out_create_group:
+	sysfs_remove_group(boot_params_kobj, &boot_params_attr_group);
+out_boot_params_kobj:
+	kobject_put(boot_params_kobj);
+out:
+	return ret;
+}
+
+arch_initcall(boot_params_ksysfs_init);
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 13/14] x86: reserve setup_data ranges late after parsing memmap cmdline
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

Currently e820_reserve_setup_data is called before parsing early params,
it works in normal case. But for memmap=exactmap, the final memory ranges
are created after parsing memmap= cmdline params, so the previous
e820_reserve_setup_data has no effect. For example, setup_data ranges
will still be marked as normal system ram, thus when later sysfs driver
ioremap them kernel will warn about mapping normal ram.

This patch fix it by moving the e820_reserve_setup_data callback after
parsing early params so they can be set as reserved ranges and later
ioremap will be fine with it.

changes:
Boris: improve patch description

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 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 b2b54cd..a3357a6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -927,8 +927,6 @@ void __init setup_arch(char **cmdline_p)
 	iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
 	setup_memory_map();
 	parse_setup_data();
-	/* update the e820_saved too */
-	e820_reserve_setup_data();
 
 	copy_edd();
 
@@ -990,6 +988,8 @@ void __init setup_arch(char **cmdline_p)
 		early_dump_pci_devices();
 #endif
 
+	/* update the e820_saved too */
+	e820_reserve_setup_data();
 	finish_e820_parsing();
 
 	if (efi_enabled(EFI_BOOT))
-- 
1.8.3.1


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

* [PATCH v6 13/14] x86: reserve setup_data ranges late after parsing memmap cmdline
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

Currently e820_reserve_setup_data is called before parsing early params,
it works in normal case. But for memmap=exactmap, the final memory ranges
are created after parsing memmap= cmdline params, so the previous
e820_reserve_setup_data has no effect. For example, setup_data ranges
will still be marked as normal system ram, thus when later sysfs driver
ioremap them kernel will warn about mapping normal ram.

This patch fix it by moving the e820_reserve_setup_data callback after
parsing early params so they can be set as reserved ranges and later
ioremap will be fine with it.

changes:
Boris: improve patch description

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Acked-by: Borislav Petkov <bp-l3A5Bk7waGM@public.gmane.org>
---
 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 b2b54cd..a3357a6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -927,8 +927,6 @@ void __init setup_arch(char **cmdline_p)
 	iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
 	setup_memory_map();
 	parse_setup_data();
-	/* update the e820_saved too */
-	e820_reserve_setup_data();
 
 	copy_edd();
 
@@ -990,6 +988,8 @@ void __init setup_arch(char **cmdline_p)
 		early_dump_pci_devices();
 #endif
 
+	/* update the e820_saved too */
+	e820_reserve_setup_data();
 	finish_e820_parsing();
 
 	if (efi_enabled(EFI_BOOT))
-- 
1.8.3.1

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

* [PATCH v6 13/14] x86: reserve setup_data ranges late after parsing memmap cmdline
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

Currently e820_reserve_setup_data is called before parsing early params,
it works in normal case. But for memmap=exactmap, the final memory ranges
are created after parsing memmap= cmdline params, so the previous
e820_reserve_setup_data has no effect. For example, setup_data ranges
will still be marked as normal system ram, thus when later sysfs driver
ioremap them kernel will warn about mapping normal ram.

This patch fix it by moving the e820_reserve_setup_data callback after
parsing early params so they can be set as reserved ranges and later
ioremap will be fine with it.

changes:
Boris: improve patch description

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
 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 b2b54cd..a3357a6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -927,8 +927,6 @@ void __init setup_arch(char **cmdline_p)
 	iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
 	setup_memory_map();
 	parse_setup_data();
-	/* update the e820_saved too */
-	e820_reserve_setup_data();
 
 	copy_edd();
 
@@ -990,6 +988,8 @@ void __init setup_arch(char **cmdline_p)
 		early_dump_pci_devices();
 #endif
 
+	/* update the e820_saved too */
+	e820_reserve_setup_data();
 	finish_e820_parsing();
 
 	if (efi_enabled(EFI_BOOT))
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
work in case memmap=exactmap, so let's always use ioremap_cache.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404b..185e1ca 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -33,7 +33,6 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	struct setup_data_node *node = file->private_data;
 	unsigned long remain;
 	loff_t pos = *ppos;
-	struct page *pg;
 	void *p;
 	u64 pa;
 
@@ -47,18 +46,12 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 		count = node->len - pos;
 
 	pa = node->paddr + sizeof(struct setup_data) + pos;
-	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
-	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
-		if (!p)
-			return -ENXIO;
-	} else
-		p = __va(pa);
+	p = ioremap_cache(pa, count);
+	if (!p)
+		return -ENXIO;
 
 	remain = copy_to_user(user_buf, p, count);
-
-	if (PageHighMem(pg))
-		iounmap(p);
+	iounmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -109,7 +102,6 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 	struct setup_data *data;
 	int error;
 	struct dentry *d;
-	struct page *pg;
 	u64 pa_data;
 	int no = 0;
 
@@ -126,16 +118,12 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 			goto err_dir;
 		}
 
-		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
-		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
-			if (!data) {
-				kfree(node);
-				error = -ENXIO;
-				goto err_dir;
-			}
-		} else
-			data = __va(pa_data);
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			kfree(node);
+			error = -ENXIO;
+			goto err_dir;
+		}
 
 		node->paddr = pa_data;
 		node->type = data->type;
@@ -143,8 +131,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		error = create_setup_data_node(d, no, node);
 		pa_data = data->next;
 
-		if (PageHighMem(pg))
-			iounmap(data);
+		iounmap(data);
 		if (error)
 			goto err_dir;
 		no++;
-- 
1.8.3.1


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

* [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
work in case memmap=exactmap, so let's always use ioremap_cache.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404b..185e1ca 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -33,7 +33,6 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	struct setup_data_node *node = file->private_data;
 	unsigned long remain;
 	loff_t pos = *ppos;
-	struct page *pg;
 	void *p;
 	u64 pa;
 
@@ -47,18 +46,12 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 		count = node->len - pos;
 
 	pa = node->paddr + sizeof(struct setup_data) + pos;
-	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
-	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
-		if (!p)
-			return -ENXIO;
-	} else
-		p = __va(pa);
+	p = ioremap_cache(pa, count);
+	if (!p)
+		return -ENXIO;
 
 	remain = copy_to_user(user_buf, p, count);
-
-	if (PageHighMem(pg))
-		iounmap(p);
+	iounmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -109,7 +102,6 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 	struct setup_data *data;
 	int error;
 	struct dentry *d;
-	struct page *pg;
 	u64 pa_data;
 	int no = 0;
 
@@ -126,16 +118,12 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 			goto err_dir;
 		}
 
-		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
-		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
-			if (!data) {
-				kfree(node);
-				error = -ENXIO;
-				goto err_dir;
-			}
-		} else
-			data = __va(pa_data);
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			kfree(node);
+			error = -ENXIO;
+			goto err_dir;
+		}
 
 		node->paddr = pa_data;
 		node->type = data->type;
@@ -143,8 +131,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		error = create_setup_data_node(d, no, node);
 		pa_data = data->next;
 
-		if (PageHighMem(pg))
-			iounmap(data);
+		iounmap(data);
 		if (error)
 			goto err_dir;
 		no++;
-- 
1.8.3.1

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

* [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16  9:30   ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-16  9:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
work in case memmap=exactmap, so let's always use ioremap_cache.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404b..185e1ca 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -33,7 +33,6 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	struct setup_data_node *node = file->private_data;
 	unsigned long remain;
 	loff_t pos = *ppos;
-	struct page *pg;
 	void *p;
 	u64 pa;
 
@@ -47,18 +46,12 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 		count = node->len - pos;
 
 	pa = node->paddr + sizeof(struct setup_data) + pos;
-	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
-	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
-		if (!p)
-			return -ENXIO;
-	} else
-		p = __va(pa);
+	p = ioremap_cache(pa, count);
+	if (!p)
+		return -ENXIO;
 
 	remain = copy_to_user(user_buf, p, count);
-
-	if (PageHighMem(pg))
-		iounmap(p);
+	iounmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -109,7 +102,6 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 	struct setup_data *data;
 	int error;
 	struct dentry *d;
-	struct page *pg;
 	u64 pa_data;
 	int no = 0;
 
@@ -126,16 +118,12 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 			goto err_dir;
 		}
 
-		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
-		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
-			if (!data) {
-				kfree(node);
-				error = -ENXIO;
-				goto err_dir;
-			}
-		} else
-			data = __va(pa_data);
+		data = ioremap_cache(pa_data, sizeof(*data));
+		if (!data) {
+			kfree(node);
+			error = -ENXIO;
+			goto err_dir;
+		}
 
 		node->paddr = pa_data;
 		node->type = data->type;
@@ -143,8 +131,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		error = create_setup_data_node(d, no, node);
 		pa_data = data->next;
 
-		if (PageHighMem(pg))
-			iounmap(data);
+		iounmap(data);
 		if (error)
 			goto err_dir;
 		no++;
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-16 15:09     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 15:09 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
>  		return;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> +			      boot_params.efi_info.efi_memdesc_size);
> +#endif

[...]

> @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
>  		goto err_unregister;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	error = efi_runtime_map_init(efi_kobj);
> +	if (error)
> +		goto err_remove_group;
> +#endif

[...]

> @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
>  
>  #endif /* CONFIG_EFI_VARS */
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +int efi_runtime_map_init(struct kobject *);
> +void efi_runtime_map_setup(void *, int, u32);
> +#endif

I was thinking more along the lines of...

---

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 120086820654..fd5a0aad1fff 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -928,10 +928,8 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
 			      boot_params.efi_info.efi_memdesc_size);
-#endif
 
 	BUG_ON(!efi.systab);
 
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 4109dca787dc..4753bac65279 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,11 +167,9 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	error = efi_runtime_map_init(efi_kobj);
 	if (error)
 		goto err_remove_group;
-#endif
 
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a98eb0621583..e64540746c63 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -875,6 +875,14 @@ int efivars_sysfs_init(void);
 #ifdef CONFIG_EFI_RUNTIME_MAP
 int efi_runtime_map_init(struct kobject *);
 void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
 #endif
 
 #endif /* _LINUX_EFI_H */

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-16 15:09     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 15:09 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	toshi.kani-VXdhtT5mjnY, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
>  		return;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> +			      boot_params.efi_info.efi_memdesc_size);
> +#endif

[...]

> @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
>  		goto err_unregister;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	error = efi_runtime_map_init(efi_kobj);
> +	if (error)
> +		goto err_remove_group;
> +#endif

[...]

> @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
>  
>  #endif /* CONFIG_EFI_VARS */
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +int efi_runtime_map_init(struct kobject *);
> +void efi_runtime_map_setup(void *, int, u32);
> +#endif

I was thinking more along the lines of...

---

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 120086820654..fd5a0aad1fff 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -928,10 +928,8 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
 			      boot_params.efi_info.efi_memdesc_size);
-#endif
 
 	BUG_ON(!efi.systab);
 
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 4109dca787dc..4753bac65279 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,11 +167,9 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	error = efi_runtime_map_init(efi_kobj);
 	if (error)
 		goto err_remove_group;
-#endif
 
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a98eb0621583..e64540746c63 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -875,6 +875,14 @@ int efivars_sysfs_init(void);
 #ifdef CONFIG_EFI_RUNTIME_MAP
 int efi_runtime_map_init(struct kobject *);
 void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
 #endif
 
 #endif /* _LINUX_EFI_H */

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-16 15:09     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 15:09 UTC (permalink / raw)
  To: Dave Young
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
>  		return;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> +			      boot_params.efi_info.efi_memdesc_size);
> +#endif

[...]

> @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
>  		goto err_unregister;
>  	}
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +	error = efi_runtime_map_init(efi_kobj);
> +	if (error)
> +		goto err_remove_group;
> +#endif

[...]

> @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
>  
>  #endif /* CONFIG_EFI_VARS */
>  
> +#ifdef CONFIG_EFI_RUNTIME_MAP
> +int efi_runtime_map_init(struct kobject *);
> +void efi_runtime_map_setup(void *, int, u32);
> +#endif

I was thinking more along the lines of...

---

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 120086820654..fd5a0aad1fff 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -928,10 +928,8 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
 			      boot_params.efi_info.efi_memdesc_size);
-#endif
 
 	BUG_ON(!efi.systab);
 
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 4109dca787dc..4753bac65279 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,11 +167,9 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
-#ifdef CONFIG_EFI_RUNTIME_MAP
 	error = efi_runtime_map_init(efi_kobj);
 	if (error)
 		goto err_remove_group;
-#endif
 
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a98eb0621583..e64540746c63 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -875,6 +875,14 @@ int efivars_sysfs_init(void);
 #ifdef CONFIG_EFI_RUNTIME_MAP
 int efi_runtime_map_init(struct kobject *);
 void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
 #endif
 
 #endif /* _LINUX_EFI_H */

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16 16:35     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 16:35 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> work in case memmap=exactmap, so let's always use ioremap_cache.
> 
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
>  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
>  1 file changed, 11 insertions(+), 24 deletions(-)

Dave, I've no idea why this change is necessary from the commit log. Is
it required for kexec to function on EFI? Why does __va() not work in
the memmap=exactmap case?

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16 16:35     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 16:35 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	toshi.kani-VXdhtT5mjnY, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> work in case memmap=exactmap, so let's always use ioremap_cache.
> 
> Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
>  1 file changed, 11 insertions(+), 24 deletions(-)

Dave, I've no idea why this change is necessary from the commit log. Is
it required for kexec to function on EFI? Why does __va() not work in
the memmap=exactmap case?

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-16 16:35     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-16 16:35 UTC (permalink / raw)
  To: Dave Young
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> work in case memmap=exactmap, so let's always use ioremap_cache.
> 
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
>  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
>  1 file changed, 11 insertions(+), 24 deletions(-)

Dave, I've no idea why this change is necessary from the commit log. Is
it required for kexec to function on EFI? Why does __va() not work in
the memmap=exactmap case?

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  6:13       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:13 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On 12/16/13 at 03:09pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> > @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
> >  		return;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> > +			      boot_params.efi_info.efi_memdesc_size);
> > +#endif
> 
> [...]
> 
> > @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
> >  		goto err_unregister;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	error = efi_runtime_map_init(efi_kobj);
> > +	if (error)
> > +		goto err_remove_group;
> > +#endif
> 
> [...]
> 
> > @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
> >  
> >  #endif /* CONFIG_EFI_VARS */
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +int efi_runtime_map_init(struct kobject *);
> > +void efi_runtime_map_setup(void *, int, u32);
> > +#endif
> 
> I was thinking more along the lines of...

Previously I only call the function conditionally thus there's
compiler warning about "unused function" for the #else

unconditionally call it build will be ok. Will update this patch.

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  6:13       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:13 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

On 12/16/13 at 03:09pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> > @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
> >  		return;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> > +			      boot_params.efi_info.efi_memdesc_size);
> > +#endif
> 
> [...]
> 
> > @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
> >  		goto err_unregister;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	error = efi_runtime_map_init(efi_kobj);
> > +	if (error)
> > +		goto err_remove_group;
> > +#endif
> 
> [...]
> 
> > @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
> >  
> >  #endif /* CONFIG_EFI_VARS */
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +int efi_runtime_map_init(struct kobject *);
> > +void efi_runtime_map_setup(void *, int, u32);
> > +#endif
> 
> I was thinking more along the lines of...

Previously I only call the function conditionally thus there's
compiler warning about "unused function" for the #else

unconditionally call it build will be ok. Will update this patch.

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

* Re: [PATCH v6 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  6:13       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:13 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On 12/16/13 at 03:09pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:29PM, Dave Young wrote:
> > @@ -899,6 +928,11 @@ void __init efi_enter_virtual_mode(void)
> >  		return;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
> > +			      boot_params.efi_info.efi_memdesc_size);
> > +#endif
> 
> [...]
> 
> > @@ -167,6 +167,12 @@ static int __init efisubsys_init(void)
> >  		goto err_unregister;
> >  	}
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +	error = efi_runtime_map_init(efi_kobj);
> > +	if (error)
> > +		goto err_remove_group;
> > +#endif
> 
> [...]
> 
> > @@ -876,4 +876,9 @@ int efivars_sysfs_init(void);
> >  
> >  #endif /* CONFIG_EFI_VARS */
> >  
> > +#ifdef CONFIG_EFI_RUNTIME_MAP
> > +int efi_runtime_map_init(struct kobject *);
> > +void efi_runtime_map_setup(void *, int, u32);
> > +#endif
> 
> I was thinking more along the lines of...

Previously I only call the function conditionally thus there's
compiler warning about "unused function" for the #else

unconditionally call it build will be ok. Will update this patch.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:24       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:24 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On 12/16/13 at 04:35pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > work in case memmap=exactmap, so let's always use ioremap_cache.
> > 
> > Signed-off-by: Dave Young <dyoung@redhat.com>
> > ---
> >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> >  1 file changed, 11 insertions(+), 24 deletions(-)
> 
> Dave, I've no idea why this change is necessary from the commit log. Is
> it required for kexec to function on EFI? Why does __va() not work in
> the memmap=exactmap case?
> 

During previous kdump tests I saw panics while reading the setup_data in debugfs.
I thought it is caused by some unmapped addresses. At that time I also reproduced
it by booting the non-kexec kernel with memmap=exact.

Since you are asking about this I'm testing it again but I seems can not
reproduce this problem any more, it's weird.

I should dug more about it and save the panic messages.

So let's drop this patch for now, I will keep an eye on this and address it later
if I can find the problem again.

--
Thanks
Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:24       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:24 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

On 12/16/13 at 04:35pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > work in case memmap=exactmap, so let's always use ioremap_cache.
> > 
> > Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > ---
> >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> >  1 file changed, 11 insertions(+), 24 deletions(-)
> 
> Dave, I've no idea why this change is necessary from the commit log. Is
> it required for kexec to function on EFI? Why does __va() not work in
> the memmap=exactmap case?
> 

During previous kdump tests I saw panics while reading the setup_data in debugfs.
I thought it is caused by some unmapped addresses. At that time I also reproduced
it by booting the non-kexec kernel with memmap=exact.

Since you are asking about this I'm testing it again but I seems can not
reproduce this problem any more, it's weird.

I should dug more about it and save the panic messages.

So let's drop this patch for now, I will keep an eye on this and address it later
if I can find the problem again.

--
Thanks
Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:24       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:24 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On 12/16/13 at 04:35pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > work in case memmap=exactmap, so let's always use ioremap_cache.
> > 
> > Signed-off-by: Dave Young <dyoung@redhat.com>
> > ---
> >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> >  1 file changed, 11 insertions(+), 24 deletions(-)
> 
> Dave, I've no idea why this change is necessary from the commit log. Is
> it required for kexec to function on EFI? Why does __va() not work in
> the memmap=exactmap case?
> 

During previous kdump tests I saw panics while reading the setup_data in debugfs.
I thought it is caused by some unmapped addresses. At that time I also reproduced
it by booting the non-kexec kernel with memmap=exact.

Since you are asking about this I'm testing it again but I seems can not
reproduce this problem any more, it's weird.

I should dug more about it and save the panic messages.

So let's drop this patch for now, I will keep an eye on this and address it later
if I can find the problem again.

--
Thanks
Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:53         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:53 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On 12/17/13 at 02:24pm, Dave Young wrote:
> On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > 
> > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > ---
> > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > 
> > Dave, I've no idea why this change is necessary from the commit log. Is
> > it required for kexec to function on EFI? Why does __va() not work in
> > the memmap=exactmap case?
> > 
> 
> During previous kdump tests I saw panics while reading the setup_data in debugfs.
> I thought it is caused by some unmapped addresses. At that time I also reproduced
> it by booting the non-kexec kernel with memmap=exact.
> 
> Since you are asking about this I'm testing it again but I seems can not
> reproduce this problem any more, it's weird.
> 
> I should dug more about it and save the panic messages.
> 
> So let's drop this patch for now, I will keep an eye on this and address it later
> if I can find the problem again.

Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
case, I remember I saw this in kdump kernel, but I still did not see it in today's
testing so I think move this issue out of this patch series is fine to me.

[    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
[    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359474] PGD 316b067 PUD 37031063 PMD 0 
[    0.359476] Oops: 0000 [#1] PREEMPT SMP 
[    0.359477] Modules linked in:
[    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
[    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
[    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
[    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
[    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
[    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
[    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
[    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
[    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
[    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
[    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
[    0.359492] Stack:
[    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
[    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
[    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
[    0.359499] Call Trace:
[    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
[    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
[    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
[    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
[    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
[    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
[    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
[    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
[    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
[    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
[    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
[    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359550]  RSP <ffff880037189e30>
[    0.359550] CR2: ffff8800d5592020
[    0.359559] ---[ end trace d52b3fbe64a26115 ]---
[    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
[    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    0.628021] 




> 
> --
> Thanks
> Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:53         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:53 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

On 12/17/13 at 02:24pm, Dave Young wrote:
> On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > 
> > > Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > ---
> > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > 
> > Dave, I've no idea why this change is necessary from the commit log. Is
> > it required for kexec to function on EFI? Why does __va() not work in
> > the memmap=exactmap case?
> > 
> 
> During previous kdump tests I saw panics while reading the setup_data in debugfs.
> I thought it is caused by some unmapped addresses. At that time I also reproduced
> it by booting the non-kexec kernel with memmap=exact.
> 
> Since you are asking about this I'm testing it again but I seems can not
> reproduce this problem any more, it's weird.
> 
> I should dug more about it and save the panic messages.
> 
> So let's drop this patch for now, I will keep an eye on this and address it later
> if I can find the problem again.

Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
case, I remember I saw this in kdump kernel, but I still did not see it in today's
testing so I think move this issue out of this patch series is fine to me.

[    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
[    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359474] PGD 316b067 PUD 37031063 PMD 0 
[    0.359476] Oops: 0000 [#1] PREEMPT SMP 
[    0.359477] Modules linked in:
[    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
[    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
[    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
[    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
[    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
[    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
[    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
[    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
[    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
[    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
[    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
[    0.359492] Stack:
[    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
[    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
[    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
[    0.359499] Call Trace:
[    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
[    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
[    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
[    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
[    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
[    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
[    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
[    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
[    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
[    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
[    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
[    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359550]  RSP <ffff880037189e30>
[    0.359550] CR2: ffff8800d5592020
[    0.359559] ---[ end trace d52b3fbe64a26115 ]---
[    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
[    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    0.628021] 




> 
> --
> Thanks
> Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17  6:53         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  6:53 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On 12/17/13 at 02:24pm, Dave Young wrote:
> On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > 
> > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > ---
> > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > 
> > Dave, I've no idea why this change is necessary from the commit log. Is
> > it required for kexec to function on EFI? Why does __va() not work in
> > the memmap=exactmap case?
> > 
> 
> During previous kdump tests I saw panics while reading the setup_data in debugfs.
> I thought it is caused by some unmapped addresses. At that time I also reproduced
> it by booting the non-kexec kernel with memmap=exact.
> 
> Since you are asking about this I'm testing it again but I seems can not
> reproduce this problem any more, it's weird.
> 
> I should dug more about it and save the panic messages.
> 
> So let's drop this patch for now, I will keep an eye on this and address it later
> if I can find the problem again.

Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
case, I remember I saw this in kdump kernel, but I still did not see it in today's
testing so I think move this issue out of this patch series is fine to me.

[    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
[    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359474] PGD 316b067 PUD 37031063 PMD 0 
[    0.359476] Oops: 0000 [#1] PREEMPT SMP 
[    0.359477] Modules linked in:
[    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
[    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
[    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
[    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
[    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
[    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
[    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
[    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
[    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
[    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
[    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
[    0.359492] Stack:
[    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
[    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
[    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
[    0.359499] Call Trace:
[    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
[    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
[    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
[    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
[    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
[    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
[    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
[    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
[    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
[    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
[    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
[    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
[    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
[    0.359550]  RSP <ffff880037189e30>
[    0.359550] CR2: ffff8800d5592020
[    0.359559] ---[ end trace d52b3fbe64a26115 ]---
[    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
[    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    0.628021] 




> 
> --
> Thanks
> Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* [PATCH v7 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  8:00     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm

From: Dave Young <dyoung@redhat.com>
Date: Tue, 26 Nov 2013 10:10:23 +0800
Subject: [PATCH 08/13] efi: export efi runtime memory mapping to sysfs

kexec kernel will need exactly same mapping for
efi runtime memory ranges. Thus here export the
runtime ranges mapping to sysfs, kexec-tools
will assemble them and pass to 2nd kernel via
setup_data.

Introducing a new directory /sys/firmware/efi/runtime-map
Just like /sys/firmware/memmap. Containing below attribute
in each file of that directory:
attribute  num_pages  phys_addr  type  virt_addr

Changelog:
 - Cleaup code, add function efi_save_runtime_map
 - Improve err handling
 - Add macros for sysfs _show functions
 - Remove forward declarations.
 Matt:
 - s/efi-runtime-map.c/runtime-map.c
 - Change dir name to runtime-map
 - Changelog and documentation fixes.
 - Documentation fixes.
 - Update to use desc_size in efi_runtime_map
 - Kconfig EFI_RUNTIME_MAP depends on X86 && KEXEC && EFI
 Boris:
 - Documentation grammar/spelling fix
 - krealloc fix.
 - Move efi_runtime_map_init to efisubsys_initcall.
 - Remove 'if EXPERT' for EFI_RUNTIME_MAP Kconfig option
 - save_runtime_map: move error handling code into the function itself.
 - other code improvement.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++++
 arch/x86/platform/efi/efi.c                        |  36 +++-
 drivers/firmware/efi/Kconfig                       |  11 ++
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |   4 +
 drivers/firmware/efi/runtime-map.c                 | 181 +++++++++++++++++++++
 include/linux/efi.h                                |  13 ++
 7 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 drivers/firmware/efi/runtime-map.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
new file mode 100644
index 0000000..c61b9b3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
@@ -0,0 +1,34 @@
+What:		/sys/firmware/efi/runtime-map/
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	Switching efi runtime services to virtual mode requires
+		that all efi memory ranges which have the runtime attribute
+		bit set to be mapped to virtual addresses.
+
+		The efi runtime services can only be switched to virtual
+		mode once without rebooting. The kexec kernel must maintain
+		the same physical to virtual address mappings as the first
+		kernel. The mappings are exported to sysfs so userspace tools
+		can reassemble them and pass them into the kexec kernel.
+
+		/sys/firmware/efi/runtime-map/ is the directory the kernel
+		exports that information in.
+
+		subdirectories are named with the number of the memory range:
+
+			/sys/firmware/efi/runtime-map/0
+			/sys/firmware/efi/runtime-map/1
+			/sys/firmware/efi/runtime-map/2
+			/sys/firmware/efi/runtime-map/3
+			...
+
+		Each subdirectory contains five files:
+
+		attribute : The attributes of the memory range.
+		num_pages : The size of the memory range in pages.
+		phys_addr : The physical address of the memory range.
+		type      : The type of the memory range.
+		virt_addr : The virtual address of the memory range.
+
+		Above values are all hexadecimal numbers with the '0x' prefix.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3e8b760..b1fff8e 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 	{NULL_GUID, NULL, NULL},
 };
 
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -810,6 +813,24 @@ static void __init efi_merge_regions(void)
 	}
 }
 
+static int __init save_runtime_map(efi_memory_desc_t *md, int idx)
+{
+	void *p;
+	p = krealloc(efi_runtime_map, (idx + 1) * memmap.desc_size, GFP_KERNEL);
+	if (!p)
+		goto out;
+
+	efi_runtime_map = p;
+	memcpy(efi_runtime_map + idx * memmap.desc_size, md, memmap.desc_size);
+
+	return 0;
+out:
+	kfree(efi_runtime_map);
+	efi_runtime_map = NULL;
+	nr_efi_runtime_map = 0;
+	return -ENOMEM;
+}
+
 /*
  * Map efi memory ranges for runtime serivce and update new_memmap with virtual
  * addresses.
@@ -820,6 +841,7 @@ static void * __init efi_map_regions(int *count)
 	void *p, *tmp, *new_memmap = NULL;
 	unsigned long size;
 	u64 end, systab;
+	int err = 0;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -844,15 +866,22 @@ static void * __init efi_map_regions(int *count)
 		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
 			       GFP_KERNEL);
 		if (!tmp)
-			goto out_krealloc;
+			goto out;
 		new_memmap = tmp;
 		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA) {
+			err = save_runtime_map(md, nr_efi_runtime_map);
+			if (err)
+				goto out;
+			nr_efi_runtime_map++;
+		}
 		(*count)++;
 	}
 
 	return new_memmap;
-out_krealloc:
+out:
 	kfree(new_memmap);
 	return NULL;
 }
@@ -899,6 +928,9 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
+	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
+			      boot_params.efi_info.efi_memdesc_size);
+
 	BUG_ON(!efi.systab);
 
 	efi_setup_page_tables();
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..730f5f2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -39,4 +39,15 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
 config UEFI_CPER
 	def_bool n
 
+config EFI_RUNTIME_MAP
+	bool "Export efi runtime maps to sysfs"
+	depends on X86 && EFI && KEXEC
+	default y
+	help
+	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
+	  That memory map is used for example by kexec to set up efi virtual
+	  mapping the 2nd kernel, but can also be used for debugging purposes.
+
+	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..a58e0f1 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -5,3 +5,4 @@ obj-y					+= efi.o vars.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
+obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 6d0bc52..7910cd5 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,6 +167,10 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
+	error = efi_runtime_map_init(efi_kobj);
+	if (error)
+		goto err_remove_group;
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
new file mode 100644
index 0000000..97cdd16
--- /dev/null
+++ b/drivers/firmware/efi/runtime-map.c
@@ -0,0 +1,181 @@
+/*
+ * linux/drivers/efi/runtime-map.c
+ * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+static u32 efi_memdesc_size;
+
+struct efi_runtime_map_entry {
+	efi_memory_desc_t md;
+	struct kobject kobj;   /* kobject for each entry */
+};
+
+static struct efi_runtime_map_entry **map_entries;
+
+struct map_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
+};
+
+static inline struct map_attribute *to_map_attr(struct attribute *attr)
+{
+	return container_of(attr, struct map_attribute, attr);
+}
+
+static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
+}
+
+#define EFI_RUNTIME_FIELD(var) entry->md.var
+
+#define EFI_RUNTIME_U64_ATTR_SHOW(name) \
+static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
+{ \
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
+}
+
+EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
+EFI_RUNTIME_U64_ATTR_SHOW(attribute);
+
+static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct efi_runtime_map_entry, kobj);
+}
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *buf)
+{
+	struct efi_runtime_map_entry *entry = to_map_entry(kobj);
+	struct map_attribute *map_attr = to_map_attr(attr);
+
+	return map_attr->show(entry, buf);
+}
+
+static struct map_attribute map_type_attr = __ATTR_RO(type);
+static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
+static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
+static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
+static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&map_type_attr.attr,
+	&map_phys_addr_attr.attr,
+	&map_virt_addr_attr.attr,
+	&map_num_pages_attr.attr,
+	&map_attribute_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops map_attr_ops = {
+	.show = map_attr_show,
+};
+
+static void map_release(struct kobject *kobj)
+{
+	struct efi_runtime_map_entry *entry;
+
+	entry = to_map_entry(kobj);
+	kfree(entry);
+}
+
+static struct kobj_type __refdata map_ktype = {
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= def_attrs,
+	.release	= map_release,
+};
+
+static struct kset *map_kset;
+
+static struct efi_runtime_map_entry *
+add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
+{
+	int ret;
+	struct efi_runtime_map_entry *entry;
+
+	if (!map_kset) {
+		map_kset = kset_create_and_add("runtime-map", NULL, kobj);
+		if (!map_kset)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		kset_unregister(map_kset);
+		return entry;
+	}
+
+	memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
+	       sizeof(efi_memory_desc_t));
+
+	kobject_init(&entry->kobj, &map_ktype);
+	entry->kobj.kset = map_kset;
+	ret = kobject_add(&entry->kobj, NULL, "%d", nr);
+	if (ret) {
+		kobject_put(&entry->kobj);
+		kset_unregister(map_kset);
+		return ERR_PTR(ret);
+	}
+
+	return entry;
+}
+
+void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
+{
+	efi_runtime_map = map;
+	nr_efi_runtime_map = nr_entries;
+	efi_memdesc_size = desc_size;
+}
+
+int __init efi_runtime_map_init(struct kobject *efi_kobj)
+{
+	int i, j, ret = 0;
+	struct efi_runtime_map_entry *entry;
+
+	if (!efi_runtime_map)
+		return 0;
+
+	map_entries = kzalloc(nr_efi_runtime_map * sizeof(entry), GFP_KERNEL);
+	if (!map_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < nr_efi_runtime_map; i++) {
+		entry = add_sysfs_runtime_map_entry(efi_kobj, i);
+		if (IS_ERR(entry)) {
+			ret = PTR_ERR(entry);
+			goto out_add_entry;
+		}
+		*(map_entries + i) = entry;
+	}
+
+	return 0;
+out_add_entry:
+	for (j = i - 1; j > 0; j--) {
+		entry = *(map_entries + j);
+		kobject_put(&entry->kobj);
+	}
+	if (map_kset)
+		kset_unregister(map_kset);
+out:
+	return ret;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 988af61..0a819e7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,4 +876,17 @@ int efivars_sysfs_init(void);
 
 #endif /* CONFIG_EFI_VARS */
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+int efi_runtime_map_init(struct kobject *);
+void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
+#endif
+
 #endif /* _LINUX_EFI_H */
-- 
1.8.3.1


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

* [PATCH v7 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  8:00     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:00 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

From: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date: Tue, 26 Nov 2013 10:10:23 +0800
Subject: [PATCH 08/13] efi: export efi runtime memory mapping to sysfs

kexec kernel will need exactly same mapping for
efi runtime memory ranges. Thus here export the
runtime ranges mapping to sysfs, kexec-tools
will assemble them and pass to 2nd kernel via
setup_data.

Introducing a new directory /sys/firmware/efi/runtime-map
Just like /sys/firmware/memmap. Containing below attribute
in each file of that directory:
attribute  num_pages  phys_addr  type  virt_addr

Changelog:
 - Cleaup code, add function efi_save_runtime_map
 - Improve err handling
 - Add macros for sysfs _show functions
 - Remove forward declarations.
 Matt:
 - s/efi-runtime-map.c/runtime-map.c
 - Change dir name to runtime-map
 - Changelog and documentation fixes.
 - Documentation fixes.
 - Update to use desc_size in efi_runtime_map
 - Kconfig EFI_RUNTIME_MAP depends on X86 && KEXEC && EFI
 Boris:
 - Documentation grammar/spelling fix
 - krealloc fix.
 - Move efi_runtime_map_init to efisubsys_initcall.
 - Remove 'if EXPERT' for EFI_RUNTIME_MAP Kconfig option
 - save_runtime_map: move error handling code into the function itself.
 - other code improvement.

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++++
 arch/x86/platform/efi/efi.c                        |  36 +++-
 drivers/firmware/efi/Kconfig                       |  11 ++
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |   4 +
 drivers/firmware/efi/runtime-map.c                 | 181 +++++++++++++++++++++
 include/linux/efi.h                                |  13 ++
 7 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 drivers/firmware/efi/runtime-map.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
new file mode 100644
index 0000000..c61b9b3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
@@ -0,0 +1,34 @@
+What:		/sys/firmware/efi/runtime-map/
+Date:		December 2013
+Contact:	Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+Description:	Switching efi runtime services to virtual mode requires
+		that all efi memory ranges which have the runtime attribute
+		bit set to be mapped to virtual addresses.
+
+		The efi runtime services can only be switched to virtual
+		mode once without rebooting. The kexec kernel must maintain
+		the same physical to virtual address mappings as the first
+		kernel. The mappings are exported to sysfs so userspace tools
+		can reassemble them and pass them into the kexec kernel.
+
+		/sys/firmware/efi/runtime-map/ is the directory the kernel
+		exports that information in.
+
+		subdirectories are named with the number of the memory range:
+
+			/sys/firmware/efi/runtime-map/0
+			/sys/firmware/efi/runtime-map/1
+			/sys/firmware/efi/runtime-map/2
+			/sys/firmware/efi/runtime-map/3
+			...
+
+		Each subdirectory contains five files:
+
+		attribute : The attributes of the memory range.
+		num_pages : The size of the memory range in pages.
+		phys_addr : The physical address of the memory range.
+		type      : The type of the memory range.
+		virt_addr : The virtual address of the memory range.
+
+		Above values are all hexadecimal numbers with the '0x' prefix.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3e8b760..b1fff8e 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 	{NULL_GUID, NULL, NULL},
 };
 
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -810,6 +813,24 @@ static void __init efi_merge_regions(void)
 	}
 }
 
+static int __init save_runtime_map(efi_memory_desc_t *md, int idx)
+{
+	void *p;
+	p = krealloc(efi_runtime_map, (idx + 1) * memmap.desc_size, GFP_KERNEL);
+	if (!p)
+		goto out;
+
+	efi_runtime_map = p;
+	memcpy(efi_runtime_map + idx * memmap.desc_size, md, memmap.desc_size);
+
+	return 0;
+out:
+	kfree(efi_runtime_map);
+	efi_runtime_map = NULL;
+	nr_efi_runtime_map = 0;
+	return -ENOMEM;
+}
+
 /*
  * Map efi memory ranges for runtime serivce and update new_memmap with virtual
  * addresses.
@@ -820,6 +841,7 @@ static void * __init efi_map_regions(int *count)
 	void *p, *tmp, *new_memmap = NULL;
 	unsigned long size;
 	u64 end, systab;
+	int err = 0;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -844,15 +866,22 @@ static void * __init efi_map_regions(int *count)
 		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
 			       GFP_KERNEL);
 		if (!tmp)
-			goto out_krealloc;
+			goto out;
 		new_memmap = tmp;
 		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA) {
+			err = save_runtime_map(md, nr_efi_runtime_map);
+			if (err)
+				goto out;
+			nr_efi_runtime_map++;
+		}
 		(*count)++;
 	}
 
 	return new_memmap;
-out_krealloc:
+out:
 	kfree(new_memmap);
 	return NULL;
 }
@@ -899,6 +928,9 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
+	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
+			      boot_params.efi_info.efi_memdesc_size);
+
 	BUG_ON(!efi.systab);
 
 	efi_setup_page_tables();
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..730f5f2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -39,4 +39,15 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
 config UEFI_CPER
 	def_bool n
 
+config EFI_RUNTIME_MAP
+	bool "Export efi runtime maps to sysfs"
+	depends on X86 && EFI && KEXEC
+	default y
+	help
+	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
+	  That memory map is used for example by kexec to set up efi virtual
+	  mapping the 2nd kernel, but can also be used for debugging purposes.
+
+	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..a58e0f1 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -5,3 +5,4 @@ obj-y					+= efi.o vars.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
+obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 6d0bc52..7910cd5 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,6 +167,10 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
+	error = efi_runtime_map_init(efi_kobj);
+	if (error)
+		goto err_remove_group;
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
new file mode 100644
index 0000000..97cdd16
--- /dev/null
+++ b/drivers/firmware/efi/runtime-map.c
@@ -0,0 +1,181 @@
+/*
+ * linux/drivers/efi/runtime-map.c
+ * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+static u32 efi_memdesc_size;
+
+struct efi_runtime_map_entry {
+	efi_memory_desc_t md;
+	struct kobject kobj;   /* kobject for each entry */
+};
+
+static struct efi_runtime_map_entry **map_entries;
+
+struct map_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
+};
+
+static inline struct map_attribute *to_map_attr(struct attribute *attr)
+{
+	return container_of(attr, struct map_attribute, attr);
+}
+
+static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
+}
+
+#define EFI_RUNTIME_FIELD(var) entry->md.var
+
+#define EFI_RUNTIME_U64_ATTR_SHOW(name) \
+static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
+{ \
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
+}
+
+EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
+EFI_RUNTIME_U64_ATTR_SHOW(attribute);
+
+static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct efi_runtime_map_entry, kobj);
+}
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *buf)
+{
+	struct efi_runtime_map_entry *entry = to_map_entry(kobj);
+	struct map_attribute *map_attr = to_map_attr(attr);
+
+	return map_attr->show(entry, buf);
+}
+
+static struct map_attribute map_type_attr = __ATTR_RO(type);
+static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
+static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
+static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
+static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&map_type_attr.attr,
+	&map_phys_addr_attr.attr,
+	&map_virt_addr_attr.attr,
+	&map_num_pages_attr.attr,
+	&map_attribute_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops map_attr_ops = {
+	.show = map_attr_show,
+};
+
+static void map_release(struct kobject *kobj)
+{
+	struct efi_runtime_map_entry *entry;
+
+	entry = to_map_entry(kobj);
+	kfree(entry);
+}
+
+static struct kobj_type __refdata map_ktype = {
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= def_attrs,
+	.release	= map_release,
+};
+
+static struct kset *map_kset;
+
+static struct efi_runtime_map_entry *
+add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
+{
+	int ret;
+	struct efi_runtime_map_entry *entry;
+
+	if (!map_kset) {
+		map_kset = kset_create_and_add("runtime-map", NULL, kobj);
+		if (!map_kset)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		kset_unregister(map_kset);
+		return entry;
+	}
+
+	memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
+	       sizeof(efi_memory_desc_t));
+
+	kobject_init(&entry->kobj, &map_ktype);
+	entry->kobj.kset = map_kset;
+	ret = kobject_add(&entry->kobj, NULL, "%d", nr);
+	if (ret) {
+		kobject_put(&entry->kobj);
+		kset_unregister(map_kset);
+		return ERR_PTR(ret);
+	}
+
+	return entry;
+}
+
+void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
+{
+	efi_runtime_map = map;
+	nr_efi_runtime_map = nr_entries;
+	efi_memdesc_size = desc_size;
+}
+
+int __init efi_runtime_map_init(struct kobject *efi_kobj)
+{
+	int i, j, ret = 0;
+	struct efi_runtime_map_entry *entry;
+
+	if (!efi_runtime_map)
+		return 0;
+
+	map_entries = kzalloc(nr_efi_runtime_map * sizeof(entry), GFP_KERNEL);
+	if (!map_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < nr_efi_runtime_map; i++) {
+		entry = add_sysfs_runtime_map_entry(efi_kobj, i);
+		if (IS_ERR(entry)) {
+			ret = PTR_ERR(entry);
+			goto out_add_entry;
+		}
+		*(map_entries + i) = entry;
+	}
+
+	return 0;
+out_add_entry:
+	for (j = i - 1; j > 0; j--) {
+		entry = *(map_entries + j);
+		kobject_put(&entry->kobj);
+	}
+	if (map_kset)
+		kset_unregister(map_kset);
+out:
+	return ret;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 988af61..0a819e7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,4 +876,17 @@ int efivars_sysfs_init(void);
 
 #endif /* CONFIG_EFI_VARS */
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+int efi_runtime_map_init(struct kobject *);
+void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
+#endif
+
 #endif /* _LINUX_EFI_H */
-- 
1.8.3.1

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

* [PATCH v7 08/14] efi: export efi runtime memory mapping to sysfs
@ 2013-12-17  8:00     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal

From: Dave Young <dyoung@redhat.com>
Date: Tue, 26 Nov 2013 10:10:23 +0800
Subject: [PATCH 08/13] efi: export efi runtime memory mapping to sysfs

kexec kernel will need exactly same mapping for
efi runtime memory ranges. Thus here export the
runtime ranges mapping to sysfs, kexec-tools
will assemble them and pass to 2nd kernel via
setup_data.

Introducing a new directory /sys/firmware/efi/runtime-map
Just like /sys/firmware/memmap. Containing below attribute
in each file of that directory:
attribute  num_pages  phys_addr  type  virt_addr

Changelog:
 - Cleaup code, add function efi_save_runtime_map
 - Improve err handling
 - Add macros for sysfs _show functions
 - Remove forward declarations.
 Matt:
 - s/efi-runtime-map.c/runtime-map.c
 - Change dir name to runtime-map
 - Changelog and documentation fixes.
 - Documentation fixes.
 - Update to use desc_size in efi_runtime_map
 - Kconfig EFI_RUNTIME_MAP depends on X86 && KEXEC && EFI
 Boris:
 - Documentation grammar/spelling fix
 - krealloc fix.
 - Move efi_runtime_map_init to efisubsys_initcall.
 - Remove 'if EXPERT' for EFI_RUNTIME_MAP Kconfig option
 - save_runtime_map: move error handling code into the function itself.
 - other code improvement.

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 .../ABI/testing/sysfs-firmware-efi-runtime-map     |  34 ++++
 arch/x86/platform/efi/efi.c                        |  36 +++-
 drivers/firmware/efi/Kconfig                       |  11 ++
 drivers/firmware/efi/Makefile                      |   1 +
 drivers/firmware/efi/efi.c                         |   4 +
 drivers/firmware/efi/runtime-map.c                 | 181 +++++++++++++++++++++
 include/linux/efi.h                                |  13 ++
 7 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
 create mode 100644 drivers/firmware/efi/runtime-map.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
new file mode 100644
index 0000000..c61b9b3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map
@@ -0,0 +1,34 @@
+What:		/sys/firmware/efi/runtime-map/
+Date:		December 2013
+Contact:	Dave Young <dyoung@redhat.com>
+Description:	Switching efi runtime services to virtual mode requires
+		that all efi memory ranges which have the runtime attribute
+		bit set to be mapped to virtual addresses.
+
+		The efi runtime services can only be switched to virtual
+		mode once without rebooting. The kexec kernel must maintain
+		the same physical to virtual address mappings as the first
+		kernel. The mappings are exported to sysfs so userspace tools
+		can reassemble them and pass them into the kexec kernel.
+
+		/sys/firmware/efi/runtime-map/ is the directory the kernel
+		exports that information in.
+
+		subdirectories are named with the number of the memory range:
+
+			/sys/firmware/efi/runtime-map/0
+			/sys/firmware/efi/runtime-map/1
+			/sys/firmware/efi/runtime-map/2
+			/sys/firmware/efi/runtime-map/3
+			...
+
+		Each subdirectory contains five files:
+
+		attribute : The attributes of the memory range.
+		num_pages : The size of the memory range in pages.
+		phys_addr : The physical address of the memory range.
+		type      : The type of the memory range.
+		virt_addr : The virtual address of the memory range.
+
+		Above values are all hexadecimal numbers with the '0x' prefix.
+Users:		Kexec
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 3e8b760..b1fff8e 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 	{NULL_GUID, NULL, NULL},
 };
 
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
  */
@@ -810,6 +813,24 @@ static void __init efi_merge_regions(void)
 	}
 }
 
+static int __init save_runtime_map(efi_memory_desc_t *md, int idx)
+{
+	void *p;
+	p = krealloc(efi_runtime_map, (idx + 1) * memmap.desc_size, GFP_KERNEL);
+	if (!p)
+		goto out;
+
+	efi_runtime_map = p;
+	memcpy(efi_runtime_map + idx * memmap.desc_size, md, memmap.desc_size);
+
+	return 0;
+out:
+	kfree(efi_runtime_map);
+	efi_runtime_map = NULL;
+	nr_efi_runtime_map = 0;
+	return -ENOMEM;
+}
+
 /*
  * Map efi memory ranges for runtime serivce and update new_memmap with virtual
  * addresses.
@@ -820,6 +841,7 @@ static void * __init efi_map_regions(int *count)
 	void *p, *tmp, *new_memmap = NULL;
 	unsigned long size;
 	u64 end, systab;
+	int err = 0;
 
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
@@ -844,15 +866,22 @@ static void * __init efi_map_regions(int *count)
 		tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
 			       GFP_KERNEL);
 		if (!tmp)
-			goto out_krealloc;
+			goto out;
 		new_memmap = tmp;
 		memcpy(new_memmap + (*count * memmap.desc_size), md,
 		       memmap.desc_size);
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA) {
+			err = save_runtime_map(md, nr_efi_runtime_map);
+			if (err)
+				goto out;
+			nr_efi_runtime_map++;
+		}
 		(*count)++;
 	}
 
 	return new_memmap;
-out_krealloc:
+out:
 	kfree(new_memmap);
 	return NULL;
 }
@@ -899,6 +928,9 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
+	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
+			      boot_params.efi_info.efi_memdesc_size);
+
 	BUG_ON(!efi.systab);
 
 	efi_setup_page_tables();
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..730f5f2 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -39,4 +39,15 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
 config UEFI_CPER
 	def_bool n
 
+config EFI_RUNTIME_MAP
+	bool "Export efi runtime maps to sysfs"
+	depends on X86 && EFI && KEXEC
+	default y
+	help
+	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
+	  That memory map is used for example by kexec to set up efi virtual
+	  mapping the 2nd kernel, but can also be used for debugging purposes.
+
+	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
+
 endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..a58e0f1 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -5,3 +5,4 @@ obj-y					+= efi.o vars.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
+obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 6d0bc52..7910cd5 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -167,6 +167,10 @@ static int __init efisubsys_init(void)
 		goto err_unregister;
 	}
 
+	error = efi_runtime_map_init(efi_kobj);
+	if (error)
+		goto err_remove_group;
+
 	/* and the standard mountpoint for efivarfs */
 	efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
 	if (!efivars_kobj) {
diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c
new file mode 100644
index 0000000..97cdd16
--- /dev/null
+++ b/drivers/firmware/efi/runtime-map.c
@@ -0,0 +1,181 @@
+/*
+ * linux/drivers/efi/runtime-map.c
+ * Copyright (C) 2013 Red Hat, Inc., Dave Young <dyoung@redhat.com>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+
+#include <asm/setup.h>
+
+static void *efi_runtime_map;
+static int nr_efi_runtime_map;
+static u32 efi_memdesc_size;
+
+struct efi_runtime_map_entry {
+	efi_memory_desc_t md;
+	struct kobject kobj;   /* kobject for each entry */
+};
+
+static struct efi_runtime_map_entry **map_entries;
+
+struct map_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct efi_runtime_map_entry *entry, char *buf);
+};
+
+static inline struct map_attribute *to_map_attr(struct attribute *attr)
+{
+	return container_of(attr, struct map_attribute, attr);
+}
+
+static ssize_t type_show(struct efi_runtime_map_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%x\n", entry->md.type);
+}
+
+#define EFI_RUNTIME_FIELD(var) entry->md.var
+
+#define EFI_RUNTIME_U64_ATTR_SHOW(name) \
+static ssize_t name##_show(struct efi_runtime_map_entry *entry, char *buf) \
+{ \
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n", EFI_RUNTIME_FIELD(name)); \
+}
+
+EFI_RUNTIME_U64_ATTR_SHOW(phys_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(virt_addr);
+EFI_RUNTIME_U64_ATTR_SHOW(num_pages);
+EFI_RUNTIME_U64_ATTR_SHOW(attribute);
+
+static inline struct efi_runtime_map_entry *to_map_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct efi_runtime_map_entry, kobj);
+}
+
+static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *buf)
+{
+	struct efi_runtime_map_entry *entry = to_map_entry(kobj);
+	struct map_attribute *map_attr = to_map_attr(attr);
+
+	return map_attr->show(entry, buf);
+}
+
+static struct map_attribute map_type_attr = __ATTR_RO(type);
+static struct map_attribute map_phys_addr_attr   = __ATTR_RO(phys_addr);
+static struct map_attribute map_virt_addr_attr  = __ATTR_RO(virt_addr);
+static struct map_attribute map_num_pages_attr  = __ATTR_RO(num_pages);
+static struct map_attribute map_attribute_attr  = __ATTR_RO(attribute);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&map_type_attr.attr,
+	&map_phys_addr_attr.attr,
+	&map_virt_addr_attr.attr,
+	&map_num_pages_attr.attr,
+	&map_attribute_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops map_attr_ops = {
+	.show = map_attr_show,
+};
+
+static void map_release(struct kobject *kobj)
+{
+	struct efi_runtime_map_entry *entry;
+
+	entry = to_map_entry(kobj);
+	kfree(entry);
+}
+
+static struct kobj_type __refdata map_ktype = {
+	.sysfs_ops	= &map_attr_ops,
+	.default_attrs	= def_attrs,
+	.release	= map_release,
+};
+
+static struct kset *map_kset;
+
+static struct efi_runtime_map_entry *
+add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
+{
+	int ret;
+	struct efi_runtime_map_entry *entry;
+
+	if (!map_kset) {
+		map_kset = kset_create_and_add("runtime-map", NULL, kobj);
+		if (!map_kset)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		kset_unregister(map_kset);
+		return entry;
+	}
+
+	memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
+	       sizeof(efi_memory_desc_t));
+
+	kobject_init(&entry->kobj, &map_ktype);
+	entry->kobj.kset = map_kset;
+	ret = kobject_add(&entry->kobj, NULL, "%d", nr);
+	if (ret) {
+		kobject_put(&entry->kobj);
+		kset_unregister(map_kset);
+		return ERR_PTR(ret);
+	}
+
+	return entry;
+}
+
+void efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size)
+{
+	efi_runtime_map = map;
+	nr_efi_runtime_map = nr_entries;
+	efi_memdesc_size = desc_size;
+}
+
+int __init efi_runtime_map_init(struct kobject *efi_kobj)
+{
+	int i, j, ret = 0;
+	struct efi_runtime_map_entry *entry;
+
+	if (!efi_runtime_map)
+		return 0;
+
+	map_entries = kzalloc(nr_efi_runtime_map * sizeof(entry), GFP_KERNEL);
+	if (!map_entries) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < nr_efi_runtime_map; i++) {
+		entry = add_sysfs_runtime_map_entry(efi_kobj, i);
+		if (IS_ERR(entry)) {
+			ret = PTR_ERR(entry);
+			goto out_add_entry;
+		}
+		*(map_entries + i) = entry;
+	}
+
+	return 0;
+out_add_entry:
+	for (j = i - 1; j > 0; j--) {
+		entry = *(map_entries + j);
+		kobject_put(&entry->kobj);
+	}
+	if (map_kset)
+		kset_unregister(map_kset);
+out:
+	return ret;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 988af61..0a819e7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -876,4 +876,17 @@ int efivars_sysfs_init(void);
 
 #endif /* CONFIG_EFI_VARS */
 
+#ifdef CONFIG_EFI_RUNTIME_MAP
+int efi_runtime_map_init(struct kobject *);
+void efi_runtime_map_setup(void *, int, u32);
+#else
+static inline int efi_runtime_map_init(struct kobject *kobj)
+{
+	return 0;
+}
+
+static inline void
+efi_runtime_map_setup(void *map, int nr_entries, u32 desc_size) {}
+#endif
+
 #endif /* _LINUX_EFI_H */
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:01     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm


From: Dave Young <dyoung@redhat.com>
Date: Tue, 26 Nov 2013 10:10:24 +0800
Subject: [PATCH 09/13] efi: passing kexec necessary efi data via setup_data

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
           simplify parse_efi_setup logic
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/efi.h            |  13 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 183 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   6 ++
 6 files changed, 183 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..cfcf438 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,19 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern u32 efi_data_len;
+extern void parse_efi_setup(u64 phys_addr, u32 data_len);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..24536f7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data, data_len);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b1fff8e..5438083 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup;		/* efi setup_data physical address */
+u32 efi_data_len;	/* efi setup_data payload length */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +117,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +495,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +530,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +647,71 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void get_nr_runtime_map(void)
+{
+	if (!efi_setup)
+		return;
+
+	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +719,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	get_nr_runtime_map();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +758,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +972,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1024,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1046,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
@@ -936,16 +1069,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..249b183 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..324b651 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr, u32 data_len)
+{
+	efi_setup = phys_addr + sizeof(struct setup_data);
+	efi_data_len = data_len - sizeof(struct setup_data);
+}
-- 
1.8.3.1


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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:01     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:01 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA


From: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date: Tue, 26 Nov 2013 10:10:24 +0800
Subject: [PATCH 09/13] efi: passing kexec necessary efi data via setup_data

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
           simplify parse_efi_setup logic
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/include/asm/efi.h            |  13 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 183 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   6 ++
 6 files changed, 183 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..cfcf438 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,19 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern u32 efi_data_len;
+extern void parse_efi_setup(u64 phys_addr, u32 data_len);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..24536f7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data, data_len);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b1fff8e..5438083 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup;		/* efi setup_data physical address */
+u32 efi_data_len;	/* efi setup_data payload length */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +117,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +495,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +530,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +647,71 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void get_nr_runtime_map(void)
+{
+	if (!efi_setup)
+		return;
+
+	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +719,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	get_nr_runtime_map();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +758,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +972,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1024,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1046,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
@@ -936,16 +1069,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..249b183 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..324b651 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr, u32 data_len)
+{
+	efi_setup = phys_addr + sizeof(struct setup_data);
+	efi_data_len = data_len - sizeof(struct setup_data);
+}
-- 
1.8.3.1

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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:01     ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:01 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal


From: Dave Young <dyoung@redhat.com>
Date: Tue, 26 Nov 2013 10:10:24 +0800
Subject: [PATCH 09/13] efi: passing kexec necessary efi data via setup_data

Add a new setup_data type SETUP_EFI for kexec use.
Passing the saved fw_vendor, runtime, config tables and efi runtime mappings.

When entering virtual mode, directly mapping the efi runtime ragions which
we passed in previously. And skip the step to call SetVirtualAddressMap.

Specially for HP z420 workstation we need save the smbios physical address.
The kernel boot sequence proceeds in the following order.  Step 2
requires efi.smbios to be the physical address.  However, I found that on
HP z420 EFI system table has a virtual address of SMBIOS in step 1.  Hence,
we need set it back to the physical address with the smbios in
efi_setup_data.  (When it is still the physical address, it simply sets
the same value.)

1. efi_init() - Set efi.smbios from EFI system table
2. dmi_scan_machine() - Temporary map efi.smbios to access SMBIOS table
3. efi_enter_virtual_mode() - Map EFI ranges

Tested on ovmf+qemu, lenovo thinkpad, a dell laptop and an
HP z420 workstation.

v2: refresh based on previous patch changes, code cleanup.
v3: use ioremap instead of phys_to_virt for efi_setup
v5: improve some code structure per comments from Matt
    Boris: improve code structure, spell fix, etc.
    Improve changelog from Toshi.
    change the variable efi_setup to the physical address of efi setup_data
    instead of the ioremapped virt address
v6: Boris: Documentation fixes
           move parse_efi_setup to efi_$(BITS).c
           simplify parse_efi_setup logic
    Matt: check return value of efi_reuse_config

Signed-off-by: Dave Young <dyoung@redhat.com>
---
 arch/x86/include/asm/efi.h            |  13 +++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/setup.c               |   3 +
 arch/x86/platform/efi/efi.c           | 183 +++++++++++++++++++++++++++++-----
 arch/x86/platform/efi/efi_32.c        |   1 +
 arch/x86/platform/efi/efi_64.c        |   6 ++
 6 files changed, 183 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 9fbaeb2..cfcf438 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -133,6 +133,19 @@ extern void efi_sync_low_kernel_mappings(void);
 extern void efi_setup_page_tables(void);
 extern void __init old_map_region(efi_memory_desc_t *md);
 
+struct efi_setup_data {
+	u64 fw_vendor;
+	u64 runtime;
+	u64 tables;
+	u64 smbios;
+	u64 reserved[8];
+	efi_memory_desc_t map[0];
+};
+
+extern u64 efi_setup;
+extern u32 efi_data_len;
+extern void parse_efi_setup(u64 phys_addr, u32 data_len);
+
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9c3733c..64fe421 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -6,6 +6,7 @@
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
 #define SETUP_PCI			3
+#define SETUP_EFI			4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK	0x07FF
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cb233bc..24536f7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -447,6 +447,9 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_EFI:
+			parse_efi_setup(pa_data, data_len);
+			break;
 		default:
 			break;
 		}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b1fff8e..5438083 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
 
 static void *efi_runtime_map;
 static int nr_efi_runtime_map;
+u64 efi_setup;		/* efi setup_data physical address */
+u32 efi_data_len;	/* efi setup_data payload length */
 
 /*
  * Returns 1 if 'facility' is enabled, 0 otherwise.
@@ -115,7 +117,6 @@ static int __init setup_storage_paranoia(char *arg)
 }
 early_param("efi_no_storage_paranoia", setup_storage_paranoia);
 
-
 static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
 {
 	unsigned long flags;
@@ -494,18 +495,28 @@ static int __init efi_systab_init(void *phys)
 {
 	if (efi_enabled(EFI_64BIT)) {
 		efi_system_table_64_t *systab64;
+		struct efi_setup_data *data = NULL;
 		u64 tmp = 0;
 
+		if (efi_setup) {
+			data = early_memremap(efi_setup, sizeof(*data));
+			if (!data)
+				return -ENOMEM;
+		}
 		systab64 = early_memremap((unsigned long)phys,
 					 sizeof(*systab64));
 		if (systab64 == NULL) {
 			pr_err("Couldn't map the system table!\n");
+			if (data)
+				early_memunmap(data, sizeof(*data));
 			return -ENOMEM;
 		}
 
 		efi_systab.hdr = systab64->hdr;
-		efi_systab.fw_vendor = systab64->fw_vendor;
-		tmp |= systab64->fw_vendor;
+
+		efi_systab.fw_vendor = data ? (unsigned long)data->fw_vendor :
+					      systab64->fw_vendor;
+		tmp |= efi_systab.fw_vendor;
 		efi_systab.fw_revision = systab64->fw_revision;
 		efi_systab.con_in_handle = systab64->con_in_handle;
 		tmp |= systab64->con_in_handle;
@@ -519,15 +530,20 @@ static int __init efi_systab_init(void *phys)
 		tmp |= systab64->stderr_handle;
 		efi_systab.stderr = systab64->stderr;
 		tmp |= systab64->stderr;
-		efi_systab.runtime = (void *)(unsigned long)systab64->runtime;
-		tmp |= systab64->runtime;
+		efi_systab.runtime = data ?
+				     (void *)(unsigned long)data->runtime :
+				     (void *)(unsigned long)systab64->runtime;
+		tmp |= (unsigned long)efi_systab.runtime;
 		efi_systab.boottime = (void *)(unsigned long)systab64->boottime;
 		tmp |= systab64->boottime;
 		efi_systab.nr_tables = systab64->nr_tables;
-		efi_systab.tables = systab64->tables;
-		tmp |= systab64->tables;
+		efi_systab.tables = data ? (unsigned long)data->tables :
+					   systab64->tables;
+		tmp |= efi_systab.tables;
 
 		early_memunmap(systab64, sizeof(*systab64));
+		if (data)
+			early_memunmap(data, sizeof(*data));
 #ifdef CONFIG_X86_32
 		if (tmp >> 32) {
 			pr_err("EFI data located above 4GB, disabling EFI.\n");
@@ -631,6 +647,71 @@ static int __init efi_memmap_init(void)
 	return 0;
 }
 
+/*
+ * A number of config table entries get remapped to virtual addresses
+ * after entering EFI virtual mode. However, the kexec kernel requires
+ * their physical addresses therefore we pass them via setup_data and
+ * correct those entries to their respective physical addresses here.
+ *
+ * Currently only handles smbios which is necessary for some firmware
+ * implementation.
+ */
+static int __init efi_reuse_config(u64 tables, int nr_tables)
+{
+	int i, sz, ret = 0;
+	void *p, *tablep;
+	struct efi_setup_data *data;
+
+	if (!efi_setup)
+		return 0;
+
+	if (!efi_enabled(EFI_64BIT))
+		return 0;
+
+	data = early_memremap(efi_setup, sizeof(*data));
+	if (!data) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (!data->smbios)
+		goto out_memremap;
+
+	sz = sizeof(efi_config_table_64_t);
+
+	p = tablep = early_memremap(tables, nr_tables * sz);
+	if (!p) {
+		pr_err("Could not map Configuration table!\n");
+		ret = -ENOMEM;
+		goto out_memremap;
+	}
+
+	for (i = 0; i < efi.systab->nr_tables; i++) {
+		efi_guid_t guid;
+
+		guid = ((efi_config_table_64_t *)p)->guid;
+
+		if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID))
+			((efi_config_table_64_t *)p)->table = data->smbios;
+		p += sz;
+	}
+	early_memunmap(tablep, nr_tables * sz);
+
+out_memremap:
+	early_memunmap(data, sizeof(*data));
+out:
+	return ret;
+}
+
+static void get_nr_runtime_map(void)
+{
+	if (!efi_setup)
+		return;
+
+	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
+			     sizeof(efi_memory_desc_t);
+}
+
 void __init efi_init(void)
 {
 	efi_char16_t *c16;
@@ -638,6 +719,7 @@ void __init efi_init(void)
 	int i = 0;
 	void *tmp;
 
+	get_nr_runtime_map();
 #ifdef CONFIG_X86_32
 	if (boot_params.efi_info.efi_systab_hi ||
 	    boot_params.efi_info.efi_memmap_hi) {
@@ -676,6 +758,9 @@ void __init efi_init(void)
 		efi.systab->hdr.revision >> 16,
 		efi.systab->hdr.revision & 0xffff, vendor);
 
+	if (efi_reuse_config(efi.systab->tables, efi.systab->nr_tables))
+		return;
+
 	if (efi_config_init(arch_tables))
 		return;
 
@@ -887,6 +972,43 @@ out:
 }
 
 /*
+ * Map efi regions which were passed via setup_data. The virt_addr is a fixed
+ * addr which was used in first kernel of a kexec boot.
+ */
+static int __init map_regions_fixed(void)
+{
+	int i, s, ret = 0;
+	u64 end, systab;
+	unsigned long size;
+	efi_memory_desc_t *md;
+	struct efi_setup_data *data;
+
+	s = sizeof(*data) + nr_efi_runtime_map * sizeof(data->map[0]);
+	data = early_memremap(efi_setup, s);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0, md = data->map; i < nr_efi_runtime_map; i++, md++) {
+		efi_map_region_fixed(md); /* FIXME: add error handling */
+		size = md->num_pages << PAGE_SHIFT;
+		end = md->phys_addr + size;
+
+		systab = (u64) (unsigned long) efi_phys.systab;
+		if (md->phys_addr <= systab && systab < end) {
+			systab += md->virt_addr - md->phys_addr;
+			efi.systab = (efi_system_table_t *)(unsigned long)systab;
+		}
+		ret = save_runtime_map(md, i);
+		if (ret)
+			goto out;
+	}
+
+out:
+	early_memunmap(data, s);
+	return ret;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, we look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor into the
@@ -902,12 +1024,16 @@ out:
  * so that we're in a different address space when calling a runtime
  * function. For function arguments passing we do copy the PGDs of the
  * kernel page table into ->trampoline_pgd prior to each call.
+ *
+ * Specially for kexec boot, efi runtime maps in previous kernel should
+ * be passed in via setup_data. In that case runtime ranges will be mapped
+ * to the same virtual addresses as the first kernel.
  */
 void __init efi_enter_virtual_mode(void)
 {
 	efi_status_t status;
 	void *new_memmap = NULL;
-	int count = 0;
+	int err, count = 0;
 
 	efi.systab = NULL;
 
@@ -920,12 +1046,19 @@ void __init efi_enter_virtual_mode(void)
 		return;
 	}
 
-	efi_merge_regions();
-
-	new_memmap = efi_map_regions(&count);
-	if (!new_memmap) {
-		pr_err("Error reallocating memory, EFI runtime non-functional!\n");
-		return;
+	if (efi_setup) {
+		err = map_regions_fixed();
+		if (err) {
+			pr_err("Error mapping runtime services, EFI runtime non-functional!\n");
+			return;
+		}
+	} else {
+		efi_merge_regions();
+		new_memmap = efi_map_regions(&count);
+		if (!new_memmap) {
+			pr_err("Error reallocating memory, EFI runtime non-functional!\n");
+			return;
+		}
 	}
 
 	efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
@@ -936,16 +1069,18 @@ void __init efi_enter_virtual_mode(void)
 	efi_setup_page_tables();
 	efi_sync_low_kernel_mappings();
 
-	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * count,
-		memmap.desc_size,
-		memmap.desc_version,
-		(efi_memory_desc_t *)__pa(new_memmap));
-
-	if (status != EFI_SUCCESS) {
-		pr_alert("Unable to switch EFI into virtual mode "
-			 "(status=%lx)!\n", status);
-		panic("EFI call to SetVirtualAddressMap() failed!");
+	if (!efi_setup) {
+		status = phys_efi_set_virtual_address_map(
+			memmap.desc_size * count,
+			memmap.desc_size,
+			memmap.desc_version,
+			(efi_memory_desc_t *)__pa(new_memmap));
+
+		if (status != EFI_SUCCESS) {
+			pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n",
+				 status);
+			panic("EFI call to SetVirtualAddressMap() failed!");
+		}
 	}
 
 	/*
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 7b3ec6e..249b183 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
 }
 
 void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
+void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
 
 void efi_call_phys_prelog(void)
 {
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ff08cb1..324b651 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
 
 	return (void __iomem *)__va(phys_addr);
 }
+
+void __init parse_efi_setup(u64 phys_addr, u32 data_len)
+{
+	efi_setup = phys_addr + sizeof(struct setup_data);
+	efi_data_len = data_len - sizeof(struct setup_data);
+}
-- 
1.8.3.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:08       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-efi, x86, mjg59, hpa, James.Bottomley, vgoyal, ebiederm,
	horms, kexec, bp, greg, matt, toshi.kani, akpm, mingo, msalter,
	leif.lindholm


Hello Boris

Does this version looks good to you? Only mapping once in print_efi_memmap..

BTW, forgot to remove 'Re:' in subject.

Please let me know if there's any other issues or need I resend the series.

Most changes vs previous version are below:

> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index b1fff8e..5438083 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
>  
>  static void *efi_runtime_map;
>  static int nr_efi_runtime_map;
> +u64 efi_setup;		/* efi setup_data physical address */
> +u32 efi_data_len;	/* efi setup_data payload length */
>  

[snip]

> +
> +static void get_nr_runtime_map(void)
> +{
> +	if (!efi_setup)
> +		return;
> +
> +	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
> +			     sizeof(efi_memory_desc_t);
> +}
> +
>  void __init efi_init(void)
>  {
>  	efi_char16_t *c16;
> @@ -638,6 +719,7 @@ void __init efi_init(void)
>  	int i = 0;
>  	void *tmp;
>  
> +	get_nr_runtime_map();
>  #ifdef CONFIG_X86_32
>  	if (boot_params.efi_info.efi_systab_hi ||
>  	    boot_params.efi_info.efi_memmap_hi) {
> @@ -676,6 +758,9 @@ void __init efi_init(void)
>  
		efi.systab->hdr.revision >> 16,
[snip]

>  
>  	/*
> diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
> index 7b3ec6e..249b183 100644
> --- a/arch/x86/platform/efi/efi_32.c
> +++ b/arch/x86/platform/efi/efi_32.c
> @@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
>  }
>  
>  void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
>  
>  void efi_call_phys_prelog(void)
>  {
> diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
> index ff08cb1..324b651 100644
> --- a/arch/x86/platform/efi/efi_64.c
> +++ b/arch/x86/platform/efi/efi_64.c
> @@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
>  
>  	return (void __iomem *)__va(phys_addr);
>  }
> +
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len)
> +{
> +	efi_setup = phys_addr + sizeof(struct setup_data);
> +	efi_data_len = data_len - sizeof(struct setup_data);
> +}
> -- 
> 1.8.3.1
> 

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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:08       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:08 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA


Hello Boris

Does this version looks good to you? Only mapping once in print_efi_memmap..

BTW, forgot to remove 'Re:' in subject.

Please let me know if there's any other issues or need I resend the series.

Most changes vs previous version are below:

> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index b1fff8e..5438083 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
>  
>  static void *efi_runtime_map;
>  static int nr_efi_runtime_map;
> +u64 efi_setup;		/* efi setup_data physical address */
> +u32 efi_data_len;	/* efi setup_data payload length */
>  

[snip]

> +
> +static void get_nr_runtime_map(void)
> +{
> +	if (!efi_setup)
> +		return;
> +
> +	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
> +			     sizeof(efi_memory_desc_t);
> +}
> +
>  void __init efi_init(void)
>  {
>  	efi_char16_t *c16;
> @@ -638,6 +719,7 @@ void __init efi_init(void)
>  	int i = 0;
>  	void *tmp;
>  
> +	get_nr_runtime_map();
>  #ifdef CONFIG_X86_32
>  	if (boot_params.efi_info.efi_systab_hi ||
>  	    boot_params.efi_info.efi_memmap_hi) {
> @@ -676,6 +758,9 @@ void __init efi_init(void)
>  
		efi.systab->hdr.revision >> 16,
[snip]

>  
>  	/*
> diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
> index 7b3ec6e..249b183 100644
> --- a/arch/x86/platform/efi/efi_32.c
> +++ b/arch/x86/platform/efi/efi_32.c
> @@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
>  }
>  
>  void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
>  
>  void efi_call_phys_prelog(void)
>  {
> diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
> index ff08cb1..324b651 100644
> --- a/arch/x86/platform/efi/efi_64.c
> +++ b/arch/x86/platform/efi/efi_64.c
> @@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
>  
>  	return (void __iomem *)__va(phys_addr);
>  }
> +
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len)
> +{
> +	efi_setup = phys_addr + sizeof(struct setup_data);
> +	efi_data_len = data_len - sizeof(struct setup_data);
> +}
> -- 
> 1.8.3.1
> 

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

* Re: [PATCH v7 09/14] efi: passing kexec necessary efi data via setup_data
@ 2013-12-17  8:08       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-17  8:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: mjg59, msalter, linux-efi, toshi.kani, matt, greg, x86, kexec,
	leif.lindholm, James.Bottomley, horms, bp, ebiederm, hpa, akpm,
	mingo, vgoyal


Hello Boris

Does this version looks good to you? Only mapping once in print_efi_memmap..

BTW, forgot to remove 'Re:' in subject.

Please let me know if there's any other issues or need I resend the series.

Most changes vs previous version are below:

> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index b1fff8e..5438083 100644
> --- a/arch/x86/platform/efi/efi.c
> +++ b/arch/x86/platform/efi/efi.c
> @@ -78,6 +78,8 @@ static __initdata efi_config_table_type_t arch_tables[] = {
>  
>  static void *efi_runtime_map;
>  static int nr_efi_runtime_map;
> +u64 efi_setup;		/* efi setup_data physical address */
> +u32 efi_data_len;	/* efi setup_data payload length */
>  

[snip]

> +
> +static void get_nr_runtime_map(void)
> +{
> +	if (!efi_setup)
> +		return;
> +
> +	nr_efi_runtime_map = (efi_data_len - sizeof(struct efi_setup_data)) /
> +			     sizeof(efi_memory_desc_t);
> +}
> +
>  void __init efi_init(void)
>  {
>  	efi_char16_t *c16;
> @@ -638,6 +719,7 @@ void __init efi_init(void)
>  	int i = 0;
>  	void *tmp;
>  
> +	get_nr_runtime_map();
>  #ifdef CONFIG_X86_32
>  	if (boot_params.efi_info.efi_systab_hi ||
>  	    boot_params.efi_info.efi_memmap_hi) {
> @@ -676,6 +758,9 @@ void __init efi_init(void)
>  
		efi.systab->hdr.revision >> 16,
[snip]

>  
>  	/*
> diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
> index 7b3ec6e..249b183 100644
> --- a/arch/x86/platform/efi/efi_32.c
> +++ b/arch/x86/platform/efi/efi_32.c
> @@ -48,6 +48,7 @@ void __init efi_map_region(efi_memory_desc_t *md)
>  }
>  
>  void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
>  
>  void efi_call_phys_prelog(void)
>  {
> diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
> index ff08cb1..324b651 100644
> --- a/arch/x86/platform/efi/efi_64.c
> +++ b/arch/x86/platform/efi/efi_64.c
> @@ -228,3 +228,9 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
>  
>  	return (void __iomem *)__va(phys_addr);
>  }
> +
> +void __init parse_efi_setup(u64 phys_addr, u32 data_len)
> +{
> +	efi_setup = phys_addr + sizeof(struct setup_data);
> +	efi_data_len = data_len - sizeof(struct setup_data);
> +}
> -- 
> 1.8.3.1
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17 11:24           ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-17 11:24 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On Tue, 17 Dec, at 02:53:46PM, Dave Young wrote:
> On 12/17/13 at 02:24pm, Dave Young wrote:
> > On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > > 
> > > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > > ---
> > > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > > 
> > > Dave, I've no idea why this change is necessary from the commit log. Is
> > > it required for kexec to function on EFI? Why does __va() not work in
> > > the memmap=exactmap case?
> > > 
> > 
> > During previous kdump tests I saw panics while reading the setup_data in debugfs.
> > I thought it is caused by some unmapped addresses. At that time I also reproduced
> > it by booting the non-kexec kernel with memmap=exact.
> > 
> > Since you are asking about this I'm testing it again but I seems can not
> > reproduce this problem any more, it's weird.
> > 
> > I should dug more about it and save the panic messages.
> > 
> > So let's drop this patch for now, I will keep an eye on this and address it later
> > if I can find the problem again.
> 
> Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> case, I remember I saw this in kdump kernel, but I still did not see it in today's
> testing so I think move this issue out of this patch series is fine to me.
 
Please include the following oops when you submit this patch again.

> [    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
> [    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359474] PGD 316b067 PUD 37031063 PMD 0 
> [    0.359476] Oops: 0000 [#1] PREEMPT SMP 
> [    0.359477] Modules linked in:
> [    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
> [    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
> [    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
> [    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
> [    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
> [    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
> [    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
> [    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
> [    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
> [    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
> [    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
> [    0.359492] Stack:
> [    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
> [    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
> [    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
> [    0.359499] Call Trace:
> [    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
> [    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
> [    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
> [    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
> [    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
> [    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
> [    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
> [    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
> [    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
> [    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
> [    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
> [    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359550]  RSP <ffff880037189e30>
> [    0.359550] CR2: ffff8800d5592020
> [    0.359559] ---[ end trace d52b3fbe64a26115 ]---
> [    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
> [    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
> [    0.628021] 

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17 11:24           ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-17 11:24 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	toshi.kani-VXdhtT5mjnY, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

On Tue, 17 Dec, at 02:53:46PM, Dave Young wrote:
> On 12/17/13 at 02:24pm, Dave Young wrote:
> > On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > > 
> > > > Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > > ---
> > > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > > 
> > > Dave, I've no idea why this change is necessary from the commit log. Is
> > > it required for kexec to function on EFI? Why does __va() not work in
> > > the memmap=exactmap case?
> > > 
> > 
> > During previous kdump tests I saw panics while reading the setup_data in debugfs.
> > I thought it is caused by some unmapped addresses. At that time I also reproduced
> > it by booting the non-kexec kernel with memmap=exact.
> > 
> > Since you are asking about this I'm testing it again but I seems can not
> > reproduce this problem any more, it's weird.
> > 
> > I should dug more about it and save the panic messages.
> > 
> > So let's drop this patch for now, I will keep an eye on this and address it later
> > if I can find the problem again.
> 
> Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> case, I remember I saw this in kdump kernel, but I still did not see it in today's
> testing so I think move this issue out of this patch series is fine to me.
 
Please include the following oops when you submit this patch again.

> [    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
> [    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359474] PGD 316b067 PUD 37031063 PMD 0 
> [    0.359476] Oops: 0000 [#1] PREEMPT SMP 
> [    0.359477] Modules linked in:
> [    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
> [    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
> [    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
> [    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
> [    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
> [    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
> [    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
> [    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
> [    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
> [    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
> [    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
> [    0.359492] Stack:
> [    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
> [    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
> [    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
> [    0.359499] Call Trace:
> [    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
> [    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
> [    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
> [    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
> [    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
> [    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
> [    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
> [    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
> [    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
> [    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
> [    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
> [    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359550]  RSP <ffff880037189e30>
> [    0.359550] CR2: ffff8800d5592020
> [    0.359559] ---[ end trace d52b3fbe64a26115 ]---
> [    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
> [    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
> [    0.628021] 

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-17 11:24           ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-17 11:24 UTC (permalink / raw)
  To: Dave Young
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On Tue, 17 Dec, at 02:53:46PM, Dave Young wrote:
> On 12/17/13 at 02:24pm, Dave Young wrote:
> > On 12/16/13 at 04:35pm, Matt Fleming wrote:
> > > On Mon, 16 Dec, at 05:30:35PM, Dave Young wrote:
> > > > kdump kernel will use memmap=exactmap kernel cmdline, but __va does not
> > > > work in case memmap=exactmap, so let's always use ioremap_cache.
> > > > 
> > > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > > ---
> > > >  arch/x86/kernel/kdebugfs.c | 35 +++++++++++------------------------
> > > >  1 file changed, 11 insertions(+), 24 deletions(-)
> > > 
> > > Dave, I've no idea why this change is necessary from the commit log. Is
> > > it required for kexec to function on EFI? Why does __va() not work in
> > > the memmap=exactmap case?
> > > 
> > 
> > During previous kdump tests I saw panics while reading the setup_data in debugfs.
> > I thought it is caused by some unmapped addresses. At that time I also reproduced
> > it by booting the non-kexec kernel with memmap=exact.
> > 
> > Since you are asking about this I'm testing it again but I seems can not
> > reproduce this problem any more, it's weird.
> > 
> > I should dug more about it and save the panic messages.
> > 
> > So let's drop this patch for now, I will keep an eye on this and address it later
> > if I can find the problem again.
> 
> Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> case, I remember I saw this in kdump kernel, but I still did not see it in today's
> testing so I think move this issue out of this patch series is fine to me.
 
Please include the following oops when you submit this patch again.

> [    0.359467] BUG: unable to handle kernel paging request at ffff8800d5592020
> [    0.359472] IP: [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359474] PGD 316b067 PUD 37031063 PMD 0 
> [    0.359476] Oops: 0000 [#1] PREEMPT SMP 
> [    0.359477] Modules linked in:
> [    0.359480] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc3+ #65
> [    0.359481] Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.15 05/09/2013
> [    0.359482] task: ffff880037022000 ti: ffff880037188000 task.ti: ffff880037188000
> [    0.359484] RIP: 0010:[<ffffffff817dbdbc>]  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359485] RSP: 0000:ffff880037189e30  EFLAGS: 00010286
> [    0.359486] RAX: ffff8800372e30e0 RBX: ffff8800372e30e0 RCX: 0000000000000191
> [    0.359486] RDX: 0000000000000000 RSI: ffffffff8168a39e RDI: ffff880037189e50
> [    0.359487] RBP: ffff880037189e90 R08: ffff8800372e30e0 R09: 0000000000000000
> [    0.359488] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003640aea0
> [    0.359489] R13: 00000000d5592018 R14: ffff88003640b200 R15: ffff8800d5592018
> [    0.359490] FS:  0000000000000000(0000) GS:ffff880037480000(0000) knlGS:0000000000000000
> [    0.359491] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.359491] CR2: ffff8800d5592020 CR3: 0000000002716000 CR4: 00000000000407e0
> [    0.359492] Stack:
> [    0.359494]  ffffffff817da6d5 ffff88003640b0e0 ffff88003640afc0 0000000000000004
> [    0.359496]  ffff880037180033 ffffffff8149d82d 00000000c9b42d58 ffffffff817dbca2
> [    0.359498]  0000000000000000 00000000000000f3 0000000000000000 0000000000000000
> [    0.359499] Call Trace:
> [    0.359502]  [<ffffffff817da6d5>] ? boot_params_ksysfs_init+0x1ff/0x244
> [    0.359507]  [<ffffffff8149d82d>] ? mutex_unlock+0x9/0xb
> [    0.359508]  [<ffffffff817dbca2>] ? topology_init+0x36/0x36
> [    0.359512]  [<ffffffff810002bf>] do_one_initcall+0xae/0x15b
> [    0.359515]  [<ffffffff81078500>] ? parameq+0xb/0x1f
> [    0.359516]  [<ffffffff81078770>] ? parse_args+0x25c/0x33a
> [    0.359519]  [<ffffffff817d5ec6>] kernel_init_freeable+0x115/0x19b
> [    0.359521]  [<ffffffff817d573d>] ? do_early_param+0x88/0x88
> [    0.359523]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359524]  [<ffffffff81489362>] kernel_init+0x9/0xfa
> [    0.359527]  [<ffffffff8149fd0c>] ret_from_fork+0x7c/0xb0
> [    0.359528]  [<ffffffff81489359>] ? rest_init+0xbd/0xbd
> [    0.359548] Code: ff 48 85 c0 48 89 c3 0f 84 b9 00 00 00 49 bf 00 00 00 00 00 88 ff ff 4c 89 28 8b 55 bc 48 8d 7d c0 4d 01 ef 48 c 
> [    0.359549] RIP  [<ffffffff817dbdbc>] arch_kdebugfs_init+0x11a/0x201
> [    0.359550]  RSP <ffff880037189e30>
> [    0.359550] CR2: ffff8800d5592020
> [    0.359559] ---[ end trace d52b3fbe64a26115 ]---
> [    0.621287] kworker/u8:0 (43) used greatest stack depth: 5232 bytes left
> [    0.628021] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
> [    0.628021] 

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-18  9:29             ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-18  9:29 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

> > 
> > Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> > case, I remember I saw this in kdump kernel, but I still did not see it in today's
> > testing so I think move this issue out of this patch series is fine to me.
>  
> Please include the following oops when you submit this patch again.

Sure, will do if I can reproduce it again in kdump kernel.

Thanks
Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-18  9:29             ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-18  9:29 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	toshi.kani-VXdhtT5mjnY, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

> > 
> > Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> > case, I remember I saw this in kdump kernel, but I still did not see it in today's
> > testing so I think move this issue out of this patch series is fine to me.
>  
> Please include the following oops when you submit this patch again.

Sure, will do if I can reproduce it again in kdump kernel.

Thanks
Dave

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

* Re: [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr
@ 2013-12-18  9:29             ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-18  9:29 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

> > 
> > Reproduced it again in normal boot with memmap=exactmap, but I agree it's a corner
> > case, I remember I saw this in kdump kernel, but I still did not see it in today's
> > testing so I think move this issue out of this patch series is fine to me.
>  
> Please include the following oops when you submit this patch again.

Sure, will do if I can reproduce it again in kdump kernel.

Thanks
Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-19 16:41     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-19 16:41 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> memmap ranges does not make sense anymore. So introduce a new function to only
> print runtime maps in case kexec/kdump kernel is used.
> 
> changelog:
> Matt: use efi_setup instead of esdata
>       share function print_efi_memmap for both normal and kexec boot.
> 
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
>  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)

Thinking about this a bit more, I'm not at all sure why this patch
exists.

Why do we not want to print the entire memory map range like we did in
the first kernel? The e820 map is printed exactly like it was in the
first kernel, why should the EFI memmap be special?

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-19 16:41     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-19 16:41 UTC (permalink / raw)
  To: Dave Young
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	mjg59-1xO5oi07KQx4cg9Nei1l7Q, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	vgoyal-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
	horms-/R6kz+dDXgpPR4JQBCEnsQ,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	bp-Gina5bIWoIWzQB+pC5nmwQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	toshi.kani-VXdhtT5mjnY, akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A

On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> memmap ranges does not make sense anymore. So introduce a new function to only
> print runtime maps in case kexec/kdump kernel is used.
> 
> changelog:
> Matt: use efi_setup instead of esdata
>       share function print_efi_memmap for both normal and kexec boot.
> 
> Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)

Thinking about this a bit more, I'm not at all sure why this patch
exists.

Why do we not want to print the entire memory map range like we did in
the first kernel? The e820 map is printed exactly like it was in the
first kernel, why should the EFI memmap be special?

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-19 16:41     ` Matt Fleming
  0 siblings, 0 replies; 78+ messages in thread
From: Matt Fleming @ 2013-12-19 16:41 UTC (permalink / raw)
  To: Dave Young
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> memmap ranges does not make sense anymore. So introduce a new function to only
> print runtime maps in case kexec/kdump kernel is used.
> 
> changelog:
> Matt: use efi_setup instead of esdata
>       share function print_efi_memmap for both normal and kexec boot.
> 
> Signed-off-by: Dave Young <dyoung@redhat.com>
> ---
>  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)

Thinking about this a bit more, I'm not at all sure why this patch
exists.

Why do we not want to print the entire memory map range like we did in
the first kernel? The e820 map is printed exactly like it was in the
first kernel, why should the EFI memmap be special?

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:35       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:35 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On 12/19/13 at 04:41pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > memmap ranges does not make sense anymore. So introduce a new function to only
> > print runtime maps in case kexec/kdump kernel is used.
> > 
> > changelog:
> > Matt: use efi_setup instead of esdata
> >       share function print_efi_memmap for both normal and kexec boot.
> > 
> > Signed-off-by: Dave Young <dyoung@redhat.com>
> > ---
> >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> >  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> Thinking about this a bit more, I'm not at all sure why this patch
> exists.
> 
> Why do we not want to print the entire memory map range like we did in
> the first kernel? The e820 map is printed exactly like it was in the
> first kernel, why should the EFI memmap be special?

Hi, Matt

Here is the memmap.map print result in kexec kernel (qemu + ovmf).
I think the memmap.map is not valid any more in kexec kernel, thus we
should print the saved runtime map.

[    0.000000] efi: EFI v2.31 by EDK II
[    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
[    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
[    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
[    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
[    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
[    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
[    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
[    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
[    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
[    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
[    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
[    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
[    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
[    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
[    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
[    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
[    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
[    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
[    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
[    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
[    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
[    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
[    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
[    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
[    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
[    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
[    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
[    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
[    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
[    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)


> 
> -- 
> Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:35       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:35 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

On 12/19/13 at 04:41pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > memmap ranges does not make sense anymore. So introduce a new function to only
> > print runtime maps in case kexec/kdump kernel is used.
> > 
> > changelog:
> > Matt: use efi_setup instead of esdata
> >       share function print_efi_memmap for both normal and kexec boot.
> > 
> > Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > ---
> >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> >  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> Thinking about this a bit more, I'm not at all sure why this patch
> exists.
> 
> Why do we not want to print the entire memory map range like we did in
> the first kernel? The e820 map is printed exactly like it was in the
> first kernel, why should the EFI memmap be special?

Hi, Matt

Here is the memmap.map print result in kexec kernel (qemu + ovmf).
I think the memmap.map is not valid any more in kexec kernel, thus we
should print the saved runtime map.

[    0.000000] efi: EFI v2.31 by EDK II
[    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
[    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
[    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
[    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
[    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
[    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
[    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
[    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
[    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
[    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
[    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
[    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
[    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
[    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
[    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
[    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
[    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
[    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
[    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
[    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
[    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
[    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
[    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
[    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
[    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
[    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
[    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
[    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
[    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
[    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)


> 
> -- 
> Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:35       ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:35 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On 12/19/13 at 04:41pm, Matt Fleming wrote:
> On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > memmap ranges does not make sense anymore. So introduce a new function to only
> > print runtime maps in case kexec/kdump kernel is used.
> > 
> > changelog:
> > Matt: use efi_setup instead of esdata
> >       share function print_efi_memmap for both normal and kexec boot.
> > 
> > Signed-off-by: Dave Young <dyoung@redhat.com>
> > ---
> >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> >  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> Thinking about this a bit more, I'm not at all sure why this patch
> exists.
> 
> Why do we not want to print the entire memory map range like we did in
> the first kernel? The e820 map is printed exactly like it was in the
> first kernel, why should the EFI memmap be special?

Hi, Matt

Here is the memmap.map print result in kexec kernel (qemu + ovmf).
I think the memmap.map is not valid any more in kexec kernel, thus we
should print the saved runtime map.

[    0.000000] efi: EFI v2.31 by EDK II
[    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
[    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
[    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
[    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
[    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
[    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
[    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
[    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
[    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
[    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
[    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
[    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
[    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
[    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
[    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
[    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
[    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
[    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
[    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
[    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
[    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
[    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
[    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
[    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
[    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
[    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
[    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
[    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
[    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
[    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)


> 
> -- 
> Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:57         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:57 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, linux-efi, x86, mjg59, hpa, James.Bottomley,
	vgoyal, ebiederm, horms, kexec, bp, greg, toshi.kani, akpm,
	mingo, msalter, leif.lindholm

On 12/20/13 at 09:35am, Dave Young wrote:
> On 12/19/13 at 04:41pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > > memmap ranges does not make sense anymore. So introduce a new function to only
> > > print runtime maps in case kexec/kdump kernel is used.
> > > 
> > > changelog:
> > > Matt: use efi_setup instead of esdata
> > >       share function print_efi_memmap for both normal and kexec boot.
> > > 
> > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > ---
> > >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> > >  1 file changed, 17 insertions(+), 7 deletions(-)
> > 
> > Thinking about this a bit more, I'm not at all sure why this patch
> > exists.
> > 
> > Why do we not want to print the entire memory map range like we did in
> > the first kernel? The e820 map is printed exactly like it was in the
> > first kernel, why should the EFI memmap be special?
> 
> Hi, Matt
> 
> Here is the memmap.map print result in kexec kernel (qemu + ovmf).
> I think the memmap.map is not valid any more in kexec kernel, thus we
> should print the saved runtime map.

I have another idea to cleanup the code, that is update efi_info in
userspace kexec-tools, make memmap.map point to saved runtime map in
setup_data, thus the kernel part will be more simple.

Working on it..

> 
> [    0.000000] efi: EFI v2.31 by EDK II
> [    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
> [    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
> [    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
> [    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
> [    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
> [    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
> [    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
> [    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
> [    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
> [    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
> [    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
> [    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
> [    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
> [    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
> [    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
> [    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
> [    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
> [    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
> [    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
> [    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
> [    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
> [    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
> [    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
> [    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
> [    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
> [    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
> [    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
> [    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
> [    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
> [    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)
> 
> 
> > 
> > -- 
> > Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:57         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:57 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59-1xO5oi07KQx4cg9Nei1l7Q, msalter-H+wXaHxf7aLQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, toshi.kani-VXdhtT5mjnY,
	greg-U8xfFu+wG4EAvxtiuMwx3w, x86-DgEjT+Ai2ygdnm+yROfE0A,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk,
	horms-/R6kz+dDXgpPR4JQBCEnsQ, bp-Gina5bIWoIWzQB+pC5nmwQ,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	mingo-DgEjT+Ai2ygdnm+yROfE0A, vgoyal-H+wXaHxf7aLQT0dZR+AlfA

On 12/20/13 at 09:35am, Dave Young wrote:
> On 12/19/13 at 04:41pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > > memmap ranges does not make sense anymore. So introduce a new function to only
> > > print runtime maps in case kexec/kdump kernel is used.
> > > 
> > > changelog:
> > > Matt: use efi_setup instead of esdata
> > >       share function print_efi_memmap for both normal and kexec boot.
> > > 
> > > Signed-off-by: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > ---
> > >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> > >  1 file changed, 17 insertions(+), 7 deletions(-)
> > 
> > Thinking about this a bit more, I'm not at all sure why this patch
> > exists.
> > 
> > Why do we not want to print the entire memory map range like we did in
> > the first kernel? The e820 map is printed exactly like it was in the
> > first kernel, why should the EFI memmap be special?
> 
> Hi, Matt
> 
> Here is the memmap.map print result in kexec kernel (qemu + ovmf).
> I think the memmap.map is not valid any more in kexec kernel, thus we
> should print the saved runtime map.

I have another idea to cleanup the code, that is update efi_info in
userspace kexec-tools, make memmap.map point to saved runtime map in
setup_data, thus the kernel part will be more simple.

Working on it..

> 
> [    0.000000] efi: EFI v2.31 by EDK II
> [    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
> [    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
> [    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
> [    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
> [    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
> [    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
> [    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
> [    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
> [    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
> [    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
> [    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
> [    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
> [    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
> [    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
> [    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
> [    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
> [    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
> [    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
> [    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
> [    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
> [    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
> [    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
> [    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
> [    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
> [    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
> [    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
> [    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
> [    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
> [    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
> [    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)
> 
> 
> > 
> > -- 
> > Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec
@ 2013-12-20  1:57         ` Dave Young
  0 siblings, 0 replies; 78+ messages in thread
From: Dave Young @ 2013-12-20  1:57 UTC (permalink / raw)
  To: Matt Fleming
  Cc: mjg59, msalter, linux-efi, toshi.kani, greg, x86, kexec,
	linux-kernel, leif.lindholm, James.Bottomley, horms, bp,
	ebiederm, hpa, akpm, mingo, vgoyal

On 12/20/13 at 09:35am, Dave Young wrote:
> On 12/19/13 at 04:41pm, Matt Fleming wrote:
> > On Mon, 16 Dec, at 05:30:31PM, Dave Young wrote:
> > > For kexec/kdump kernel efi runtime mappings are saved, printing original whole
> > > memmap ranges does not make sense anymore. So introduce a new function to only
> > > print runtime maps in case kexec/kdump kernel is used.
> > > 
> > > changelog:
> > > Matt: use efi_setup instead of esdata
> > >       share function print_efi_memmap for both normal and kexec boot.
> > > 
> > > Signed-off-by: Dave Young <dyoung@redhat.com>
> > > ---
> > >  arch/x86/platform/efi/efi.c | 24 +++++++++++++++++-------
> > >  1 file changed, 17 insertions(+), 7 deletions(-)
> > 
> > Thinking about this a bit more, I'm not at all sure why this patch
> > exists.
> > 
> > Why do we not want to print the entire memory map range like we did in
> > the first kernel? The e820 map is printed exactly like it was in the
> > first kernel, why should the EFI memmap be special?
> 
> Hi, Matt
> 
> Here is the memmap.map print result in kexec kernel (qemu + ovmf).
> I think the memmap.map is not valid any more in kexec kernel, thus we
> should print the saved runtime map.

I have another idea to cleanup the code, that is update efi_info in
userspace kexec-tools, make memmap.map point to saved runtime map in
setup_data, thus the kernel part will be more simple.

Working on it..

> 
> [    0.000000] efi: EFI v2.31 by EDK II
> [    0.000000] efi:  ACPI=0x1f9e0000  ACPI 2.0=0x1f9e0014 
> [    0.000000] efi: mem00: type=33490747, attr=0x1ff073c, range=[0xffffffff8105542e-0xfffff80fd649d42e) (72057594029606228MB)
> [    0.000000] efi: mem01: type=33490747, attr=0x10756, range=[0xffffffff8105548e-0xfffff80fd650d48e) (72057594029606228MB)
> [    0.000000] efi: mem02: type=67410, attr=0x10758, range=[0xffffffff81055548-0xfffff80fd6630548) (72057594029606229MB)
> [    0.000000] efi: mem03: type=67416, attr=0x1ff0749, range=[0xffffffff810556c2-0xfffff80fd67246c2) (72057594029606230MB)
> [    0.000000] efi: mem04: type=67416, attr=0x10756, range=[0xffffffff810557d1-0xfffff80fd685d7d1) (72057594029606232MB)
> [    0.000000] efi: mem05: type=67410, attr=0x10756, range=[0xffffffff8105584a-0xfffff80fd68b684a) (72057594029606232MB)
> [    0.000000] efi: mem06: type=67415, attr=0x10758, range=[0xffffffff810558b7-0xfffff80fd69168b7) (72057594029606232MB)
> [    0.000000] efi: mem07: type=67417, attr=0x10758, range=[0xffffffff810558fa-0xfffff80fd697c8fa) (72057594029606233MB)
> [    0.000000] efi: mem08: type=67415, attr=0x10758, range=[0xffffffff810559c2-0xfffff80fd6a6b9c2) (72057594029606234MB)
> [    0.000000] efi: mem09: type=67417, attr=0x10754, range=[0xffffffff81055a4f-0xfffff80fd6b2fa4f) (72057594029606234MB)
> [    0.000000] efi: mem10: type=33490778, attr=0x10753, range=[0xffffffff81055b66-0xfffff80fd6c49b66) (72057594029606235MB)
> [    0.000000] efi: mem11: type=67417, attr=0x10753, range=[0xffffffff81055c75-0xfffff80fd6d0dc75) (72057594029606236MB)
> [    0.000000] efi: mem12: type=67411, attr=0x10759, range=[0xffffffff81055dc2-0xfffff80fd6e38dc2) (72057594029606237MB)
> [    0.000000] efi: mem13: type=33490773, attr=0x1ff075a, range=[0xffffffff81055e3e-0xfffff80fd6ea1e3e) (72057594029606238MB)
> [    0.000000] efi: mem14: type=67409, attr=0x10752, range=[0xffffffff81056053-0xfffff80fd7163053) (72057594029606241MB)
> [    0.000000] efi: mem15: type=67409, attr=0x1ff0747, range=[0xffffffff8105612b-0xfffff80fd719012b) (72057594029606241MB)
> [    0.000000] efi: mem16: type=67409, attr=0x10751, range=[0xffffffff8105628c-0xfffff80fd73a828c) (72057594029606243MB)
> [    0.000000] efi: mem17: type=67410, attr=0x10751, range=[0xffffffff81056441-0xfffff80fd74ff441) (72057594029606244MB)
> [    0.000000] efi: mem18: type=67410, attr=0x10752, range=[0xffffffff8105652a-0xfffff80fd761152a) (72057594029606245MB)
> [    0.000000] efi: mem19: type=33490748, attr=0x1072c, range=[0xffffffff810565e6-0xfffff80fd79dc5e6) (72057594029606249MB)
> [    0.000000] efi: mem20: type=67409, attr=0x10751, range=[0xffffffff81056a25-0xfffff80fd7ae0a25) (72057594029606250MB)
> [    0.000000] efi: mem21: type=67372, attr=0x1ff073b, range=[0xffffffff8105745c-0xfffff80fd84bc45c) (72057594029606260MB)
> [    0.000000] efi: mem22: type=33490720, attr=0x1ff0744, range=[0xffffffff81057a3a-0xfffff80fd95d8a3a) (72057594029606277MB)
> [    0.000000] efi: mem23: type=33490757, attr=0x1ff073f, range=[0xffffffff81058659-0xfffff80fd9734659) (72057594029606278MB)
> [    0.000000] efi: mem24: type=33490752, attr=0x1ff074b, range=[0xffffffff81058867-0xfffff80fd98e1867) (72057594029606280MB)
> [    0.000000] efi: mem25: type=67410, attr=0x10751, range=[0xffffffff810589d9-0xfffff80fd9ac79d9) (72057594029606282MB)
> [    0.000000] efi: mem26: type=67414, attr=0x10753, range=[0xffffffff81058b4c-0xfffff80fd9c42b4c) (72057594029606283MB)
> [    0.000000] efi: mem27: type=67416, attr=0x1072c, range=[0xffffffff81058c85-0xfffff80fd9dffc85) (72057594029606285MB)
> [    0.000000] efi: mem28: type=67374, attr=0x1072d, range=[0xffffffff81058e41-0xfffff80fd9eb0e41) (72057594029606286MB)
> 
> 
> > 
> > -- 
> > Matt Fleming, Intel Open Source Technology Center

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

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

end of thread, other threads:[~2013-12-20  1:58 UTC | newest]

Thread overview: 78+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-16  9:30 [PATCH v6 00/14] kexec kernel efi runtime support Dave Young
2013-12-16  9:30 ` Dave Young
2013-12-16  9:30 ` Dave Young
2013-12-16  9:30 ` [PATCH v6 01/14] x86/mm: sparse warning fix for early_memremap Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 02/14] efi: Use early_memremap and early_memunmap to fix sparse warnings Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 03/14] efi: remove unused variables in __map_region Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 04/14] efi: add a wrapper function efi_map_region_fixed Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 05/14] efi: reserve boot service fix Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 06/14] efi: cleanup efi_enter_virtual_mode function Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 07/14] efi: export more efi table variable to sysfs Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 08/14] efi: export efi runtime memory mapping " Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16 15:09   ` Matt Fleming
2013-12-16 15:09     ` Matt Fleming
2013-12-16 15:09     ` Matt Fleming
2013-12-17  6:13     ` Dave Young
2013-12-17  6:13       ` Dave Young
2013-12-17  6:13       ` Dave Young
2013-12-17  8:00   ` [PATCH v7 " Dave Young
2013-12-17  8:00     ` Dave Young
2013-12-17  8:00     ` Dave Young
2013-12-16  9:30 ` [PATCH v6 09/14] efi: passing kexec necessary efi data via setup_data Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-17  8:01   ` [PATCH v7 " Dave Young
2013-12-17  8:01     ` Dave Young
2013-12-17  8:01     ` Dave Young
2013-12-17  8:08     ` Dave Young
2013-12-17  8:08       ` Dave Young
2013-12-17  8:08       ` Dave Young
2013-12-16  9:30 ` [PATCH v6 10/14] efi: only print saved efi runtime maps instead of all memmap ranges for kexec Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-19 16:41   ` Matt Fleming
2013-12-19 16:41     ` Matt Fleming
2013-12-19 16:41     ` Matt Fleming
2013-12-20  1:35     ` Dave Young
2013-12-20  1:35       ` Dave Young
2013-12-20  1:35       ` Dave Young
2013-12-20  1:57       ` Dave Young
2013-12-20  1:57         ` Dave Young
2013-12-20  1:57         ` Dave Young
2013-12-16  9:30 ` [PATCH v6 11/14] x86: add xloadflags bit for efi runtime support on kexec Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 12/14] x86: export x86 boot_params to sysfs Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 13/14] x86: reserve setup_data ranges late after parsing memmap cmdline Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30 ` [PATCH v6 14/14] x86: kdebugfs do not use __va for getting setup_data virt addr Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16  9:30   ` Dave Young
2013-12-16 16:35   ` Matt Fleming
2013-12-16 16:35     ` Matt Fleming
2013-12-16 16:35     ` Matt Fleming
2013-12-17  6:24     ` Dave Young
2013-12-17  6:24       ` Dave Young
2013-12-17  6:24       ` Dave Young
2013-12-17  6:53       ` Dave Young
2013-12-17  6:53         ` Dave Young
2013-12-17  6:53         ` Dave Young
2013-12-17 11:24         ` Matt Fleming
2013-12-17 11:24           ` Matt Fleming
2013-12-17 11:24           ` Matt Fleming
2013-12-18  9:29           ` Dave Young
2013-12-18  9:29             ` Dave Young
2013-12-18  9:29             ` Dave Young

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.