All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/2] x86: Add IMR support to Quark/Galileo
@ 2015-01-28 18:36 Bryan O'Donoghue
  2015-01-28 18:36 ` [PATCH 1/2] x86: Add Isolated Memory Regions for Quark X1000 Bryan O'Donoghue
  2015-01-28 18:36 ` [PATCH 2/2] x86, quark: Add Intel Quark platform support Bryan O'Donoghue
  0 siblings, 2 replies; 38+ messages in thread
From: Bryan O'Donoghue @ 2015-01-28 18:36 UTC (permalink / raw)
  To: tglx, mingo, hpa, x86, dvhart, andy.shevchenko, boon.leong.ong,
	linux-kernel
  Cc: Bryan O'Donoghue

This patchset adds support for Isolated Memory Regions to the kernel.

Quark SoC X1000 contains a set of registers called Isolated Memory Regions.
IMRs provide fine grained memory access control to various system agents
within the SoC such as CPU SMM/non-SMM mode, PCIe virtual channels, CPU
snoop cycles, eSRAM flush cycles and the RMU. In simple terms, IMRs provide
a mechanism to protect memory regions from unwarranted access by system
agents that should not have access to that memory.

IMRs support a lock bit. Once a lock bit is set for an individual IMR it is
not possible to tear down that IMR without performing a cold boot of the
system. IMRs support reporting of violations. The SoC system can be
configured to reboot immediately when an IMR violation has taken place.
Immediate reboot of the system on IMR violation is recommended and is
currently how Quark BIOS configures the system.

An example of IMRs in use is given with Arduino compatiable Galileo boards
which ship with an IMR around the ACPI runtime services memory. If a DMA
read/write cycle were to occur to this region of memory this would trigger
the IMR violation mechansim.

As part of the IMR init code all unlocked IMRs are removed to ensure the
EFI memory map and IMR memory map are consistent. This is necessary since at
various stages during the boot of Quark systems firmware and second stage
bootloader will place unlocked IMRs around various assets in memory, with
the expectation that subsequent phases of boot will tear-down unlocked/stale
IMRs before proceeding. The kernel needs to tear-down unlocked IMRs placed
around the boot params structure and compressed kernel in memory. Without
doing so DMA addresses given out by the kernel to DMA capable hardware runs
the risk of triggering an IMR fault when DMA happens to those addresses.
As a result any unlocked IMR must be torn down by the kernel early in the
boot process to sanitize the memory map. 

As an additional protection to the run-time kernel from unwarranted memory
transactions an IMR is placed around the kernel's .text and .rodata
sections. 

Changes since v5:
 - Full stops
   Added to all comments - including one-liners.
   Andy Shevchenko
 - %zu and %zx
   Used to print size_t variables
   Andy Shevchenko
 - imr_selftest
   Split into seperate module
   Andy Shevchenko
Changes since v4:
 - Quark added as a platform in a separate patch to IMRs
   Andy Shevchenko
 - imr_read
   Add extra reg++ to end of read for consistency
   Andy Shevchenko
 - ret
   Declarations of return variable moved to end of each declaration block
   Andy Shevchenko
 - Parameters passed to debugfs hooks
   Andy Shevchenko
 - struct imr_dev *idev = &imr_dev;
   Used globally for entry point functions
   Andy Shevchenko/Bryan O'Donoghue
 - struct imr_dev * passed to static functions
   Andy Shevchenko/Bryan O'Donoghue
 - Comment in imr_fixup_memmap
   Paried down and made more readable
   Andy Shevchenko
 - imr_fixup_memmap/imr_selftest
   phys_addr_t used for base
   Andy Shevchenko
 - phys_addr_t/size_t
   Supplemented globally in place of unsigned long where appropriate
   Bryan O'Donoghue
 - print routines to take %pa globally
   In place of pr_info("0x%08lx\n", (unsigned long)some_phs_addr_t_variable);
   Andy Shevchenko
 - debugfs hook moved to after init = true
   Andy Shevchenko

