From 2730e6579677174d4fbe517c1aec9c22b7638067 Mon Sep 17 00:00:00 2001 From: Ivan-Velickovic Date: Fri, 9 Jun 2023 22:13:42 +1000 Subject: [PATCH] Mark CLINT as reserved device on RISC-V platforms Without this patch, user-level programs have the ability to map in the core-local interrupt controller on RISC-V platforms which contains the memory-mapped registers for the core-local timer the kernel uses. This is a level of privilege that user-level programs should not have. Writing to the `mtime` register is possible which can then affect the timer interrupts are delivered to the kernel. Signed-off-by: Ivan-Velickovic --- CHANGES | 3 +++ src/plat/ariane/overlay-ariane.dts | 13 ++++++++++ src/plat/hifive/overlay-hifive.dts | 20 +++++++++++--- src/plat/polarfire/overlay-polarfire.dts | 12 +++++++++ .../overlay-qemu-riscv-virt.dts | 9 +++++++ src/plat/rocketchip/config.cmake | 1 + .../rocketchip/overlay-rocketchip-base.dts | 21 +++++++++++++++ .../rocketchip/overlay-rocketchip-zcu102.dts | 17 +++++++++--- src/plat/spike/config.cmake | 1 + src/plat/spike/overlay-spike.dts | 26 +++++++++++++++++++ tools/hardware.yml | 11 ++++++++ 11 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 src/plat/rocketchip/overlay-rocketchip-base.dts create mode 100644 src/plat/spike/overlay-spike.dts diff --git a/CHANGES b/CHANGES index eb96255aa..54665a506 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,9 @@ Upcoming release: BREAKING * Changed how `gen_config.h` files are generated. Previously, they were generated at CMake configure time. Now, they are generated at build time as a dependency of the `${prefix}_Gen` target. To manually build the kernel `gen_config.h` file after running `cmake`, run `ninja gen_config/kernel/gen_config.h`. +* Remove the ability for user-space on RISC-V platforms to access the core-local interrupt controller (CLINT). The + CLINT contains memory-mapped registers that the kernel depends on for timer interrupts and hence should not be + accessible by user-space. ## Upgrade Notes diff --git a/src/plat/ariane/overlay-ariane.dts b/src/plat/ariane/overlay-ariane.dts index e3ea0fc2e..ae38aa6fa 100644 --- a/src/plat/ariane/overlay-ariane.dts +++ b/src/plat/ariane/overlay-ariane.dts @@ -7,6 +7,19 @@ / { chosen { seL4,kernel-devices = + &{/soc/clint@2000000}, &{/soc/interrupt-controller@c000000}; }; + + /* + * The size and address of the CLINT is from the memory map listed in the + * CVA6 documentation. It can be found here: + * https://docs.openhwgroup.org/projects/cva6-user-manual/05_cva6_apu/cva6_apu.html#memory-map + */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x00000000 0x2000000 0x00000000 0x0000c0000>; + }; + }; }; diff --git a/src/plat/hifive/overlay-hifive.dts b/src/plat/hifive/overlay-hifive.dts index e3ea0fc2e..530ebaa3d 100644 --- a/src/plat/hifive/overlay-hifive.dts +++ b/src/plat/hifive/overlay-hifive.dts @@ -5,8 +5,20 @@ */ / { - chosen { - seL4,kernel-devices = - &{/soc/interrupt-controller@c000000}; - }; + chosen { + seL4,kernel-devices = + &{/soc/clint@2000000}, + &{/soc/interrupt-controller@c000000}; + }; + + /* + * According to the SiFive "FU540-C000 Manual" (version v1p4) + * the CLINT is mapped from 0x0200_0000 to 0x0200_FFFF. + */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x00000000 0x2000000 0x00000000 0x000010000>; + }; + }; }; diff --git a/src/plat/polarfire/overlay-polarfire.dts b/src/plat/polarfire/overlay-polarfire.dts index 11195b114..7b90f0429 100644 --- a/src/plat/polarfire/overlay-polarfire.dts +++ b/src/plat/polarfire/overlay-polarfire.dts @@ -7,6 +7,18 @@ / { chosen { seL4,kernel-devices = + &{/soc/clint@2000000}, &{/soc/interrupt-controller@c000000}; }; + + /* + * According to the "PolarFire SoC MSS Technical Reference Manual" + * (revision H), the CLINT is mapped from 0x0200_0000 to 0x0200_FFFF. + */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x00000000 0x2000000 0x00000000 0x000010000>; + }; + }; }; diff --git a/src/plat/qemu-riscv-virt/overlay-qemu-riscv-virt.dts b/src/plat/qemu-riscv-virt/overlay-qemu-riscv-virt.dts index 36f930b6f..34a43eaf2 100644 --- a/src/plat/qemu-riscv-virt/overlay-qemu-riscv-virt.dts +++ b/src/plat/qemu-riscv-virt/overlay-qemu-riscv-virt.dts @@ -15,6 +15,15 @@ * */ seL4,kernel-devices = + &{/soc/clint@2000000}, &{/soc/plic@c000000}; }; + + /* The size and address of the CLINT is derived from QEMU source code. */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x00000000 0x2000000 0x00000000 0x000010000>; + }; + }; }; diff --git a/src/plat/rocketchip/config.cmake b/src/plat/rocketchip/config.cmake index b83338ccc..ea59d2aae 100644 --- a/src/plat/rocketchip/config.cmake +++ b/src/plat/rocketchip/config.cmake @@ -50,6 +50,7 @@ if(KernelPlatformRocketchip) INTERRUPT_CONTROLLER drivers/irq/riscv_plic0.h ) else() + list(APPEND KernelDTSList "src/plat/rocketchip/overlay-rocketchip-base.dts") config_set(KernelOpenSBIPlatform OPENSBI_PLATFORM "generic") # This is an experimental platform that supports accessing peripherals, but # the status of support for external interrupts via a PLIC is unclear and diff --git a/src/plat/rocketchip/overlay-rocketchip-base.dts b/src/plat/rocketchip/overlay-rocketchip-base.dts new file mode 100644 index 000000000..9170965fc --- /dev/null +++ b/src/plat/rocketchip/overlay-rocketchip-base.dts @@ -0,0 +1,21 @@ +/* + * Copyright 2023, UNSW + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/ { + chosen { + seL4,kernel-devices = + &{/soc/clint@2000000}, + &{/soc/interrupt-controller@c000000}; + }; + + /* The size and address of the CLINT is derived from the Rocketchip source code. */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x2000000 0x10000>; + }; + }; +}; diff --git a/src/plat/rocketchip/overlay-rocketchip-zcu102.dts b/src/plat/rocketchip/overlay-rocketchip-zcu102.dts index 6d8729587..568c92aef 100644 --- a/src/plat/rocketchip/overlay-rocketchip-zcu102.dts +++ b/src/plat/rocketchip/overlay-rocketchip-zcu102.dts @@ -5,10 +5,19 @@ */ / { - chosen { - seL4,kernel-devices = - &{/soc/interrupt-controller@c000000}; - }; + chosen { + seL4,kernel-devices = + &{/soc/clint@2000000}, + &{/soc/interrupt-controller@c000000}; + }; + + /* The size and address of the CLINT is derived from the Rocketchip source code. */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x2000000 0x10000>; + }; + }; /delete-node/ memory@80000000; diff --git a/src/plat/spike/config.cmake b/src/plat/spike/config.cmake index d2799fa12..fb1a0d01f 100644 --- a/src/plat/spike/config.cmake +++ b/src/plat/spike/config.cmake @@ -26,6 +26,7 @@ if(KernelPlatformSpike) else() list(APPEND KernelDTSList "tools/dts/spike.dts") endif() + list(APPEND KernelDTSList "src/plat/spike/overlay-spike.dts") declare_default_headers( TIMER_FREQUENCY 10000000 PLIC_MAX_NUM_INT 0 INTERRUPT_CONTROLLER drivers/irq/riscv_plic_dummy.h diff --git a/src/plat/spike/overlay-spike.dts b/src/plat/spike/overlay-spike.dts new file mode 100644 index 000000000..3d2c757ac --- /dev/null +++ b/src/plat/spike/overlay-spike.dts @@ -0,0 +1,26 @@ +/* + * Copyright 2023, UNSW + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/ { + chosen { + seL4,kernel-devices = + &{/soc/clint@2000000}; + }; + + /* + * The size and address of the CLINT is derived from the source code + * of QEMU (which supports the Spike as a platform) and the Spike RISC-V + * ISA simulator. At the time of writing the two simulators do not agree + * on the size of the CLINT. We take the larger of the two sizes (0xc0000) + * in order to be safe. + */ + soc { + clint@2000000 { + compatible = "riscv,cpu-intc"; + reg = <0x00000000 0x2000000 0x00000000 0x0000c0000>; + }; + }; +}; diff --git a/tools/hardware.yml b/tools/hardware.yml index 33d6e0c07..cf55f22f9 100644 --- a/tools/hardware.yml +++ b/tools/hardware.yml @@ -208,6 +208,17 @@ devices: kernel: PLIC_PPTR kernel_size: 0x04000000 + # SiFive CLINT (HiFive, Polarfire, Ariane, QEMU RISC-V virt, Spike) + # Note that not all CLINTs with this compatible string are of the same size. + # However, omitting the kernel_size field works as each kernel device frame + # is of size 0x200000, which is currently larger than the CLINT's of all + # supported platforms. + - compatible: + - riscv,cpu-intc + regions: + - index: 0 + kernel: CLINT_PPTR + # elfloader rules - compatible: - arm,psci-0.2