Skip to content

Commit 3a40611

Browse files
aarkegzluodebhky1999
authored
Interrupt-injection and GPPT (#31)
* feat(vcpu): add interrupt injection support and enhance system register handling - Add interrupt injection support to Aarch64VCpu - Implement get_sysreg_device function for system register access - Update GuestSystemRegisters to include CNTHCTL_EL2 - Modify exception handling to use SysRegAddr - Adjust vcpu initialization to enable virtual IRQ and FIQ * feat(sysreg): update handle_read and handle_write to use unused parameters * update dependecies * update percpu * try setting ich_hcr_el2.en * [feat] use 4 level paging for ept * better code and comment for setting ich_hcr_el2 * add error messages for `current_el_sync_handler` * pin rust toolchain version * set `CNTHCTL_EL2::EL1PCEN` and `CNTHCTL_EL2::EL1PTCEN`, unset `HCR_EL2::IMO` to allow Guest to handle irqs themselves * [STINKS] embed vgicv3 devices with HARD-CODED qemu gicv3 address location * [feat] introduce set_return_value API * [WIP!][TOBEREWRITE!] add gic-vdevice cofigs * fixes after merging ivc code * fix branch names for `axvcpu` * emulate `ICC_SGI1R_EL1` * update to newest dependencies * de-coupling `arm_vcpu` and `arm_vgic`, fix some warnings * fix a missing doc * remove `arm_vgic` dependency * add `builtin_sysreg_access_handler`, add interrupt and timer passthrough config * remove sysreg emu devices * rollback `tock-registers` to 0.9 * reformatted --------- Co-authored-by: Debin <luodeb@outlook.com> Co-authored-by: hky1999 <976929993@qq.com>
1 parent 1e107bc commit 3a40611

File tree

8 files changed

+217
-40
lines changed

8 files changed

+217
-40
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ edition = "2024"
77
log = "0.4.21"
88
spin = "0.9"
99

10-
aarch64-cpu = "9.3"
11-
tock-registers = "0.8"
10+
aarch64-cpu = "10.0"
11+
tock-registers = "0.9"
1212
numeric-enum-macro = "0.2"
1313

1414
axerrno = "0.1.0"
1515
percpu = { version = "0.2.0", features = ["arm-el2"] }
16-
aarch64_sysreg = "0.1.1"
1716

1817
axaddrspace = { git = "https://github.com/arceos-hypervisor/axaddrspace.git" }
1918
axvcpu = { git = "https://github.com/arceos-hypervisor/axvcpu.git" }
19+
axdevice_base = { git = "https://github.com/arceos-hypervisor/axdevice_crates.git" }
20+
axvisor_api = { git = "https://github.com/arceos-hypervisor/axvisor_api.git" }

rust-toolchain.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[toolchain]
2+
profile = "minimal"
3+
channel = "nightly-2024-12-25"
4+
components = ["rust-src", "llvm-tools", "rustfmt", "clippy"]
5+
targets = [
6+
"aarch64-unknown-none",
7+
"aarch64-unknown-none-softfloat",
8+
]

src/context_frame.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use core::arch::asm;
2-
use core::fmt::Formatter;
1+
use core::{arch::asm, fmt::Formatter};
32

43
use aarch64_cpu::registers::*;
54

@@ -156,6 +155,7 @@ pub struct GuestSystemRegisters {
156155
cntv_ctl_el0: u32,
157156
cntp_tval_el0: u32,
158157
cntv_tval_el0: u32,
158+
pub cnthctl_el2: u64,
159159

160160
// vpidr and vmpidr
161161
vpidr_el2: u32,
@@ -220,6 +220,7 @@ impl GuestSystemRegisters {
220220
asm!("mrs {0:x}, CNTP_TVAL_EL0", out(reg) self.cntp_tval_el0);
221221
asm!("mrs {0:x}, CNTV_TVAL_EL0", out(reg) self.cntv_tval_el0);
222222
asm!("mrs {0}, CNTVCT_EL0", out(reg) self.cntvct_el0);
223+
asm!("mrs {0}, CNTHCTL_EL2", out(reg) self.cnthctl_el2);
223224
// MRS!("self.vpidr_el2, VPIDR_EL2, "x");
224225
asm!("mrs {0}, VMPIDR_EL2", out(reg) self.vmpidr_el2);
225226

@@ -265,6 +266,7 @@ impl GuestSystemRegisters {
265266
asm!("msr CNTV_CVAL_EL0, {0}", in(reg) self.cntv_cval_el0);
266267
asm!("msr CNTKCTL_EL1, {0:x}", in (reg) self.cntkctl_el1);
267268
asm!("msr CNTV_CTL_EL0, {0:x}", in (reg) self.cntv_ctl_el0);
269+
asm!("msr CNTHCTL_EL2, {0}", in(reg) self.cnthctl_el2);
268270
// The restoration of SP_EL0 is done in `exception_return_el2`,
269271
// which move the value from `self.ctx.sp_el0` to `SP_EL0`.
270272
// asm!("msr SP_EL0, {0}", in(reg) self.sp_el0);

src/exception.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
use aarch64_cpu::registers::{ESR_EL2, HCR_EL2, Readable, SCTLR_EL1, VTCR_EL2, VTTBR_EL2};
2-
3-
use axaddrspace::GuestPhysAddr;
4-
use axaddrspace::device::AccessWidth;
5-
use axerrno::{AxError, AxResult};
6-
use axvcpu::AxVCpuExitReason;
7-
81
use crate::TrapFrame;
92
use crate::exception_utils::{
103
exception_class, exception_class_value, exception_data_abort_access_is_write,
@@ -15,6 +8,15 @@ use crate::exception_utils::{
158
exception_sysreg_direction_write, exception_sysreg_gpr,
169
};
1710

11+
use aarch64_cpu::registers::{ESR_EL2, HCR_EL2, Readable, SCTLR_EL1, VTCR_EL2, VTTBR_EL2};
12+
use axaddrspace::{
13+
GuestPhysAddr,
14+
device::{AccessWidth, SysRegAddr},
15+
};
16+
use axerrno::{AxError, AxResult};
17+
use axvcpu::AxVCpuExitReason;
18+
use log::error;
19+
1820
numeric_enum_macro::numeric_enum! {
1921
#[repr(u8)]
2022
#[derive(Debug)]
@@ -179,6 +181,7 @@ fn handle_data_abort(context_frame: &mut TrapFrame) -> AxResult<AxVCpuExitReason
179181
width,
180182
reg,
181183
reg_width,
184+
signed_ext: false,
182185
})
183186
}
184187

@@ -204,11 +207,14 @@ fn handle_system_register(context_frame: &mut TrapFrame) -> AxResult<AxVCpuExitR
204207
context_frame.set_exception_pc(val);
205208
if write {
206209
return Ok(AxVCpuExitReason::SysRegWrite {
207-
addr,
210+
addr: SysRegAddr::new(addr),
208211
value: context_frame.gpr(reg as usize) as u64,
209212
});
210213
}
211-
Ok(AxVCpuExitReason::SysRegRead { addr, reg })
214+
Ok(AxVCpuExitReason::SysRegRead {
215+
addr: SysRegAddr::new(addr),
216+
reg,
217+
})
212218
}
213219

214220
/// Handles HVC or SMC exceptions that serve as psci (Power State Coordination Interface) calls.
@@ -284,6 +290,14 @@ fn current_el_irq_handler(_tf: &mut TrapFrame) {
284290
/// Handles synchronous exceptions that occur from the current exception level.
285291
#[unsafe(no_mangle)]
286292
fn current_el_sync_handler(tf: &mut TrapFrame) {
293+
let esr = ESR_EL2.extract();
294+
let ec = ESR_EL2.read(ESR_EL2::EC);
295+
let iss = ESR_EL2.read(ESR_EL2::ISS);
296+
297+
error!("ESR_EL2: {:#x}", esr.get());
298+
error!("Exception Class: {:#x}", ec);
299+
error!("Instruction Specific Syndrome: {:#x}", iss);
300+
287301
panic!(
288302
"Unhandled synchronous exception from current EL: {:#x?}",
289303
tf

src/exception_utils.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use aarch64_cpu::registers::{ESR_EL2, FAR_EL2, PAR_EL1};
2-
use tock_registers::interfaces::*;
3-
42
use axaddrspace::GuestPhysAddr;
53
use axerrno::{AxResult, ax_err};
4+
use tock_registers::interfaces::*;
65

76
/// Retrieves the Exception Syndrome Register (ESR) value from EL2.
87
///

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mod smc;
1515
mod vcpu;
1616

1717
pub use self::pcpu::Aarch64PerCpu;
18-
pub use self::vcpu::{Aarch64VCpu, Aarch64VCpuCreateConfig};
18+
pub use self::vcpu::{Aarch64VCpu, Aarch64VCpuCreateConfig, Aarch64VCpuSetupConfig};
1919

2020
/// context frame for aarch64
2121
pub type TrapFrame = context_frame::Aarch64ContextFrame;

src/pcpu.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use core::{cell::OnceCell, marker::PhantomData};
22

33
use aarch64_cpu::registers::*;
4-
use tock_registers::interfaces::ReadWriteable;
5-
64
use axerrno::AxResult;
75
use axvcpu::{AxArchPerCpu, AxVCpuHal};
6+
use tock_registers::interfaces::ReadWriteable;
87

98
/// Per-CPU data. A pointer to this struct is loaded into TP when a CPU starts. This structure
109
#[repr(C)]
@@ -64,6 +63,19 @@ impl<H: AxVCpuHal> AxArchPerCpu for Aarch64PerCpu<H> {
6463
+ HCR_EL2::TSC::EnableTrapEl1SmcToEl2,
6564
);
6665

66+
// Note that `ICH_HCR_EL2` is not the same as `HCR_EL2`.
67+
//
68+
// `ICH_HCR_EL2[0]` controls the virtual CPU interface operation.
69+
//
70+
// We leave it for the virtual GIC implementations to decide whether to enable it or not.
71+
//
72+
// unsafe {
73+
// core::arch::asm! {
74+
// "msr ich_hcr_el2, {value:x}",
75+
// value = in(reg) 0,
76+
// }
77+
// }
78+
6779
Ok(())
6880
}
6981

0 commit comments

Comments
 (0)