Changes since v3:
 - Remove reference to imr.o in arch/x86/kernel/Makefile
   Bryan O'Donoghue

Changes since v2:
 - Move IMR code to arch/x86/platform/intel-quark/imr.c
   Thomas Gleixner/Darren Hart
 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
    Andy Shevchenko
 - ret = iosf_mbi_read()
    Style made consistent in imr_write
    Andy Shevchenko
 - reg++/IMR_NUM_REGS
    Offset used for lock bit in imr_write
    Andy Shevchenko
 - debugfs s->private pointer used
    Andy Shevchenko
 - debugfs
    Conditional compilation defines removed
    Andy Shevchenko
 - debugfs
    Failure to hook debugfs treated as non-fatal
    Andy Shevchenko
 - phys_addr_t
    Updated API to use phys_addr_t in place of unsigned long for base param
    Andy Shevchenko
 - printk
    "KiB" instead of "k"
    Andy Shevchenko
 - imr_enabled
    -> static inline imr_is_enabled
    Ong, Boon Leong/Andy Shevchenko
 - imr_write
    trap final ret from iosf_mbi_write for lock bit in imr_write - bugfix
    Ong, Boon Leong
 - imr_fixup_size
    -> static inline imr_fixup_size
    Ong, Boon Leong
 - imr_address_overlap
    -> imr_address_overlap
    Ong, Boon Leong
 - imr_add_range
    End address in imr_add_range calculated after imr_fixup_size()
    Ong, Boon Leong
 - imr_del_range
    Pass i in place of reg in imr_del_range() - bugfix
    Ong, Boon Leong
 - Add test case
    imr_del_range(-1, addr, size)
    Ong, Boon Leong/Andy Shevchenko
 - Added text "aligned to 1 KiB" removed reference to "4 k"
    Ong, Boon Leong
 - imr_is_enabled
    Definition of enabled updated to be negation of disabled
    Bryan O'Donoghue
 - imr_add_range
    Add check for adding an IMR in the disabled state
    Bryan O'Donoghue
 - Add test case IMR @ invalid address, @0 with rmask/wmask=CPU, @ 0 size 0x800
    Bryan O'Donoghue
 - Add WARN() to failed IMR test in print routine
    Bryan O'Donoghue
 - Update license to Dual BSD/GPL
    Reflect licensing in Intel reference code
    Bryan O'Donoghue

Changes since v1:
 - Galileo platform code
    Removed completely. Policy to tear-down unlocked IMRs and setup IMR
    around kernel .text and .rodata as part of IMR init code.
    Darren Hart/Ong, Boon Leong
 - imr_add/imr_del
    Renamed to imr_add_range and imr_del_range respectively.
    Andy Shevchenko
 - x86_match_cpu
    Used in place of DMI strings specific to Galileo.
    Andy Shevchenko/Ong, Boon Leong
 - Expanded git log definitions of IMRs
    Addition of more descriptive text to deliniate between different IMR
    types.
    Ong, Boon Leong
 - struct imr
    Renamed to struct imr_regs
    Andy Shevchenko/Darren Hart
 - imr_read/imr_write
    Flow reworked flow of register indexing
    Andy Shevchenko
 - debugfs hooks changed
    Andy Shevchenko
 - imr_enabled
    Definition of an enabled IMR updated to include read/write mask values
    present in IMR. Address @ zero and read/write mask in conjunction will
    be the definition of a disabled IMR on X1000 to be consistent with
    firmware both old and current which also defines a disabled IMR this
    way.
    Darren Hart/Ong, Boon Leong
 - Overlapping
    Comment added to code to explain the design decision not to allow IMR
    overlaps.
    Darren Hart/Ong, Boon Leong
 - CONFIG_DEBUG_IMR_SELFTEST
    Automated IMR self test moved from removed Galileo platform code and
    added to IMR init code. Option exists in the kernel hacking section.
    Darren Hart
 - IMR self test
    Expanded to over more scenarios
    Bryan O'Donoghue
 - Remove reference to IMR_ENABLE bit
    Undocumented bit with respect to Quark X1000
    Ong, Boon Leong
 - Expanded kernel IMR to encompass .text and .rodata
    IMR protecting both .text and .rodata as in the same way as .text and
    .rodata are marked read-only in the relevant page-table entries.
    Bryan O'Donoghue
 - Overlap bounds checking
    Moved range checking of overlap into a function
    Andy Shevchenko

