Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

alistair23
Copy link
Contributor

Pull Request Overview

This PR applies on top of #2420

This PR adds support for marking regions of the kernel as protected by PMP.

This allows some regions to have reduced permissions applied to them. This can be used to restrict write/execute to different regions used by the kernel.

Testing Strategy

Boot Tock and an app on OpenTitan FPGA and QEMU.

TODO or Help Wanted

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

@github-actions github-actions bot added arch/risc-v RISC-V architecture WG-OpenTitan In the purview of the OpenTitan working group. labels Feb 10, 2021
@alistair23 alistair23 force-pushed the alistair/pmp-kernel branch from f5b4cdd to c9ba6cd Compare March 8, 2021 20:05
@alistair23 alistair23 requested a review from bradjc March 10, 2021 17:06
Comment on lines +342 to +390
// This is PMP support for kernel regions
// PMP does not allow a deny by default option, so all regions not marked
// with the below commands will have full access.
// This is still a useful implementation as it can be used to limit the
// kernels access, for example removing execute permission from regions
// we don't need to execute from and removing write permissions from
// executable reions.
let mut mpu_config = rv32i::pmp::PMPConfig::default();
// The kernel stack
chip.pmp
.allocate_kernel_region(
&_sstack as *const u8,
&_estack as *const u8 as usize - &_sstack as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel text
chip.pmp
.allocate_kernel_region(
&_stext as *const u8,
&_etext as *const u8 as usize - &_stext as *const u8 as usize,
mpu::Permissions::ReadExecuteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel relocate data
chip.pmp
.allocate_kernel_region(
&_srelocate as *const u8,
&_erelocate as *const u8 as usize - &_srelocate as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel BSS
chip.pmp
.allocate_kernel_region(
&_szero as *const u8,
&_ezero as *const u8 as usize - &_szero as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();

chip.pmp.enable_kernel_mpu(&mut mpu_config);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put all of this in chips/earlgrey? Our chips already (historically) use the linker symbols, but they could also just be passed in to a function. But configuring the PMP seems like a reasonable chip-level operation, and a different board implementation might want to use the exact same code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question. It doesn't really matter too much.

I feel that it fits in boards/ as that is where other similar operations are. For example the stack size is allocated in boards, so I feel that stack protection should also be in boards.

We also only want to enable this after debug is setup (in case something goes wrong), so it makes sense in boards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The board can still call it, and decide when (or if) to call it, just the code would exist in a more central location.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can, but the board will still end up calling it so I don't think we would really save anything.

The HIL for allocate_kernel_region() also says: "It is expected that this function is called in reset_handler()."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have bad memories of duplicated code in main.rs, that's all. Components helped a lot, but I'm wary of setting things up so that code will get copied, and then changes require updating all RISC-V boards (which I do not recommend :)).

This is also similar to load_processes, which is only stored in process.rs for convenience, but is most definitely a board-level function/task. It's just copying it to every main.rs wasn't scalable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would still required changes in all RISC-V if it's in chips.

I still think here is a good place. Maybe arch would work though, then it can just be called from all the boards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this would not even be architecture specific, and tock could by default limit access on all platforms in the same way that this does for OT. But I think it is fine to leave it here for now and worry about code duplication once it actually exists.

Copy link
Contributor

@bradjc bradjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a question about /boards vs. /chips.

hudson-ayers
hudson-ayers previously approved these changes Mar 12, 2021
Comment on lines +342 to +390
// This is PMP support for kernel regions
// PMP does not allow a deny by default option, so all regions not marked
// with the below commands will have full access.
// This is still a useful implementation as it can be used to limit the
// kernels access, for example removing execute permission from regions
// we don't need to execute from and removing write permissions from
// executable reions.
let mut mpu_config = rv32i::pmp::PMPConfig::default();
// The kernel stack
chip.pmp
.allocate_kernel_region(
&_sstack as *const u8,
&_estack as *const u8 as usize - &_sstack as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel text
chip.pmp
.allocate_kernel_region(
&_stext as *const u8,
&_etext as *const u8 as usize - &_stext as *const u8 as usize,
mpu::Permissions::ReadExecuteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel relocate data
chip.pmp
.allocate_kernel_region(
&_srelocate as *const u8,
&_erelocate as *const u8 as usize - &_srelocate as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();
// The kernel BSS
chip.pmp
.allocate_kernel_region(
&_szero as *const u8,
&_ezero as *const u8 as usize - &_szero as *const u8 as usize,
mpu::Permissions::ReadWriteOnly,
&mut mpu_config,
)
.unwrap();

chip.pmp.enable_kernel_mpu(&mut mpu_config);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this would not even be architecture specific, and tock could by default limit access on all platforms in the same way that this does for OT. But I think it is fine to leave it here for now and worry about code duplication once it actually exists.

@alistair23 alistair23 force-pushed the alistair/pmp-kernel branch from 8440dbf to d902dee Compare March 15, 2021 14:43
@alistair23
Copy link
Contributor Author

Ok, all updated!

@bradjc
Copy link
Contributor

bradjc commented Mar 15, 2021

bors r+

@bors
Copy link
Contributor

bors bot commented Mar 15, 2021

@bors bors bot merged commit a996e69 into tock:master Mar 15, 2021
@alistair23 alistair23 deleted the alistair/pmp-kernel branch March 15, 2021 17:22
lschuermann pushed a commit to lschuermann/tock that referenced this pull request Mar 20, 2021
2422: OpenTitan: Enable PMP for kernel regions r=bradjc a=alistair23

### Pull Request Overview

This PR applies on top of tock#2420

This PR adds support for marking regions of the kernel as protected by PMP.

This allows some regions to have reduced permissions applied to them. This can be used to restrict write/execute to different regions used by the kernel.

### Testing Strategy

Boot Tock and an app on OpenTitan FPGA and QEMU.

### TODO or Help Wanted

### Documentation Updated

- [X] Updated the relevant files in `/docs`, or no updates are required.

### Formatting

- [X] Ran `make prepush`.


Co-authored-by: Alistair Francis <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch/risc-v RISC-V architecture WG-OpenTitan In the purview of the OpenTitan working group.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants