Skip to content

Commit 79ce892

Browse files
committed
enabled mapping of an empty page during TVM runtime
Signed-off-by: Wojciech Ozga <woz@zurich.ibm.com>
1 parent 0c592c6 commit 79ce892

14 files changed

Lines changed: 108 additions & 49 deletions

File tree

security-monitor/src/confidential_flow/handlers/mmio/mmio_access_fault.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,48 @@
11
// SPDX-FileCopyrightText: 2023 IBM Corporation
22
// SPDX-FileContributor: Wojciech Ozga <woz@zurich.ibm.com>, IBM Research - Zurich
33
// SPDX-License-Identifier: Apache-2.0
4-
use crate::core::control_data::{ConfidentialHart, ConfidentialVmId, ConfidentialVmMmioRegion, ControlDataStorage};
4+
use crate::confidential_flow::handlers::symmetrical_multiprocessing::RemoteHfenceGvmaVmid;
5+
use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow};
6+
use crate::core::architecture::{is_bit_enabled, PageSize};
7+
use crate::core::control_data::{
8+
ConfidentialHart, ConfidentialHartRemoteCommand, ConfidentialVmId, ConfidentialVmMmioRegion, ControlDataStorage,
9+
};
10+
use crate::core::memory_layout::ConfidentialVmPhysicalAddress;
11+
512
use core::mem;
613

714
pub struct MmioAccessFault {
815
cause: usize,
916
mtval: usize,
10-
instruction_length: usize,
17+
mtinst: usize,
18+
fault_address: usize,
1119
}
1220

