From 2a00bc042e8d2e8fc923e75039618c186e633e5b Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Thu, 11 Jul 2019 03:01:44 -0700 Subject: [PATCH] Apply CPU features checks so that management CPU cores that can't run supervisor kernels aren't allowed to join the container thread scheduler. Also trim redundant asm from RISC-V boot code --- src/kernel/scheduler.rs | 13 +++++++++++-- src/platform/riscv/asm/entry.s | 5 ----- src/platform/riscv/src/cpu.rs | 27 ++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/kernel/scheduler.rs b/src/kernel/scheduler.rs index bf979f8..c9b94eb 100644 --- a/src/kernel/scheduler.rs +++ b/src/kernel/scheduler.rs @@ -34,10 +34,19 @@ pub fn init(device_tree_buf: &u8) -> Result<(), Cause> } /* activate preemptive multitasking. each CPU core should call this -to start running software threads */ +to start running software threads. CPU cores that can't run user and supervisor-level +code aren't allowed to join the scheduler: these cores are likely auxiliary or +management CPUs that have to park waiting for interrupts */ pub fn start() { - platform::timer::start(); + if platform::cpu::features_priv_check(platform::cpu::PrivilegeMode::User) == true + { + platform::timer::start(); + } + else + { + klog!("Not joining the scheduler, awaiting IRQs"); + } } /* a thread has been running for one timeslice, triggering a timer interrupt. diff --git a/src/platform/riscv/asm/entry.s b/src/platform/riscv/asm/entry.s index 26d5dd6..b6c1a71 100644 --- a/src/platform/riscv/asm/entry.s +++ b/src/platform/riscv/asm/entry.s @@ -79,8 +79,3 @@ enter_kernel: infinite_loop: wfi j infinite_loop - -is_boot_cpu: - # set a0 to true to indicate this is the boot CPU - li a0, 1 - j enter_kernel diff --git a/src/platform/riscv/src/cpu.rs b/src/platform/riscv/src/cpu.rs index 3046dc2..55545bb 100644 --- a/src/platform/riscv/src/cpu.rs +++ b/src/platform/riscv/src/cpu.rs @@ -22,6 +22,10 @@ const EXTENSIONS: &'static [&'static str] = &["a", "b", "c", "d", "e", "f", "g", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; +/* flags within CPUFeatures, derived from misa */ +const CPUFEATURES_SUPERVISOR_MODE: usize = 1 << 18; /* supervisor mode is implemented */ +const CPUFEATURES_USER_MODE: usize = 1 << 20; /* user mode is implemented */ + /* levels of privilege accepted by the kernel */ #[derive(Copy, Clone, Debug)] pub enum PrivilegeMode @@ -126,6 +130,23 @@ pub fn features() -> CPUFeatures return read_csr!(misa) as CPUFeatures; } +/* check that this CPU core has sufficient features to run code at the given privilege level + => required = privilege level required + <= return true if CPU can run code at the required privilege, false if not */ +pub fn features_priv_check(required: PrivilegeMode) -> bool +{ + let cpu = read_csr!(misa); + + /* all RISC-V cores provide machine (kernel) mode. Diosix requires supervisor mode for user mode */ + match (required, cpu & CPUFEATURES_SUPERVISOR_MODE != 0, cpu & CPUFEATURES_USER_MODE != 0) + { + ( PrivilegeMode::Kernel, _, _) => true, + (PrivilegeMode::Supervisor, true, _) => true, + ( PrivilegeMode::User, true, true) => true, + _ => false + } +} + /* provide an iterator that lists descriptive strings about this CPU core */ pub fn describe() -> CPUDescriptionIter { @@ -180,9 +201,9 @@ impl Iterator for CPUDescriptionIter check anyway for diagnostic purposes */ Some(match self.misa >> width_shift { - 1 => "32-bit RISC-V, extensions: ", - 2 => "64-bit RISC-V, extensions: ", - _ => "Unsupported RISC-V, extensions: " + 1 => "32-bit RISC-V, ext: ", + 2 => "64-bit RISC-V, ext: ", + _ => "Unsupported RISC-V, ext: " }) }, CPUDescriptionState::Extension(index) =>