Checks ID_AA64MMFR0_EL1 for at least 36 bits physical address (#967)

This commit is contained in:
Putta Khunchalee 2024-09-06 00:40:59 +07:00 committed by GitHub
parent 2dadcebc9e
commit cc1dc7e43c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 24 additions and 18 deletions

View File

@ -12,6 +12,8 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
- name: Update Rust
run: rustup update stable
- name: Add additional Rust targets
run: rustup target add x86_64-unknown-none
- name: Lint Rust sources

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::hv::{Cpu, CpuStates};
use super::hw::RamMap;
use super::MainCpuError;
@ -8,7 +9,7 @@ pub fn setup_main_cpu(cpu: &mut impl Cpu, entry: usize, map: RamMap) -> Result<(
.states()
.map_err(|e| MainCpuError::GetCpuStatesFailed(Box::new(e)))?;
let mmfr0 = states
.get_id_aa64_mmfr0()
.get_id_aa64mmfr0()
.map_err(|e| MainCpuError::GetIdAa64mmfr0Failed(Box::new(e)))?;
match map.page_size.get() {
@ -20,6 +21,13 @@ pub fn setup_main_cpu(cpu: &mut impl Cpu, entry: usize, map: RamMap) -> Result<(
_ => todo!(),
}
// Check if CPU support at least 36 bits physical address.
let pa_range = mmfr0 & 0xF;
if pa_range == 0 {
return Err(MainCpuError::PhysicalAddressTooSmall);
}
// Set PSTATE so the PE run in AArch64 mode. Not sure why we need M here since the document said
// it is ignore. See https://gist.github.com/imbushuo/51b09e61ecd7b7ac063853ad65cedf34 where
// M = 5 came from.

View File

@ -14,6 +14,7 @@ type hv_vcpu_t = hv_sys::hv_vcpu_t;
#[allow(non_camel_case_types)]
type hv_vcpu_t = hv_sys::hv_vcpuid_t;
#[cfg(target_arch = "x86_64")]
macro_rules! wrap_return {
($ret:expr) => {
match NonZero::new($ret) {
@ -129,7 +130,7 @@ impl<'a> Cpu for HfCpu<'a> {
fn states(&mut self) -> Result<Self::States<'_>, Self::GetStatesErr> {
Ok(HfStates {
cpu: self,
id_aa64_mmfr0: State::None,
id_aa64mmfr0: State::None,
pstate: State::None,
sctlr_el1: State::None,
mair_el1: State::None,
@ -190,7 +191,7 @@ impl<'a> Drop for HfCpu<'a> {
pub struct HfStates<'a, 'b> {
cpu: &'a mut HfCpu<'b>,
#[cfg(target_arch = "aarch64")]
id_aa64_mmfr0: State<u64>,
id_aa64mmfr0: State<u64>,
#[cfg(target_arch = "x86_64")]
rsp: State<usize>,
#[cfg(target_arch = "x86_64")]
@ -237,16 +238,16 @@ impl<'a, 'b> CpuStates for HfStates<'a, 'b> {
type Err = StatesError;
#[cfg(target_arch = "aarch64")]
fn get_id_aa64_mmfr0(&mut self) -> Result<u64, Self::Err> {
fn get_id_aa64mmfr0(&mut self) -> Result<u64, Self::Err> {
use hv_sys::hv_sys_reg_t_HV_SYS_REG_ID_AA64MMFR0_EL1 as HV_SYS_REG_ID_AA64MMFR0_EL1;
let v = match self.id_aa64_mmfr0 {
let v = match self.id_aa64mmfr0 {
State::None => {
let v = self
.cpu
.read_sys(HV_SYS_REG_ID_AA64MMFR0_EL1)
.map_err(StatesError::ReadRegisterFailed)?;
self.id_aa64_mmfr0 = State::Clean(v);
self.id_aa64mmfr0 = State::Clean(v);
v
}
State::Clean(v) | State::Dirty(v) => v,

View File

@ -59,7 +59,7 @@ pub trait CpuStates {
type Err: Error + Send + 'static;
#[cfg(target_arch = "aarch64")]
fn get_id_aa64_mmfr0(&mut self) -> Result<u64, Self::Err>;
fn get_id_aa64mmfr0(&mut self) -> Result<u64, Self::Err>;
#[cfg(target_arch = "x86_64")]
fn set_rdi(&mut self, v: usize);

View File

@ -744,6 +744,10 @@ enum MainCpuError {
#[error("vCPU does not support {0:#x} page size")]
PageSizeNotSupported(NonZero<usize>),
#[cfg(target_arch = "aarch64")]
#[error("physical address supported by vCPU too small")]
PhysicalAddressTooSmall,
#[error("couldn't commit vCPU states")]
CommitCpuStatesFailed(#[source] Box<dyn Error + Send>),
}

View File

@ -5,7 +5,6 @@ use crate::config::set_boot_env;
use crate::context::Context;
use crate::malloc::KernelHeap;
use crate::proc::Thread;
use alloc::string::String;
use alloc::sync::Arc;
use core::arch::asm;
use core::mem::zeroed;
@ -82,16 +81,8 @@ fn panic(i: &PanicInfo) -> ! {
None => ("unknown", 0),
};
// Get message.
let msg = if let Some(&v) = i.payload().downcast_ref::<&str>() {
v
} else if let Some(v) = i.payload().downcast_ref::<String>() {
v
} else {
"unknown panic payload"
};
crate::console::error(file, line, msg);
// Print the message.
crate::console::error(file, line, i.message());
crate::panic::panic();
}