1321
impl MmioAccessFault {
1422
pub const ADDRESS_ALIGNMENT: usize = mem::size_of::<usize>();
1523

16-
pub fn new(cause: usize, mtval: usize, instruction_length: usize) -> Self {
17-
Self { cause, mtval, instruction_length }
24+
pub fn new(cause: usize, mtval: usize, mtinst: usize, fault_address: usize) -> Self {
25+
Self { cause, mtval, mtinst, fault_address }
26+
}
27+
28+
pub fn handle(self, mut confidential_flow: ConfidentialFlow) -> ! {
29+
match ControlDataStorage::try_confidential_vm_mut(confidential_flow.confidential_vm_id(), |mut confidential_vm| {
30+
let confidential_vm_physical_address = ConfidentialVmPhysicalAddress::new(self.fault_address);
31+
let page_size = confidential_vm.memory_protector_mut().map_empty_page(confidential_vm_physical_address, PageSize::Size4KiB)?;
32+
let request = RemoteHfenceGvmaVmid::all_harts(None, page_size, confidential_flow.confidential_vm_id());
33+
confidential_flow
34+
.broadcast_remote_command(&mut confidential_vm, ConfidentialHartRemoteCommand::RemoteHfenceGvmaVmid(request))?;
35+
Ok(())
36+
}) {
37+
Ok(_) => confidential_flow.exit_to_confidential_hart(),
38+
Err(_) => confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::MmioAccessFault(self)),
39+
}
1840
}
1941

2042
pub fn apply_to_confidential_hart(&self, confidential_hart: &mut ConfidentialHart) {
21-
let mepc = confidential_hart.csrs().mepc.read_from_main_memory() + self.instruction_length;
43+
let instruction = self.mtinst | 0x3;
44+
let instruction_length = if is_bit_enabled(self.mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 };
45+
let mepc = confidential_hart.csrs().mepc.read_from_main_memory() + instruction_length;
2246
confidential_hart.csrs_mut().vsepc.write(mepc);
2347
let trap_vector_address = confidential_hart.csrs().vstvec.read();
2448
confidential_hart.csrs_mut().mepc.save_value_in_main_memory(trap_vector_address);

security-monitor/src/confidential_flow/handlers/mmio/mmio_load_request.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0
44
use crate::confidential_flow::handlers::mmio::{MmioAccessFault, MmioLoadPending};
55
use crate::confidential_flow::handlers::sbi::SbiResponse;
6-
use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow};
6+
use crate::confidential_flow::ConfidentialFlow;
77
use crate::core::architecture::is_bit_enabled;
88
use crate::core::architecture::specification::CAUSE_LOAD_ACCESS;
99
use crate::core::control_data::{ConfidentialHart, HypervisorHart, ResumableOperation};
@@ -28,17 +28,15 @@ impl MmioLoadRequest {
2828
}
2929

3030
pub fn handle(self, confidential_flow: ConfidentialFlow) -> ! {
31-
// According to the RISC-V privilege spec, mtinst encodes faulted instruction (bit 0 is 1) or a pseudo instruction
32-
assert!(self.mtinst & 0x1 > 0);
33-
let instruction = self.mtinst | 0x3;
34-
let instruction_length = if is_bit_enabled(self.mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 };
35-
3631
let fault_address = (self.mtval2 << 2) | (self.mtval & 0x3);
3732
if !MmioAccessFault::tried_to_access_valid_mmio_region(confidential_flow.confidential_vm_id(), fault_address) {
38-
let mmio_access_fault_handler = MmioAccessFault::new(CAUSE_LOAD_ACCESS.into(), self.mtval, instruction_length);
39-
confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::MmioAccessFault(mmio_access_fault_handler));
33+
MmioAccessFault::new(CAUSE_LOAD_ACCESS.into(), self.mtval, self.mtinst, fault_address).handle(confidential_flow)
4034
}
4135

36+
// According to the RISC-V privilege spec, mtinst encodes faulted instruction (bit 0 is 1) or a pseudo instruction
37+
assert!(self.mtinst & 0x1 > 0);
38+
let instruction = self.mtinst | 0x3;
39+
let instruction_length = if is_bit_enabled(self.mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 };
4240
match crate::core::architecture::decode_result_register(instruction) {
4341
Ok(gpr) => confidential_flow
4442
.set_resumable_operation(ResumableOperation::MmioLoad(MmioLoadPending::new(instruction_length, gpr)))

security-monitor/src/confidential_flow/handlers/mmio/mmio_store_request.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0
44
use crate::confidential_flow::handlers::mmio::{MmioAccessFault, MmioStorePending};
55
use crate::confidential_flow::handlers::sbi::SbiResponse;
6-
use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow};
6+
use crate::confidential_flow::ConfidentialFlow;
77
use crate::core::architecture::specification::CAUSE_STORE_ACCESS;
88
use crate::core::architecture::{is_bit_enabled, GeneralPurposeRegister};
99
use crate::core::control_data::{ConfidentialHart, HypervisorHart, ResumableOperation};
@@ -28,9 +28,6 @@ impl MmioStoreRequest {
2828
let mtval = confidential_hart.csrs().mtval.read();
2929
let mtval2 = confidential_hart.csrs().mtval2.read();
3030

31-
// According to the RISC-V privilege spec, mtinst encodes faulted instruction when bit 0 is 1.
32-
// Otherwise it is a pseudo instruction.
33-
assert!(mtinst & 0x1 > 0);
3431
let instruction = mtinst | 0x3;
3532
let instruction_length = if is_bit_enabled(mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 };
3633
let gpr = crate::core::architecture::decode_result_register(instruction);
@@ -42,8 +39,7 @@ impl MmioStoreRequest {
4239
pub fn handle(self, confidential_flow: ConfidentialFlow) -> ! {
4340
let fault_address = (self.mtval2 << 2) | (self.mtval & 0x3);
4441
if !MmioAccessFault::tried_to_access_valid_mmio_region(confidential_flow.confidential_vm_id(), fault_address) {
45-
let mmio_access_fault_handler = MmioAccessFault::new(CAUSE_STORE_ACCESS.into(), self.mtval, self.instruction_length);
46-
confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::MmioAccessFault(mmio_access_fault_handler));
42+
MmioAccessFault::new(CAUSE_STORE_ACCESS.into(), self.mtval, self.mtinst, fault_address).handle(confidential_flow)
4743
}
4844

4945
match self.gpr {

security-monitor/src/confidential_flow/handlers/shared_page/share_page_complete.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ impl SharePageComplete {
4545

4646
ControlDataStorage::try_confidential_vm_mut(confidential_flow.confidential_vm_id(), |mut confidential_vm| {
4747
let page_size = confidential_vm.memory_protector_mut().map_shared_page(hypervisor_address, self.request.address)?;
48-
let request = RemoteHfenceGvmaVmid::all_harts(&self.request.address, page_size, confidential_flow.confidential_vm_id());
48+
let request =
49+
RemoteHfenceGvmaVmid::all_harts(Some(self.request.address.clone()), page_size, confidential_flow.confidential_vm_id());
4950
confidential_flow
5051
.broadcast_remote_command(&mut confidential_vm, ConfidentialHartRemoteCommand::RemoteHfenceGvmaVmid(request))?;
5152
Ok(())

security-monitor/src/confidential_flow/handlers/shared_page/unshare_page_request.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl UnsharePageRequest {
4848
let confidential_vm_id = confidential_flow.confidential_vm_id();
4949
ControlDataStorage::try_confidential_vm_mut(confidential_vm_id, |mut confidential_vm| {
5050
let unmapped_page_size = confidential_vm.memory_protector_mut().unmap_shared_page(&self.address)?;
51-
let request = RemoteHfenceGvmaVmid::all_harts(&self.address, unmapped_page_size, confidential_vm_id);
51+
let request = RemoteHfenceGvmaVmid::all_harts(Some(self.address.clone()), unmapped_page_size, confidential_vm_id);
5252
confidential_flow
5353
.broadcast_remote_command(&mut confidential_vm, ConfidentialHartRemoteCommand::RemoteHfenceGvmaVmid(request))?;
5454
Ok(())

security-monitor/src/confidential_flow/handlers/shutdown/shutdown_vm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::core::control_data::{ConfidentialHart, ConfidentialHartRemoteCommand,
1313
/// To shutdown the entire confidential VM and remove it from the control data memory, all confidential harts must be
1414
/// shutdown (lifecycle state `Shutdown`). To do so, we send `Shutdown IPI` to all confidential harts. The last
1515
/// confidential hart that shutdowns itself, will remove the entire confidential VM from the control data.
16-
#[derive(Clone)]
16+
#[derive(Clone, PartialEq)]
1717
pub struct ShutdownRequest {
1818
calling_hart_id: usize,
1919
}

security-monitor/src/confidential_flow/handlers/symmetrical_multiprocessing/fence_i.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::core::control_data::{
99
};
1010

1111
/// Handles a request from one confidential hart to execute fence.i instruction on remote confidential harts.
12-
#[derive(Clone)]
12+
#[derive(Clone, PartialEq)]
1313
pub struct RemoteFenceI {
1414
ipi: Ipi,
1515
}

security-monitor/src/confidential_flow/handlers/symmetrical_multiprocessing/hfence_gvma_vmid.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ use crate::core::control_data::{ConfidentialHart, ConfidentialHartRemoteCommandE
77
use crate::core::memory_layout::ConfidentialVmPhysicalAddress;
88

99
/// An inter hart request sent by the security monitor to clear G-stage level cached address translations.
10-
#[derive(Clone)]
10+
#[derive(Clone, PartialEq)]
1111
pub struct RemoteHfenceGvmaVmid {
1212
ipi: Ipi,
13-
_start_address: usize,
13+
_start_address: Option<ConfidentialVmPhysicalAddress>,
1414
_size: PageSize,
1515
_vmid: ConfidentialVmId,
1616
}
1717

1818
impl RemoteHfenceGvmaVmid {
19-
pub fn all_harts(start_address: &ConfidentialVmPhysicalAddress, _size: PageSize, _vmid: ConfidentialVmId) -> Self {
20-
Self { ipi: Ipi::all_harts(), _start_address: start_address.usize(), _size, _vmid }
19+
pub fn all_harts(start_address: Option<ConfidentialVmPhysicalAddress>, _size: PageSize, _vmid: ConfidentialVmId) -> Self {
20+
Self { ipi: Ipi::all_harts(), _start_address: start_address, _size, _vmid }
2121
}
2222
}
2323

security-monitor/src/confidential_flow/handlers/symmetrical_multiprocessing/sfence_vma.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::core::control_data::{
1010
};
1111

1212
/// Handles a request from one confidential hart to execute sfence.vma instruction on remote confidential harts.
13-
#[derive(Clone)]
13+
#[derive(Clone, PartialEq)]
1414
pub struct RemoteSfenceVma {
1515
ipi: Ipi,
1616
_start_address: usize,

security-monitor/src/confidential_flow/handlers/symmetrical_multiprocessing/sfence_vma_asid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::core::control_data::{
1111

1212
/// Handles a request from one confidential hart to execute sfence.vma instruction on remote confidential harts. It represents an inter hart
1313
/// request.
14-
#[derive(Clone)]
14+
#[derive(Clone, PartialEq)]
1515
pub struct RemoteSfenceVmaAsid {
1616
ipi: Ipi,
1717
_start_address: usize,

0 commit comments

Comments
 (0)