1. 27 12月, 2011 1 次提交
    • N
      KVM: nVMX: Add KVM_REQ_IMMEDIATE_EXIT · d6185f20
      Nadav Har'El 提交于
      This patch adds a new vcpu->requests bit, KVM_REQ_IMMEDIATE_EXIT.
      This bit requests that when next entering the guest, we should run it only
      for as little as possible, and exit again.
      
      We use this new option in nested VMX: When L1 launches L2, but L0 wishes L1
      to continue running so it can inject an event to it, we unfortunately cannot
      just pretend to have run L2 for a little while - We must really launch L2,
      otherwise certain one-off vmcs12 parameters (namely, L1 injection into L2)
      will be lost. So the existing code runs L2 in this case.
      But L2 could potentially run for a long time until it exits, and the
      injection into L1 will be delayed. The new KVM_REQ_IMMEDIATE_EXIT allows us
      to request that L2 will be entered, as necessary, but will exit as soon as
      possible after entry.
      
      Our implementation of this request uses smp_send_reschedule() to send a
      self-IPI, with interrupts disabled. The interrupts remain disabled until the
      guest is entered, and then, after the entry is complete (often including
      processing an injection and jumping to the relevant handler), the physical
      interrupt is noticed and causes an exit.
      
      On recent Intel processors, we could have achieved the same goal by using
      MTF instead of a self-IPI. Another technique worth considering in the future
      is to use VM_EXIT_ACK_INTR_ON_EXIT and a highest-priority vector IPI - to
      slightly improve performance by avoiding the useless interrupt handler
      which ends up being called when smp_send_reschedule() is used.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NAvi Kivity <avi@redhat.com>
      d6185f20
  2. 17 11月, 2011 3 次提交
  3. 26 9月, 2011 7 次提交
  4. 24 7月, 2011 2 次提交
  5. 12 7月, 2011 27 次提交
    • N
      KVM: nVMX: Fix bug preventing more than two levels of nesting · 509c75ea
      Nadav Har'El 提交于
      The nested VMX feature is supposed to fully emulate VMX for the guest. This
      (theoretically) not only allows it to run its own guests, but also also
      to further emulate VMX for its own guests, and allow arbitrarily deep nesting.
      
      This patch fixes a bug (discovered by Kevin Tian) in handling a VMLAUNCH
      by L2, which prevented deeper nesting.
      
      Deeper nesting now works (I only actually tested L3), but is currently
      *absurdly* slow, to the point of being unusable.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      509c75ea
    • J
      KVM: VMX: Silence warning on 32-bit hosts · 2e4ce7f5
      Jan Kiszka 提交于
      a is unused now on CONFIG_X86_32.
      Signed-off-by: NJan Kiszka <jan.kiszka@siemens.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      2e4ce7f5
    • N
      KVM: nVMX: Miscellenous small corrections · 2844d849
      Nadav Har'El 提交于
      Small corrections of KVM (spelling, etc.) not directly related to nested VMX.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      2844d849
    • N
      KVM: nVMX: Add VMX to list of supported cpuid features · 7b8050f5
      Nadav Har'El 提交于
      If the "nested" module option is enabled, add the "VMX" CPU feature to the
      list of CPU features KVM advertises with the KVM_GET_SUPPORTED_CPUID ioctl.
      
      Qemu uses this ioctl, and intersects KVM's list with its own list of desired
      cpu features (depending on the -cpu option given to qemu) to determine the
      final list of features presented to the guest.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      7b8050f5
    • N
      KVM: nVMX: Additional TSC-offset handling · 7991825b
      Nadav Har'El 提交于
      In the unlikely case that L1 does not capture MSR_IA32_TSC, L0 needs to
      emulate this MSR write by L2 by modifying vmcs02.tsc_offset. We also need to
      set vmcs12.tsc_offset, for this change to survive the next nested entry (see
      prepare_vmcs02()).
      Additionally, we also need to modify vmx_adjust_tsc_offset: The semantics
      of this function is that the TSC of all guests on this vcpu, L1 and possibly
      several L2s, need to be adjusted. To do this, we need to adjust vmcs01's
      tsc_offset (this offset will also apply to each L2s we enter). We can't set
      vmcs01 now, so we have to remember this adjustment and apply it when we
      later exit to L1.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      7991825b
    • N
      KVM: nVMX: Further fixes for lazy FPU loading · 36cf24e0
      Nadav Har'El 提交于
      KVM's "Lazy FPU loading" means that sometimes L0 needs to set CR0.TS, even
      if a guest didn't set it. Moreover, L0 must also trap CR0.TS changes and
      NM exceptions, even if we have a guest hypervisor (L1) who didn't want these
      traps. And of course, conversely: If L1 wanted to trap these events, we
      must let it, even if L0 is not interested in them.
      
      This patch fixes some existing KVM code (in update_exception_bitmap(),
      vmx_fpu_activate(), vmx_fpu_deactivate()) to do the correct merging of L0's
      and L1's needs. Note that handle_cr() was already fixed in the above patch,
      and that new code in introduced in previous patches already handles CR0
      correctly (see prepare_vmcs02(), prepare_vmcs12(), and nested_vmx_vmexit()).
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      36cf24e0
    • N
      KVM: nVMX: Handling of CR0 and CR4 modifying instructions · eeadf9e7
      Nadav Har'El 提交于
      When L2 tries to modify CR0 or CR4 (with mov or clts), and modifies a bit
      which L1 asked to shadow (via CR[04]_GUEST_HOST_MASK), we already do the right
      thing: we let L1 handle the trap (see nested_vmx_exit_handled_cr() in a
      previous patch).
      When L2 modifies bits that L1 doesn't care about, we let it think (via
      CR[04]_READ_SHADOW) that it did these modifications, while only changing
      (in GUEST_CR[04]) the bits that L0 doesn't shadow.
      
      This is needed for corect handling of CR0.TS for lazy FPU loading: L0 may
      want to leave TS on, while pretending to allow the guest to change it.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      eeadf9e7
    • N
      KVM: nVMX: Correct handling of idt vectoring info · 66c78ae4
      Nadav Har'El 提交于
      This patch adds correct handling of IDT_VECTORING_INFO_FIELD for the nested
      case.
      
      When a guest exits while delivering an interrupt or exception, we get this
      information in IDT_VECTORING_INFO_FIELD in the VMCS. When L2 exits to L1,
      there's nothing we need to do, because L1 will see this field in vmcs12, and
      handle it itself. However, when L2 exits and L0 handles the exit itself and
      plans to return to L2, L0 must inject this event to L2.
      
      In the normal non-nested case, the idt_vectoring_info case is discovered after
      the exit, and the decision to inject (though not the injection itself) is made
      at that point. However, in the nested case a decision of whether to return
      to L2 or L1 also happens during the injection phase (see the previous
      patches), so in the nested case we can only decide what to do about the
      idt_vectoring_info right after the injection, i.e., in the beginning of
      vmx_vcpu_run, which is the first time we know for sure if we're staying in
      L2.
      
      Therefore, when we exit L2 (is_guest_mode(vcpu)), we disable the regular
      vmx_complete_interrupts() code which queues the idt_vectoring_info for
      injection on next entry - because such injection would not be appropriate
      if we will decide to exit to L1. Rather, we just save the idt_vectoring_info
      and related fields in vmcs12 (which is a convenient place to save these
      fields). On the next entry in vmx_vcpu_run (*after* the injection phase,
      potentially exiting to L1 to inject an event requested by user space), if
      we find ourselves in L1 we don't need to do anything with those values
      we saved (as explained above). But if we find that we're in L2, or rather
      *still* at L2 (it's not nested_run_pending, meaning that this is the first
      round of L2 running after L1 having just launched it), we need to inject
      the event saved in those fields - by writing the appropriate VMCS fields.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      66c78ae4
    • N
      KVM: nVMX: Correct handling of exception injection · 0b6ac343
      Nadav Har'El 提交于
      Similar to the previous patch, but concerning injection of exceptions rather
      than external interrupts.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      0b6ac343
    • N
      KVM: nVMX: Correct handling of interrupt injection · b6f1250e
      Nadav Har'El 提交于
      The code in this patch correctly emulates external-interrupt injection
      while a nested guest L2 is running.
      
      Because of this code's relative un-obviousness, I include here a longer-than-
      usual justification for what it does - much longer than the code itself ;-)
      
      To understand how to correctly emulate interrupt injection while L2 is
      running, let's look first at what we need to emulate: How would things look
      like if the extra L0 hypervisor layer is removed, and instead of L0 injecting
      an interrupt, we had hardware delivering an interrupt?
      
      Now we have L1 running on bare metal with a guest L2, and the hardware
      generates an interrupt. Assuming that L1 set PIN_BASED_EXT_INTR_MASK to 1, and
      VM_EXIT_ACK_INTR_ON_EXIT to 0 (we'll revisit these assumptions below), what
      happens now is this: The processor exits from L2 to L1, with an external-
      interrupt exit reason but without an interrupt vector. L1 runs, with
      interrupts disabled, and it doesn't yet know what the interrupt was. Soon
      after, it enables interrupts and only at that moment, it gets the interrupt
      from the processor. when L1 is KVM, Linux handles this interrupt.
      
      Now we need exactly the same thing to happen when that L1->L2 system runs
      on top of L0, instead of real hardware. This is how we do this:
      
      When L0 wants to inject an interrupt, it needs to exit from L2 to L1, with
      external-interrupt exit reason (with an invalid interrupt vector), and run L1.
      Just like in the bare metal case, it likely can't deliver the interrupt to
      L1 now because L1 is running with interrupts disabled, in which case it turns
      on the interrupt window when running L1 after the exit. L1 will soon enable
      interrupts, and at that point L0 will gain control again and inject the
      interrupt to L1.
      
      Finally, there is an extra complication in the code: when nested_run_pending,
      we cannot return to L1 now, and must launch L2. We need to remember the
      interrupt we wanted to inject (and not clear it now), and do it on the
      next exit.
      
      The above explanation shows that the relative strangeness of the nested
      interrupt injection code in this patch, and the extra interrupt-window
      exit incurred, are in fact necessary for accurate emulation, and are not
      just an unoptimized implementation.
      
      Let's revisit now the two assumptions made above:
      
      If L1 turns off PIN_BASED_EXT_INTR_MASK (no hypervisor that I know
      does, by the way), things are simple: L0 may inject the interrupt directly
      to the L2 guest - using the normal code path that injects to any guest.
      We support this case in the code below.
      
      If L1 turns on VM_EXIT_ACK_INTR_ON_EXIT, things look very different from the
      description above: L1 expects to see an exit from L2 with the interrupt vector
      already filled in the exit information, and does not expect to be interrupted
      again with this interrupt. The current code does not (yet) support this case,
      so we do not allow the VM_EXIT_ACK_INTR_ON_EXIT exit-control to be turned on
      by L1.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      b6f1250e
    • N
      KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit · 644d711a
      Nadav Har'El 提交于
      This patch contains the logic of whether an L2 exit should be handled by L0
      and then L2 should be resumed, or whether L1 should be run to handle this
      exit (using the nested_vmx_vmexit() function of the previous patch).
      
      The basic idea is to let L1 handle the exit only if it actually asked to
      trap this sort of event. For example, when L2 exits on a change to CR0,
      we check L1's CR0_GUEST_HOST_MASK to see if L1 expressed interest in any
      bit which changed; If it did, we exit to L1. But if it didn't it means that
      it is we (L0) that wished to trap this event, so we handle it ourselves.
      
      The next two patches add additional logic of what to do when an interrupt or
      exception is injected: Does L0 need to do it, should we exit to L1 to do it,
      or should we resume L2 and keep the exception to be injected later.
      
      We keep a new flag, "nested_run_pending", which can override the decision of
      which should run next, L1 or L2. nested_run_pending=1 means that we *must* run
      L2 next, not L1. This is necessary in particular when L1 did a VMLAUNCH of L2
      and therefore expects L2 to be run (and perhaps be injected with an event it
      specified, etc.). Nested_run_pending is especially intended to avoid switching
      to L1 in the injection decision-point described above.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      644d711a
    • N
      KVM: nVMX: vmcs12 checks on nested entry · 7c177938
      Nadav Har'El 提交于
      This patch adds a bunch of tests of the validity of the vmcs12 fields,
      according to what the VMX spec and our implementation allows. If fields
      we cannot (or don't want to) honor are discovered, an entry failure is
      emulated.
      
      According to the spec, there are two types of entry failures: If the problem
      was in vmcs12's host state or control fields, the VMLAUNCH instruction simply
      fails. But a problem is found in the guest state, the behavior is more
      similar to that of an exit.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      7c177938
    • N
      KVM: nVMX: Exiting from L2 to L1 · 4704d0be
      Nadav Har'El 提交于
      This patch implements nested_vmx_vmexit(), called when the nested L2 guest
      exits and we want to run its L1 parent and let it handle this exit.
      
      Note that this will not necessarily be called on every L2 exit. L0 may decide
      to handle a particular exit on its own, without L1's involvement; In that
      case, L0 will handle the exit, and resume running L2, without running L1 and
      without calling nested_vmx_vmexit(). The logic for deciding whether to handle
      a particular exit in L1 or in L0, i.e., whether to call nested_vmx_vmexit(),
      will appear in a separate patch below.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      4704d0be
    • N
      KVM: nVMX: No need for handle_vmx_insn function any more · 99e65e80
      Nadav Har'El 提交于
      Before nested VMX support, the exit handler for a guest executing a VMX
      instruction (vmclear, vmlaunch, vmptrld, vmptrst, vmread, vmread, vmresume,
      vmwrite, vmon, vmoff), was handle_vmx_insn(). This handler simply threw a #UD
      exception. Now that all these exit reasons are properly handled (and emulate
      the respective VMX instruction), nothing calls this dummy handler and it can
      be removed.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      99e65e80
    • N
      KVM: nVMX: Implement VMLAUNCH and VMRESUME · cd232ad0
      Nadav Har'El 提交于
      Implement the VMLAUNCH and VMRESUME instructions, allowing a guest
      hypervisor to run its own guests.
      
      This patch does not include some of the necessary validity checks on
      vmcs12 fields before the entry. These will appear in a separate patch
      below.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      cd232ad0
    • N
      KVM: nVMX: Prepare vmcs02 from vmcs01 and vmcs12 · fe3ef05c
      Nadav Har'El 提交于
      This patch contains code to prepare the VMCS which can be used to actually
      run the L2 guest, vmcs02. prepare_vmcs02 appropriately merges the information
      in vmcs12 (the vmcs that L1 built for L2) and in vmcs01 (our desires for our
      own guests).
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      fe3ef05c
    • N
      KVM: nVMX: Move control field setup to functions · bf8179a0
      Nadav Har'El 提交于
      Move some of the control field setup to common functions. These functions will
      also be needed for running L2 guests - L0's desires (expressed in these
      functions) will be appropriately merged with L1's desires.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      bf8179a0
    • N
      KVM: nVMX: Move host-state field setup to a function · a3a8ff8e
      Nadav Har'El 提交于
      Move the setting of constant host-state fields (fields that do not change
      throughout the life of the guest) from vmx_vcpu_setup to a new common function
      vmx_set_constant_host_state(). This function will also be used to set the
      host state when running L2 guests.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      a3a8ff8e
    • N
      KVM: nVMX: Implement VMREAD and VMWRITE · 49f705c5
      Nadav Har'El 提交于
      Implement the VMREAD and VMWRITE instructions. With these instructions, L1
      can read and write to the VMCS it is holding. The values are read or written
      to the fields of the vmcs12 structure introduced in a previous patch.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      49f705c5
    • N
      KVM: nVMX: Implement VMPTRST · 6a4d7550
      Nadav Har'El 提交于
      This patch implements the VMPTRST instruction.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      6a4d7550
    • N
      KVM: nVMX: Implement VMPTRLD · 63846663
      Nadav Har'El 提交于
      This patch implements the VMPTRLD instruction.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      63846663
    • N
      KVM: nVMX: Implement VMCLEAR · 27d6c865
      Nadav Har'El 提交于
      This patch implements the VMCLEAR instruction.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      27d6c865
    • N
      KVM: nVMX: Success/failure of VMX instructions. · 0140caea
      Nadav Har'El 提交于
      VMX instructions specify success or failure by setting certain RFLAGS bits.
      This patch contains common functions to do this, and they will be used in
      the following patches which emulate the various VMX instructions.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      0140caea
    • N
      KVM: nVMX: Add VMCS fields to the vmcs12 · 22bd0358
      Nadav Har'El 提交于
      In this patch we add to vmcs12 (the VMCS that L1 keeps for L2) all the
      standard VMCS fields.
      
      Later patches will enable L1 to read and write these fields using VMREAD/
      VMWRITE, and they will be used during a VMLAUNCH/VMRESUME in preparing vmcs02,
      a hardware VMCS for running L2.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      22bd0358
    • N
      KVM: nVMX: Introduce vmcs02: VMCS used to run L2 · ff2f6fe9
      Nadav Har'El 提交于
      We saw in a previous patch that L1 controls its L2 guest with a vcms12.
      L0 needs to create a real VMCS for running L2. We call that "vmcs02".
      A later patch will contain the code, prepare_vmcs02(), for filling the vmcs02
      fields. This patch only contains code for allocating vmcs02.
      
      In this version, prepare_vmcs02() sets *all* of vmcs02's fields each time we
      enter from L1 to L2, so keeping just one vmcs02 for the vcpu is enough: It can
      be reused even when L1 runs multiple L2 guests. However, in future versions
      we'll probably want to add an optimization where vmcs02 fields that rarely
      change will not be set each time. For that, we may want to keep around several
      vmcs02s of L2 guests that have recently run, so that potentially we could run
      these L2s again more quickly because less vmwrites to vmcs02 will be needed.
      
      This patch adds to each vcpu a vmcs02 pool, vmx->nested.vmcs02_pool,
      which remembers the vmcs02s last used to run up to VMCS02_POOL_SIZE L2s.
      As explained above, in the current version we choose VMCS02_POOL_SIZE=1,
      I.e., one vmcs02 is allocated (and loaded onto the processor), and it is
      reused to enter any L2 guest. In the future, when prepare_vmcs02() is
      optimized not to set all fields every time, VMCS02_POOL_SIZE should be
      increased.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      ff2f6fe9
    • N
      KVM: nVMX: Decoding memory operands of VMX instructions · 064aea77
      Nadav Har'El 提交于
      This patch includes a utility function for decoding pointer operands of VMX
      instructions issued by L1 (a guest hypervisor)
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      064aea77
    • N
      KVM: nVMX: Implement reading and writing of VMX MSRs · b87a51ae
      Nadav Har'El 提交于
      When the guest can use VMX instructions (when the "nested" module option is
      on), it should also be able to read and write VMX MSRs, e.g., to query about
      VMX capabilities. This patch adds this support.
      Signed-off-by: NNadav Har'El <nyh@il.ibm.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      b87a51ae