1. 11 12月, 2014 1 次提交
  2. 10 12月, 2014 3 次提交
  3. 05 12月, 2014 9 次提交
  4. 04 12月, 2014 8 次提交
  5. 24 11月, 2014 4 次提交
  6. 22 11月, 2014 2 次提交
  7. 20 11月, 2014 9 次提交
    • N
      KVM: x86: Remove FIXMEs in emulate.c · 86619e7b
      Nicholas Krause 提交于
      Remove FIXME comments about needing fault addresses to be returned.  These
      are propaagated from walk_addr_generic to gva_to_gpa and from there to
      ops->read_std and ops->write_std.
      Signed-off-by: NNicholas Krause <xerofoify@gmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      86619e7b
    • P
      KVM: emulator: remove duplicated limit check · 997b0412
      Paolo Bonzini 提交于
      The check on the higher limit of the segment, and the check on the
      maximum accessible size, is the same for both expand-up and
      expand-down segments.  Only the computation of "lim" varies.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      997b0412
    • P
      KVM: emulator: remove code duplication in register_address{,_increment} · 01485a22
      Paolo Bonzini 提交于
      register_address has been a duplicate of address_mask ever since the
      ancestor of __linearize was born in 90de84f5 (KVM: x86 emulator:
      preserve an operand's segment identity, 2010-11-17).
      
      However, we can put it to a better use by including the call to reg_read
      in register_address.  Similarly, the call to reg_rmw can be moved to
      register_address_increment.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      01485a22
    • N
      KVM: x86: Move __linearize masking of la into switch · 31ff6488
      Nadav Amit 提交于
      In __linearize there is check of the condition whether to check if masking of
      the linear address is needed.  It occurs immediately after switch that
      evaluates the same condition.  Merge them.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      31ff6488
    • N
      KVM: x86: Non-canonical access using SS should cause #SS · abc7d8a4
      Nadav Amit 提交于
      When SS is used using a non-canonical address, an #SS exception is generated on
      real hardware.  KVM emulator causes a #GP instead. Fix it to behave as real x86
      CPU.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      abc7d8a4
    • N
      KVM: x86: Perform limit checks when assigning EIP · d50eaa18
      Nadav Amit 提交于
      If branch (e.g., jmp, ret) causes limit violations, since the target IP >
      limit, the #GP exception occurs before the branch.  In other words, the RIP
      pushed on the stack should be that of the branch and not that of the target.
      
      To do so, we can call __linearize, with new EIP, which also saves us the code
      which performs the canonical address checks. On the case of assigning an EIP >=
      2^32 (when switching cs.l), we also safe, as __linearize will check the new EIP
      does not exceed the limit and would trigger #GP(0) otherwise.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      d50eaa18
    • N
      KVM: x86: Emulator performs privilege checks on __linearize · a7315d2f
      Nadav Amit 提交于
      When segment is accessed, real hardware does not perform any privilege level
      checks.  In contrast, KVM emulator does. This causes some discrepencies from
      real hardware. For instance, reading from readable code segment may fail due to
      incorrect segment checks. In addition, it introduces unnecassary overhead.
      
      To reference Intel SDM 5.5 ("Privilege Levels"): "Privilege levels are checked
      when the segment selector of a segment descriptor is loaded into a segment
      register." The SDM never mentions privilege level checks during memory access,
      except for loading far pointers in section 5.10 ("Pointer Validation"). Those
      are actually segment selector loads and are emulated in the similarily (i.e.,
      regardless to __linearize checks).
      
      This behavior was also checked using sysexit. A data-segment whose DPL=0 was
      loaded, and after sysexit (CPL=3) it is still accessible.
      
      Therefore, all the privilege level checks in __linearize are removed.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      a7315d2f
    • N
      KVM: x86: Stack size is overridden by __linearize · 1c1c35ae
      Nadav Amit 提交于
      When performing segmented-read/write in the emulator for stack operations, it
      ignores the stack size, and uses the ad_bytes as indication for the pointer
      size. As a result, a wrong address may be accessed.
      
      To fix this behavior, we can remove the masking of address in __linearize and
      perform it beforehand.  It is already done for the operands (so currently it is
      inefficiently done twice). It is missing in two cases:
      1. When using rip_relative
      2. On fetch_bit_operand that changes the address.
      
      This patch masks the address on these two occassions, and removes the masking
      from __linearize.
      
      Note that it does not mask EIP during fetch. In protected/legacy mode code
      fetch when RIP >= 2^32 should result in #GP and not wrap-around. Since we make
      limit checks within __linearize, this is the expected behavior.
      
      Partial revert of commit 518547b3 (KVM: x86: Emulator does not
      calculate address correctly, 2014-09-30).
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      1c1c35ae
    • N
      KVM: x86: Revert NoBigReal patch in the emulator · 7d882ffa
      Nadav Amit 提交于
      Commit 10e38fc7cab6 ("KVM: x86: Emulator flag for instruction that only support
      16-bit addresses in real mode") introduced NoBigReal for instructions such as
      MONITOR. Apparetnly, the Intel SDM description that led to this patch is
      misleading.  Since no instruction is using NoBigReal, it is safe to remove it,
      we fully understand what the SDM means.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      7d882ffa
  8. 18 11月, 2014 2 次提交
  9. 17 11月, 2014 2 次提交
    • N
      KVM: x86: Fix lost interrupt on irr_pending race · f210f757
      Nadav Amit 提交于
      apic_find_highest_irr assumes irr_pending is set if any vector in APIC_IRR is
      set.  If this assumption is broken and apicv is disabled, the injection of
      interrupts may be deferred until another interrupt is delivered to the guest.
      Ultimately, if no other interrupt should be injected to that vCPU, the pending
      interrupt may be lost.
      
      commit 56cc2406 ("KVM: nVMX: fix "acknowledge interrupt on exit" when APICv
      is in use") changed the behavior of apic_clear_irr so irr_pending is cleared
      after setting APIC_IRR vector. After this commit, if apic_set_irr and
      apic_clear_irr run simultaneously, a race may occur, resulting in APIC_IRR
      vector set, and irr_pending cleared. In the following example, assume a single
      vector is set in IRR prior to calling apic_clear_irr:
      
      apic_set_irr				apic_clear_irr
      ------------				--------------
      apic->irr_pending = true;
      					apic_clear_vector(...);
      					vec = apic_search_irr(apic);
      					// => vec == -1
      apic_set_vector(...);
      					apic->irr_pending = (vec != -1);
      					// => apic->irr_pending == false
      
      Nonetheless, it appears the race might even occur prior to this commit:
      
      apic_set_irr				apic_clear_irr
      ------------				--------------
      apic->irr_pending = true;
      					apic->irr_pending = false;
      					apic_clear_vector(...);
      					if (apic_search_irr(apic) != -1)
      						apic->irr_pending = true;
      					// => apic->irr_pending == false
      apic_set_vector(...);
      
      Fixing this issue by:
      1. Restoring the previous behavior of apic_clear_irr: clear irr_pending, call
         apic_clear_vector, and then if APIC_IRR is non-zero, set irr_pending.
      2. On apic_set_irr: first call apic_set_vector, then set irr_pending.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f210f757
    • P
      KVM: compute correct map even if all APICs are software disabled · a3e339e1
      Paolo Bonzini 提交于
      Logical destination mode can be used to send NMI IPIs even when all
      APICs are software disabled, so if all APICs are software disabled we
      should still look at the DFRs.
      
      So the DFRs should all be the same, even if some or all APICs are
      software disabled.  However, the SDM does not say this, so tweak
      the logic as follows:
      
      - if one APIC is enabled and has LDR != 0, use that one to build the map.
      This picks the right DFR in case an OS is only setting it for the
      software-enabled APICs, or in case an OS is using logical addressing
      on some APICs while leaving the rest in reset state (using LDR was
      suggested by Radim).
      
      - if all APICs are disabled, pick a random one to build the map.
      We use the last one with LDR != 0 for simplicity.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      a3e339e1