Bryan O'Donoghue (2):
  x86: Add Isolated Memory Regions for Quark X1000
  x86, quark: Add Intel Quark platform support

 arch/x86/Kconfig                             |  16 +
 arch/x86/Kconfig.debug                       |  12 +
 arch/x86/include/asm/imr.h                   |  60 +++
 arch/x86/platform/Makefile                   |   1 +
 arch/x86/platform/intel-quark/Makefile       |   2 +
 arch/x86/platform/intel-quark/imr.c          | 616 +++++++++++++++++++++++++++
 arch/x86/platform/intel-quark/imr_selftest.c | 135 ++++++
 drivers/platform/x86/Kconfig                 |  25 ++
 8 files changed, 867 insertions(+)
 create mode 100644 arch/x86/include/asm/imr.h
 create mode 100644 arch/x86/platform/intel-quark/Makefile
 create mode 100644 arch/x86/platform/intel-quark/imr.c
 create mode 100644 arch/x86/platform/intel-quark/imr_selftest.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 38+ messages in thread
* [PATCH 0/2] x86: Add IMR support to Quark/Galileo
@ 2014-12-29 17:23 Bryan O'Donoghue
  2014-12-29 17:23 ` [PATCH 1/2] x86: Add Isolated Memory Regions for Quark X1000 Bryan O'Donoghue
  0 siblings, 1 reply; 38+ messages in thread
From: Bryan O'Donoghue @ 2014-12-29 17:23 UTC (permalink / raw)
  To: tglx, mingo, hpa, x86, dvhart, platform-driver-x86, linux-kernel
  Cc: Bryan O'Donoghue

This patchset adds an IMR driver to the kernel plus platform code for
Intel Galileo Gen1/Gen2 boards.

IMRs:
Quark SoC X1000 ships with a set of registers called Isolated Memory Regions
IMRs provide fine grained memory access control to various system agents
within the SoC such as CPU SMM/non-SMM mode, PCIe virtual channels, CPU snoop
cycles, eSRAM flush cycles and the RMU. In simple terms, IMRs provide a
mechanism to protect memory regions from unwarranted access by system agents
that should not have access to that memory.

IMRs support a lock bit. Once a lock bit is set for an individual IMR it is
not possible to tear down that IMR without performing a cold boot of the
system. IMRs support reporting of violations. The SoC system can be
configured to reboot immediately when an IMR violation has taken place.
Immediate reboot of the system on IMR violation is recommended and is
currently how Quark BIOS configures the system.

As an example Galileo boards ship with an IMR around the ACPI runtime
services memory and if a DMA read/write cycle were to occur to this region
of memory this would trigger the IMR violation mechansim. 

Galileo:
Intel's Arduino compatible Galileo boards boot to Linux with IMRs protecting
the compressed kernel image and boot params data structure. The memory that
the compressed kernel and boot params data structure is in, is marked as
usable memory by the EFI memory map. As a result it is possible for memory
marked as processor read/write only in an IMR to be given to devices in the
SoC for the purposes of DMA by way of dma_alloc_coherent.
A DMA to a region of memory by a system agent which is not allowed access
this memory result in a system reset. Without tearing down the IMRs placed
around the compressed kernel image and boot params data structure there is a
high risk of triggering an inadvertent system reset when performing DMA
actions with any of the peripherals that support DMA in Quark such as the
MMC, Ethernet or USB host/device.

Therefore Galileo specific platform code is the second component of this
patchset. The platform code tears-down every unlocked IMR to ensure no
conflict exists between the IMR usage during boot and the EFI memory map. In
addition an IMR is placed around the kernel's .text section to ensure no
invalid access to kernel code can happen by way of spurious DMA, SMM or RMU
read/write cycles. This code gets compiled into the kernel because we want
to run the code early before any DMA has taken place. The prime examples of
DMA transactions resetting the system are mouting a root filesystem on MMC
or mouting a root filesystem over NFS.

Bryan O'Donoghue (2):
  x86: Add Isolated Memory Regions for Quark X1000
  platform/x86 Add Intel Galileo platform specific setup

 arch/x86/Kconfig                     |  23 ++
 arch/x86/include/asm/imr.h           |  79 ++++++
 arch/x86/include/asm/intel-quark.h   |  31 ++
 arch/x86/kernel/Makefile             |   1 +
 arch/x86/kernel/imr.c                | 529 +++++++++++++++++++++++++++++++++++
 drivers/platform/x86/Kconfig         |  15 +
 drivers/platform/x86/Makefile        |   1 +
 drivers/platform/x86/intel_galileo.c | 175 ++++++++++++
 8 files changed, 854 insertions(+)
 create mode 100644 arch/x86/include/asm/imr.h
 create mode 100644 arch/x86/include/asm/intel-quark.h
 create mode 100644 arch/x86/kernel/imr.c
 create mode 100644 drivers/platform/x86/intel_galileo.c

-- 
1.9.1


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

end of thread, other threads:[~2015-01-29 16:28 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-28 18:36 [PATCH v6 0/2] x86: Add IMR support to Quark/Galileo Bryan O'Donoghue
2015-01-28 18:36 ` [PATCH 1/2] x86: Add Isolated Memory Regions for Quark X1000 Bryan O'Donoghue
2015-01-29  5:38   ` Darren Hart
2015-01-29  7:44   ` Ingo Molnar
2015-01-29 10:08     ` Andy Shevchenko
2015-01-29 10:12       ` Bryan O'Donoghue
2015-01-29 13:47         ` Ong, Boon Leong
2015-01-29 15:22           ` Bryan O'Donoghue
2015-01-29 15:32             ` Ong, Boon Leong
2015-01-29 15:40               ` Bryan O'Donoghue
2015-01-29 16:12                 ` Bryan O'Donoghue
2015-01-29 16:26                   ` Ong, Boon Leong
2015-01-29 15:15         ` Ong, Boon Leong
2015-01-29 13:27     ` Bryan O'Donoghue
2015-01-29  9:59   ` Ong, Boon Leong
2015-01-28 18:36 ` [PATCH 2/2] x86, quark: Add Intel Quark platform support Bryan O'Donoghue
  -- strict thread matches above, loose matches on Subject: below --
