Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure CpuFrequency is never explicitly set to zero #29

Merged
merged 1 commit into from
Apr 24, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions src/arch/x86_64/kernel/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,39 +239,45 @@ impl CpuFrequency {
source: CpuFrequencySources::Invalid,
}
}

unsafe fn detect_from_cmdline(&mut self) -> Result<(), ()> {
let mhz = environment::get_command_line_cpu_frequency();
fn set_detected_cpu_frequency(
&mut self,
mhz: u16,
source: CpuFrequencySources,
) -> Result<(), ()> {
//The clock frequency must never be set to zero, otherwise a division by zero will
//occur during runtime
if mhz > 0 {
self.mhz = mhz;
self.source = CpuFrequencySources::CommandLine;
self.source = source;
Ok(())
} else {
Err(())
}
}

unsafe fn detect_from_cmdline(&mut self) -> Result<(), ()> {
let mhz = environment::get_command_line_cpu_frequency();
self.set_detected_cpu_frequency(mhz, CpuFrequencySources::CommandLine)
}

unsafe fn detect_from_cpuid(&mut self, cpuid: &CpuId) -> Result<(), ()> {
let processor_frequency_info = cpuid.get_processor_frequency_info();

if processor_frequency_info.is_some() {
self.mhz = processor_frequency_info.unwrap().processor_base_frequency();
self.source = CpuFrequencySources::CpuId;

Ok(())
} else {
Err(())
match processor_frequency_info {
Some(freq_info) => {
let mhz = freq_info.processor_base_frequency();
self.set_detected_cpu_frequency(mhz, CpuFrequencySources::CpuId)
}
None => Err(()),
}
}

unsafe fn detect_from_cpid_tsc_info(&mut self, cpuid: &CpuId) -> Result<(), ()> {
let tsc_info = cpuid.get_tsc_info();

if tsc_info.is_some() {
self.mhz = (tsc_info.unwrap().tsc_frequency() / 1000000u64) as u16;
self.source = CpuFrequencySources::CpuIdTscInfo;

Ok(())
let mhz = (tsc_info.unwrap().tsc_frequency() / 1000000u64) as u16;
self.set_detected_cpu_frequency(mhz, CpuFrequencySources::CpuIdTscInfo)
} else {
Err(())
}
Expand Down Expand Up @@ -299,9 +305,8 @@ impl CpuFrequency {
hundred_char.to_digit(10),
ten_char.to_digit(10),
) {
self.mhz = (thousand * 1000 + hundred * 100 + ten * 10) as u16;
self.source = CpuFrequencySources::CpuIdBrandString;
return Ok(());
let mhz = (thousand * 1000 + hundred * 100 + ten * 10) as u16;
return self.set_detected_cpu_frequency(mhz, CpuFrequencySources::CpuIdTscInfo);
}
}

Expand All @@ -310,13 +315,7 @@ impl CpuFrequency {

unsafe fn detect_from_hypervisor(&mut self) -> Result<(), ()> {
let cpu_freq = intrinsics::volatile_load(&(*BOOT_INFO).cpu_freq);
if cpu_freq > 0 {
self.mhz = cpu_freq as u16;
self.source = CpuFrequencySources::Hypervisor;
return Ok(());
}

Err(())
self.set_detected_cpu_frequency(cpu_freq as u16, CpuFrequencySources::Hypervisor)
}

extern "x86-interrupt" fn measure_frequency_timer_handler(
Expand Down Expand Up @@ -397,10 +396,8 @@ impl CpuFrequency {

// Calculate the CPU frequency out of this measurement.
let cycle_count = end - start;
self.mhz = (measurement_frequency * cycle_count / (1_000_000 * tick_count)) as u16;
self.source = CpuFrequencySources::Measurement;

Ok(())
let mhz = (measurement_frequency * cycle_count / (1_000_000 * tick_count)) as u16;
self.set_detected_cpu_frequency(mhz, CpuFrequencySources::Measurement)
}

unsafe fn detect(&mut self) {
Expand Down