Skip to content
Snippets Groups Projects
  1. Jan 20, 2024
    • Paolo Bonzini's avatar
      target/i386: pcrel: store low bits of physical address in data[0] · c46f68bd
      Paolo Bonzini authored
      For PC-relative translation blocks, env->eip changes during the
      execution of a translation block, Therefore, QEMU must be able to
      recover an instruction's PC just from the TranslationBlock struct and
      the instruction data with.  Because a TB will not span two pages, QEMU
      stores all the low bits of EIP in the instruction data and replaces them
      in x86_restore_state_to_opc.  Bits 12 and higher (which may vary between
      executions of a PCREL TB, since these only use the physical address in
      the hash key) are kept unmodified from env->eip.  The assumption is that
      these bits of EIP, unlike bits 0-11, will not change as the translation
      block executes.
      
      Unfortunately, this is incorrect when the CS base is not aligned to a page.
      Then the linear address of the instructions (i.e. the one with the
      CS base addred) indeed will never span two pages, but bits 12+ of EIP
      can actually change.  For example, if CS base is 0x80262200 and EIP =
      0x6FF4, the first instruction in the translation block will be at linear
      address 0x802691F4.  Even a very small TB will cross to EIP = 0x7xxx,
      while the linear addresses will remain comfortably within a single page.
      
      The fix is simply to use the low bits of the linear address for data[0],
      since those don't change.  Then x86_restore_state_to_opc uses tb->cs_base
      to compute a temporary linear address (referring to some unknown
      instruction in the TB, but with the correct values of bits 12 and higher);
      the low bits are replaced with data[0], and EIP is obtained by subtracting
      again the CS base.
      
      Huge thanks to Mark Cave-Ayland for the image and initial debugging,
      and to Gitlab user @kjliew for help with bisecting another occurrence
      of (hopefully!) the same bug.
      
      It should be relatively easy to write a testcase that performs MMIO on
      an EIP with different bits 12+ than the first instruction of the translation
      block; any help is welcome.
      
      Fixes: e3a79e0e ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
      Cc: qemu-stable@nongnu.org
      Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
      Cc: Richard Henderson <richard.henderson@linaro.org>
      Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
      Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
      Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
      
      
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      (cherry picked from commit 729ba8e933f8af5800c3a92b37e630e9bdaa9f1e)
      Signed-off-by: default avatarMichael Tokarev <mjt@tls.msk.ru>
      c46f68bd
    • guoguangyao's avatar
      target/i386: fix incorrect EIP in PC-relative translation blocks · 652c34cb
      guoguangyao authored
      
      The PCREL patches introduced a bug when updating EIP in the !CF_PCREL case.
      Using s->pc in func gen_update_eip_next() solves the problem.
      
      Cc: qemu-stable@nongnu.org
      Fixes: b5e0d5d2 ("target/i386: Fix 32-bit wrapping of pc/eip computation")
      Signed-off-by: default avatarguoguangyao <guoguangyao18@mails.ucas.ac.cn>
      Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
      Message-ID: <20240115020804.30272-1-guoguangyao18@mails.ucas.ac.cn>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      (cherry picked from commit 2926eab8969908bc068629e973062a0fb6ff3759)
      Signed-off-by: default avatarMichael Tokarev <mjt@tls.msk.ru>
      652c34cb
    • Richard Henderson's avatar
      target/i386: Do not re-compute new pc with CF_PCREL · 6e8e580e
      Richard Henderson authored
      
      With PCREL, we have a page-relative view of EIP, and an
      approximation of PC = EIP+CSBASE that is good enough to
      detect page crossings.  If we try to recompute PC after
      masking EIP, we will mess up that approximation and write
      a corrupt value to EIP.
      
      We already handled masking properly for PCREL, so the
      fix in b5e0d5d2 was only needed for the !PCREL path.
      
      Cc: qemu-stable@nongnu.org
      Fixes: b5e0d5d2 ("target/i386: Fix 32-bit wrapping of pc/eip computation")
      Reported-by: default avatarMichael Tokarev <mjt@tls.msk.ru>
      Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
      Message-ID: <20240101230617.129349-1-richard.henderson@linaro.org>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      (cherry picked from commit a58506b748b8988a95f4fa1a2420ac5c17038b30)
      Signed-off-by: default avatarMichael Tokarev <mjt@tls.msk.ru>
      6e8e580e
  2. Dec 12, 2023
  3. Dec 06, 2023
    • Michael Roth's avatar
      i386/sev: Avoid SEV-ES crash due to missing MSR_EFER_LMA bit · 5746f70d
      Michael Roth authored
      
      Commit 7191f24c ("accel/kvm/kvm-all: Handle register access errors")
      added error checking for KVM_SET_SREGS/KVM_SET_SREGS2. In doing so, it
      exposed a long-running bug in current KVM support for SEV-ES where the
      kernel assumes that MSR_EFER_LMA will be set explicitly by the guest
      kernel, in which case EFER write traps would result in KVM eventually
      seeing MSR_EFER_LMA get set and recording it in such a way that it would
      be subsequently visible when accessing it via KVM_GET_SREGS/etc.
      
      However, guest kernels currently rely on MSR_EFER_LMA getting set
      automatically when MSR_EFER_LME is set and paging is enabled via
      CR0_PG_MASK. As a result, the EFER write traps don't actually expose the
      MSR_EFER_LMA bit, even though it is set internally, and when QEMU
      subsequently tries to pass this EFER value back to KVM via
      KVM_SET_SREGS* it will fail various sanity checks and return -EINVAL,
      which is now considered fatal due to the aforementioned QEMU commit.
      
      This can be addressed by inferring the MSR_EFER_LMA bit being set when
      paging is enabled and MSR_EFER_LME is set, and synthesizing it to ensure
      the expected bits are all present in subsequent handling on the host
      side.
      
      Ultimately, this handling will be implemented in the host kernel, but to
      avoid breaking QEMU's SEV-ES support when using older host kernels, the
      same handling can be done in QEMU just after fetching the register
      values via KVM_GET_SREGS*. Implement that here.
      
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Marcelo Tosatti <mtosatti@redhat.com>
      Cc: Tom Lendacky <thomas.lendacky@amd.com>
      Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
      Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
      Cc: Lara Lazier <laramglazier@gmail.com>
      Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
      Cc: Maxim Levitsky <mlevitsk@redhat.com>
      Cc:  <kvm@vger.kernel.org>
      Fixes: 7191f24c ("accel/kvm/kvm-all: Handle register access errors")
      Signed-off-by: default avatarMichael Roth <michael.roth@amd.com>
      Acked-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Message-ID: <20231206155821.1194551-1-michael.roth@amd.com>
      5746f70d
  4. Nov 17, 2023
  5. Nov 07, 2023
  6. Nov 06, 2023
    • David Woodhouse's avatar
      hw/xen: select kernel mode for per-vCPU event channel upcall vector · 18e83f28
      David Woodhouse authored
      
      A guest which has configured the per-vCPU upcall vector may set the
      HVM_PARAM_CALLBACK_IRQ param to fairly much anything other than zero.
      
      For example, Linux v6.0+ after commit b1c3497e604 ("x86/xen: Add support
      for HVMOP_set_evtchn_upcall_vector") will just do this after setting the
      vector:
      
             /* Trick toolstack to think we are enlightened. */
             if (!cpu)
                     rc = xen_set_callback_via(1);
      
      That's explicitly setting the delivery to GSI#1, but it's supposed to be
      overridden by the per-vCPU vector setting. This mostly works in Qemu
      *except* for the logic to enable the in-kernel handling of event channels,
      which falsely determines that the kernel cannot accelerate GSI delivery
      in this case.
      
      Add a kvm_xen_has_vcpu_callback_vector() to report whether vCPU#0 has
      the vector set, and use that in xen_evtchn_set_callback_param() to
      enable the kernel acceleration features even when the param *appears*
      to be set to target a GSI.
      
      Preserve the Xen behaviour that when HVM_PARAM_CALLBACK_IRQ is set to
      *zero* the event channel delivery is disabled completely. (Which is
      what that bizarre guest behaviour is working round in the first place.)
      
      Cc: qemu-stable@nongnu.org
      Fixes: 91cce756 ("hw/xen: Add xen_evtchn device for event channel emulation")
      Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
      Reviewed-by: default avatarPaul Durrant <paul@xen.org>
      18e83f28
    • David Woodhouse's avatar
      i386/xen: fix per-vCPU upcall vector for Xen emulation · e7dbb62f
      David Woodhouse authored
      
      The per-vCPU upcall vector support had three problems. Firstly it was
      using the wrong hypercall argument and would always return -EFAULT when
      the guest tried to set it up. Secondly it was using the wrong ioctl() to
      pass the vector to the kernel and thus the *kernel* would always return
      -EINVAL. Finally, even when delivering the event directly from userspace
      with an MSI, it put the destination CPU ID into the wrong bits of the
      MSI address.
      
      Linux doesn't (yet) use this mode so it went without decent testing
      for a while.
      
      Cc: qemu-stable@nongnu.org
      Fixes: 105b47fd ("i386/xen: implement HVMOP_set_evtchn_upcall_vector")
      Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
      Reviewed-by: default avatarPaul Durrant <paul@xen.org>
      e7dbb62f
    • David Woodhouse's avatar
      i386/xen: Don't advertise XENFEAT_supervisor_mode_kernel · e969f992
      David Woodhouse authored
      
      This confuses lscpu into thinking it's running in PVH mode.
      
      Cc: qemu-stable@nongnu.org
      Fixes: bedcc139 ("i386/xen: implement HYPERVISOR_xen_version")
      Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
      Reviewed-by: default avatarPaul Durrant <paul@xen.org>
      e969f992
  7. Oct 25, 2023
  8. Oct 22, 2023
  9. Oct 20, 2023
Loading