2014-12-29 17:23 [PATCH 0/2] x86: Add IMR support to Quark/Galileo Bryan O'Donoghue
2014-12-29 17:23 ` [PATCH 1/2] x86: Add Isolated Memory Regions for Quark X1000 Bryan O'Donoghue
2014-12-31 15:05   ` Andy Shevchenko
2015-01-01 20:11     ` Bryan O'Donoghue
2015-01-06  7:36   ` Darren Hart
2015-01-06 13:43     ` Bryan O'Donoghue
2015-01-06 16:54       ` Darren Hart
2015-01-07 23:45       ` Ong, Boon Leong
2015-01-07 23:45         ` Ong, Boon Leong
2015-01-08 12:10         ` Bryan O'Donoghue
2015-01-08 12:10           ` Bryan O'Donoghue
2015-01-08 14:52           ` Ong, Boon Leong
2015-01-08 14:52             ` Ong, Boon Leong
2015-01-08  0:04   ` Ong, Boon Leong
2015-01-08  0:04     ` Ong, Boon Leong
2015-01-08 13:08     ` Bryan O'Donoghue
2015-01-08 13:08       ` Bryan O'Donoghue
2015-01-08 14:45       ` Ong, Boon Leong
2015-01-08 14:45         ` Ong, Boon Leong
2015-01-08 15:11         ` Bryan O'Donoghue
2015-01-08 15:11           ` Bryan O'Donoghue
2015-01-09  3:44           ` Darren Hart
2015-01-09  3:44             ` Darren Hart

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.