mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
x86_64: set reset vector when using bios
BIOS expect all the cpus to be pointed at the i386 reset vector before boot. We can't guarantee that a fresh vcpu will be pointed to the reset vector by default, so we should set the reset vector when we're configuring the vcpu when we're using a BIOS. Cherrypick from downstream branch. Actual author: Colin Downs-Razouk <colindr@google.com>. TEST=builds BUG=b:213152505 Change-Id: Idf4e0a200c8141adf5cbb83856cbd57362d84716 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3657811 Reviewed-by: Colin Downs-Razouk <colindr@google.com> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Noah Gold <nkgold@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
953670c3ea
commit
ebb6efe266
2 changed files with 29 additions and 0 deletions
|
@ -777,6 +777,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
}
|
||||
|
||||
if has_bios {
|
||||
regs::set_reset_vector(vcpu).map_err(Error::SetupRegs)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ pub enum Error {
|
|||
/// Failed to get sregs for this cpu.
|
||||
#[error("failed to get sregs for this cpu: {0}")]
|
||||
GetSRegsIoctlFailed(base::Error),
|
||||
/// Failed to get base registers for this cpu.
|
||||
#[error("failed to get base registers for this cpu: {0}")]
|
||||
GettingRegistersIoctl(base::Error),
|
||||
/// Setting up msrs failed.
|
||||
#[error("setting up msrs failed: {0}")]
|
||||
MsrIoctlFailed(base::Error),
|
||||
|
@ -349,6 +352,31 @@ pub fn setup_sregs(mem: &GuestMemory, vcpu: &dyn VcpuX86_64) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Configures a CPU to be pointed at the i386 reset vector.
|
||||
///
|
||||
/// The reset vector is the default location a CPU will go to find the first instruction it will
|
||||
/// execute after a reset. On i386, the reset vector means the RIP is set to 0xfff0 the CS base is
|
||||
/// set to 0xffff0000, and the CS selector is set to 0xf000.
|
||||
///
|
||||
/// When using a BIOS, each of the VCPUs should be pointed at the reset vector before execution
|
||||
/// begins.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `vcpu` - the VCPU to configure.
|
||||
pub fn set_reset_vector(vcpu: &dyn VcpuX86_64) -> Result<()> {
|
||||
let mut sregs = vcpu.get_sregs().map_err(Error::GetSRegsIoctlFailed)?;
|
||||
let mut regs = vcpu.get_regs().map_err(Error::GettingRegistersIoctl)?;
|
||||
|
||||
regs.rip = 0xfff0;
|
||||
sregs.cs.base = 0xffff0000;
|
||||
sregs.cs.selector = 0xf000;
|
||||
|
||||
vcpu.set_sregs(&sregs).map_err(Error::SetSRegsIoctlFailed)?;
|
||||
vcpu.set_regs(®s).map_err(Error::SettingRegistersIoctl)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue