From d7c1591e54527b15bcf1e4ac7cf1e1bc2dc98315 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Tue, 14 Jul 2020 10:46:24 -0700 Subject: [PATCH] x86_64 configure_vcpu handles image type Regardless of what image type crosvm is running, it must set the cpuid since the cpuid is not set by software. This missing setting was preventing uboot from jumping to the 64 bit kernel since it thought the cpu was not long mode capable. BUG=b:153027511 TEST=Booted cuttlefish with and without uboot Change-Id: Ib8902b324532daf2a0e8ff462603207ff0c64bad Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2298171 Tested-by: kokoro Reviewed-by: Daniel Verkamp Commit-Queue: Ram Muthiah --- x86_64/src/lib.rs | 55 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/x86_64/src/lib.rs b/x86_64/src/lib.rs index 239222d684..7c75d76344 100644 --- a/x86_64/src/lib.rs +++ b/x86_64/src/lib.rs @@ -371,16 +371,15 @@ impl arch::LinuxArch for X8664arch { let mut vcpus = Vec::with_capacity(vcpu_count as usize); for cpu_id in 0..vcpu_count { let vcpu = Vcpu::new(cpu_id as libc::c_ulong, &kvm, &vm).map_err(Error::CreateVcpu)?; - if let VmImage::Kernel(_) = components.vm_image { - Self::configure_vcpu( - vm.get_memory(), - &kvm, - &vm, - &vcpu, - cpu_id as u64, - vcpu_count as u64, - )?; - } + Self::configure_vcpu( + vm.get_memory(), + &kvm, + &vm, + &vcpu, + cpu_id as u64, + vcpu_count as u64, + &components.vm_image, + )?; vcpus.push(vcpu); } @@ -941,13 +940,12 @@ impl X8664arch { /// # Arguments /// /// * `guest_mem` - The memory to be used by the guest. - /// * `kernel_load_offset` - Offset in bytes from `guest_mem` at which the - /// kernel starts. /// * `kvm` - The /dev/kvm object that created vcpu. /// * `vm` - The VM object associated with this VCPU. /// * `vcpu` - The VCPU object to configure. /// * `cpu_id` - The id of the given `vcpu`. /// * `num_cpus` - Number of virtual CPUs the guest will have. + /// * `image_type` - Type of image being run on vcpu fn configure_vcpu( guest_mem: &GuestMemory, kvm: &Kvm, @@ -955,23 +953,26 @@ impl X8664arch { vcpu: &Vcpu, cpu_id: u64, num_cpus: u64, + image_type: &VmImage, ) -> Result<()> { - let kernel_load_addr = GuestAddress(KERNEL_START_OFFSET); cpuid::setup_cpuid(kvm, vcpu, cpu_id, num_cpus).map_err(Error::SetupCpuid)?; - regs::setup_msrs(vcpu, END_ADDR_BEFORE_32BITS).map_err(Error::SetupMsrs)?; - let kernel_end = guest_mem - .checked_offset(kernel_load_addr, KERNEL_64BIT_ENTRY_OFFSET) - .ok_or(Error::KernelOffsetPastEnd)?; - regs::setup_regs( - vcpu, - (kernel_end).offset() as u64, - BOOT_STACK_POINTER as u64, - ZERO_PAGE_OFFSET as u64, - ) - .map_err(Error::SetupRegs)?; - regs::setup_fpu(vcpu).map_err(Error::SetupFpu)?; - regs::setup_sregs(guest_mem, vcpu).map_err(Error::SetupSregs)?; - interrupts::set_lint(vcpu).map_err(Error::SetLint)?; + if let VmImage::Kernel(_) = image_type { + let kernel_load_addr = GuestAddress(KERNEL_START_OFFSET); + regs::setup_msrs(vcpu, END_ADDR_BEFORE_32BITS).map_err(Error::SetupMsrs)?; + let kernel_end = guest_mem + .checked_offset(kernel_load_addr, KERNEL_64BIT_ENTRY_OFFSET) + .ok_or(Error::KernelOffsetPastEnd)?; + regs::setup_regs( + vcpu, + (kernel_end).offset() as u64, + BOOT_STACK_POINTER as u64, + ZERO_PAGE_OFFSET as u64, + ) + .map_err(Error::SetupRegs)?; + regs::setup_fpu(vcpu).map_err(Error::SetupFpu)?; + regs::setup_sregs(guest_mem, vcpu).map_err(Error::SetupSregs)?; + interrupts::set_lint(vcpu).map_err(Error::SetLint)?; + } Ok(()) } }