1. 06 Dec, 2012 15 commits
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Improve handling of local vs. global TLB invalidations · 1b400ba0
      Paul Mackerras authored
      When we change or remove a HPT (hashed page table) entry, we can do
      either a global TLB invalidation (tlbie) that works across the whole
      machine, or a local invalidation (tlbiel) that only affects this core.
      Currently we do local invalidations if the VM has only one vcpu or if
      the guest requests it with the H_LOCAL flag, though the guest Linux
      kernel currently doesn't ever use H_LOCAL.  Then, to cope with the
      possibility that vcpus moving around to different physical cores might
      expose stale TLB entries, there is some code in kvmppc_hv_entry to
      flush the whole TLB of entries for this VM if either this vcpu is now
      running on a different physical core from where it last ran, or if this
      physical core last ran a different vcpu.
      
      There are a number of problems on POWER7 with this as it stands:
      
      - The TLB invalidation is done per thread, whereas it only needs to be
        done per core, since the TLB is shared between the threads.
      - With the possibility of the host paging out guest pages, the use of
        H_LOCAL by an SMP guest is dangerous since the guest could possibly
        retain and use a stale TLB entry pointing to a page that had been
        removed from the guest.
      - The TLB invalidations that we do when a vcpu moves from one physical
        core to another are unnecessary in the case of an SMP guest that isn't
        using H_LOCAL.
      - The optimization of using local invalidations rather than global should
        apply to guests with one virtual core, not just one vcpu.
      
      (None of this applies on PPC970, since there we always have to
      invalidate the whole TLB when entering and leaving the guest, and we
      can't support paging out guest memory.)
      
      To fix these problems and simplify the code, we now maintain a simple
      cpumask of which cpus need to flush the TLB on entry to the guest.
      (This is indexed by cpu, though we only ever use the bits for thread
      0 of each core.)  Whenever we do a local TLB invalidation, we set the
      bits for every cpu except the bit for thread 0 of the core that we're
      currently running on.  Whenever we enter a guest, we test and clear the
      bit for our core, and flush the TLB if it was set.
      
      On initial startup of the VM, and when resetting the HPT, we set all the
      bits in the need_tlb_flush cpumask, since any core could potentially have
      stale TLB entries from the previous VM to use the same LPID, or the
      previous contents of the HPT.
      
      Then, we maintain a count of the number of online virtual cores, and use
      that when deciding whether to use a local invalidation rather than the
      number of online vcpus.  The code to make that decision is extracted out
      into a new function, global_invalidates().  For multi-core guests on
      POWER7 (i.e. when we are using mmu notifiers), we now never do local
      invalidations regardless of the H_LOCAL flag.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      1b400ba0
    • Michael Ellerman's avatar
      6a7f972d
    • Paul Mackerras's avatar
      KVM: PPC: Book3S PR: MSR_DE doesn't exist on Book 3S · 3a2e7b0d
      Paul Mackerras authored
      The mask of MSR bits that get transferred from the guest MSR to the
      shadow MSR included MSR_DE.  In fact that bit only exists on Book 3E
      processors, and it is assigned the same bit used for MSR_BE on Book 3S
      processors.  Since we already had MSR_BE in the mask, this just removes
      MSR_DE.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      3a2e7b0d
    • Paul Mackerras's avatar
      KVM: PPC: Book3S PR: Fix VSX handling · 28c483b6
      Paul Mackerras authored
      This fixes various issues in how we were handling the VSX registers
      that exist on POWER7 machines.  First, we were running off the end
      of the current->thread.fpr[] array.  Ultimately this was because the
      vcpu->arch.vsr[] array is sized to be able to store both the FP
      registers and the extra VSX registers (i.e. 64 entries), but PR KVM
      only uses it for the extra VSX registers (i.e. 32 entries).
      
      Secondly, calling load_up_vsx() from C code is a really bad idea,
      because it jumps to fast_exception_return at the end, rather than
      returning with a blr instruction.  This was causing it to jump off
      to a random location with random register contents, since it was using
      the largely uninitialized stack frame created by kvmppc_load_up_vsx.
      
      In fact, it isn't necessary to call either __giveup_vsx or load_up_vsx,
      since giveup_fpu and load_up_fpu handle the extra VSX registers as well
      as the standard FP registers on machines with VSX.  Also, since VSX
      instructions can access the VMX registers and the FP registers as well
      as the extra VSX registers, we have to load up the FP and VMX registers
      before we can turn on the MSR_VSX bit for the guest.  Conversely, if
      we save away any of the VSX or FP registers, we have to turn off MSR_VSX
      for the guest.
      
      To handle all this, it is more convenient for a single call to
      kvmppc_giveup_ext() to handle all the state saving that needs to be done,
      so we make it take a set of MSR bits rather than just one, and the switch
      statement becomes a series of if statements.  Similarly kvmppc_handle_ext
      needs to be able to load up more than one set of registers.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      28c483b6
    • Paul Mackerras's avatar
      KVM: PPC: Book3S PR: Emulate PURR, SPURR and DSCR registers · b0a94d4e
      Paul Mackerras authored
      This adds basic emulation of the PURR and SPURR registers.  We assume
      we are emulating a single-threaded core, so these advance at the same
      rate as the timebase.  A Linux kernel running on a POWER7 expects to
      be able to access these registers and is not prepared to handle a
      program interrupt on accessing them.
      
      This also adds a very minimal emulation of the DSCR (data stream
      control register).  Writes are ignored and reads return zero.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      b0a94d4e
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Don't give the guest RW access to RO pages · 1cc8ed0b
      Paul Mackerras authored
      Currently, if the guest does an H_PROTECT hcall requesting that the
      permissions on a HPT entry be changed to allow writing, we make the
      requested change even if the page is marked read-only in the host
      Linux page tables.  This is a problem since it would for instance
      allow a guest to modify a page that KSM has decided can be shared
      between multiple guests.
      
      To fix this, if the new permissions for the page allow writing, we need
      to look up the memslot for the page, work out the host virtual address,
      and look up the Linux page tables to get the PTE for the page.  If that
      PTE is read-only, we reduce the HPTE permissions to read-only.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      1cc8ed0b
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Report correct HPT entry index when reading HPT · 05dd85f7
      Paul Mackerras authored
      This fixes a bug in the code which allows userspace to read out the
      contents of the guest's hashed page table (HPT).  On the second and
      subsequent passes through the HPT, when we are reporting only those
      entries that have changed, we were incorrectly initializing the index
      field of the header with the index of the first entry we skipped
      rather than the first changed entry.  This fixes it.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      05dd85f7
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Reset reverse-map chains when resetting the HPT · a64fd707
      Paul Mackerras authored
      With HV-style KVM, we maintain reverse-mapping lists that enable us to
      find all the HPT (hashed page table) entries that reference each guest
      physical page, with the heads of the lists in the memslot->arch.rmap
      arrays.  When we reset the HPT (i.e. when we reboot the VM), we clear
      out all the HPT entries but we were not clearing out the reverse
      mapping lists.  The result is that as we create new HPT entries, the
      lists get corrupted, which can easily lead to loops, resulting in the
      host kernel hanging when it tries to traverse those lists.
      
      This fixes the problem by zeroing out all the reverse mapping lists
      when we zero out the HPT.  This incidentally means that we are also
      zeroing our record of the referenced and changed bits (not the bits
      in the Linux PTEs, used by the Linux MM subsystem, but the bits used
      by the KVM_GET_DIRTY_LOG ioctl, and those used by kvm_age_hva() and
      kvm_test_age_hva()).
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      a64fd707
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Provide a method for userspace to read and write the HPT · a2932923
      Paul Mackerras authored
      A new ioctl, KVM_PPC_GET_HTAB_FD, returns a file descriptor.  Reads on
      this fd return the contents of the HPT (hashed page table), writes
      create and/or remove entries in the HPT.  There is a new capability,
      KVM_CAP_PPC_HTAB_FD, to indicate the presence of the ioctl.  The ioctl
      takes an argument structure with the index of the first HPT entry to
      read out and a set of flags.  The flags indicate whether the user is
      intending to read or write the HPT, and whether to return all entries
      or only the "bolted" entries (those with the bolted bit, 0x10, set in
      the first doubleword).
      
      This is intended for use in implementing qemu's savevm/loadvm and for
      live migration.  Therefore, on reads, the first pass returns information
      about all HPTEs (or all bolted HPTEs).  When the first pass reaches the
      end of the HPT, it returns from the read.  Subsequent reads only return
      information about HPTEs that have changed since they were last read.
      A read that finds no changed HPTEs in the HPT following where the last
      read finished will return 0 bytes.
      
      The format of the data provides a simple run-length compression of the
      invalid entries.  Each block of data starts with a header that indicates
      the index (position in the HPT, which is just an array), the number of
      valid entries starting at that index (may be zero), and the number of
      invalid entries following those valid entries.  The valid entries, 16
      bytes each, follow the header.  The invalid entries are not explicitly
      represented.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      [agraf: fix documentation]
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      a2932923
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Make a HPTE removal function available · 6b445ad4
      Paul Mackerras authored
      This makes a HPTE removal function, kvmppc_do_h_remove(), available
      outside book3s_hv_rm_mmu.c.  This will be used by the HPT writing
      code.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      6b445ad4
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Add a mechanism for recording modified HPTEs · 44e5f6be
      Paul Mackerras authored
      This uses a bit in our record of the guest view of the HPTE to record
      when the HPTE gets modified.  We use a reserved bit for this, and ensure
      that this bit is always cleared in HPTE values returned to the guest.
      
      The recording of modified HPTEs is only done if other code indicates
      its interest by setting kvm->arch.hpte_mod_interest to a non-zero value.
      The reason for this is that when later commits add facilities for
      userspace to read the HPT, the first pass of reading the HPT will be
      quicker if there are no (or very few) HPTEs marked as modified,
      rather than having most HPTEs marked as modified.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      44e5f6be
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Fix bug causing loss of page dirty state · 4879f241
      Paul Mackerras authored
      This fixes a bug where adding a new guest HPT entry via the H_ENTER
      hcall would lose the "changed" bit in the reverse map information
      for the guest physical page being mapped.  The result was that the
      KVM_GET_DIRTY_LOG could return a zero bit for the page even though
      the page had been modified by the guest.
      
      This fixes it by only modifying the index and present bits in the
      reverse map entry, thus preserving the reference and change bits.
      We were also unnecessarily setting the reference bit, and this
      fixes that too.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      4879f241
    • Paul Mackerras's avatar
      KVM: PPC: Book3S HV: Restructure HPT entry creation code · 7ed661bf
      Paul Mackerras authored
      This restructures the code that creates HPT (hashed page table)
      entries so that it can be called in situations where we don't have a
      struct vcpu pointer, only a struct kvm pointer.  It also fixes a bug
      where kvmppc_map_vrma() would corrupt the guest R4 value.
      
      Most of the work of kvmppc_virtmode_h_enter is now done by a new
      function, kvmppc_virtmode_do_h_enter, which itself calls another new
      function, kvmppc_do_h_enter, which contains most of the old
      kvmppc_h_enter.  The new kvmppc_do_h_enter takes explicit arguments
      for the place to return the HPTE index, the Linux page tables to use,
      and whether it is being called in real mode, thus removing the need
      for it to have the vcpu as an argument.
      
      Currently kvmppc_map_vrma creates the VRMA (virtual real mode area)
      HPTEs by calling kvmppc_virtmode_h_enter, which is designed primarily
      to handle H_ENTER hcalls from the guest that need to pin a page of
      memory.  Since H_ENTER returns the index of the created HPTE in R4,
      kvmppc_virtmode_h_enter updates the guest R4, corrupting the guest R4
      in the case when it gets called from kvmppc_map_vrma on the first
      VCPU_RUN ioctl.  With this, kvmppc_map_vrma instead calls
      kvmppc_virtmode_do_h_enter with the address of a dummy word as the
      place to store the HPTE index, thus avoiding corrupting the guest R4.
      Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      7ed661bf
    • Alexander Graf's avatar
      KVM: PPC: Support eventfd · 0e673fb6
      Alexander Graf authored
      In order to support the generic eventfd infrastructure on PPC, we need
      to call into the generic KVM in-kernel device mmio code.
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      0e673fb6
    • Alexander Graf's avatar
      KVM: Distangle eventfd code from irqchip · 914daba8
      Alexander Graf authored
      The current eventfd code assumes that when we have eventfd, we also have
      irqfd for in-kernel interrupt delivery. This is not necessarily true. On
      PPC we don't have an in-kernel irqchip yet, but we can still support easily
      support eventfd.
      Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
      914daba8
  2. 02 Dec, 2012 1 commit
  3. 30 Nov, 2012 3 commits
    • Will Auld's avatar
      KVM: x86: Emulate IA32_TSC_ADJUST MSR · ba904635
      Will Auld authored
      CPUID.7.0.EBX[1]=1 indicates IA32_TSC_ADJUST MSR 0x3b is supported
      
      Basic design is to emulate the MSR by allowing reads and writes to a guest
      vcpu specific location to store the value of the emulated MSR while adding
      the value to the vmcs tsc_offset. In this way the IA32_TSC_ADJUST value will
      be included in all reads to the TSC MSR whether through rdmsr or rdtsc. This
      is of course as long as the "use TSC counter offsetting" VM-execution control
      is enabled as well as the IA32_TSC_ADJUST control.
      
      However, because hardware will only return the TSC + IA32_TSC_ADJUST +
      vmsc tsc_offset for a guest process when it does and rdtsc (with the correct
      settings) the value of our virtualized IA32_TSC_ADJUST must be stored in one
      of these three locations. The argument against storing it in the actual MSR
      is performance. This is likely to be seldom used while the save/restore is
      required on every transition. IA32_TSC_ADJUST was created as a way to solve
      some issues with writing TSC itself so that is not an option either.
      
      The remaining option, defined above as our solution has the problem of
      returning incorrect vmcs tsc_offset values (unless we intercept and fix, not
      done here) as mentioned above. However, more problematic is that storing the
      data in vmcs tsc_offset will have a different semantic effect on the system
      than does using the actual MSR. This is illustrated in the following example:
      
      The hypervisor set the IA32_TSC_ADJUST, then the guest sets it and a guest
      process performs a rdtsc. In this case the guest process will get
      TSC + IA32_TSC_ADJUST_hyperviser + vmsc tsc_offset including
      IA32_TSC_ADJUST_guest. While the total system semantics changed the semantics
      as seen by the guest do not and hence this will not cause a problem.
      Signed-off-by: default avatarWill Auld <will.auld@intel.com>
      Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
      ba904635
    • Will Auld's avatar
      KVM: x86: Add code to track call origin for msr assignment · 8fe8ab46
      Will Auld authored
      In order to track who initiated the call (host or guest) to modify an msr
      value I have changed function call parameters along the call path. The
      specific change is to add a struct pointer parameter that points to (index,
      data, caller) information rather than having this information passed as
      individual parameters.
      
      The initial use for this capability is for updating the IA32_TSC_ADJUST msr
      while setting the tsc value. It is anticipated that this capability is
      useful for other tasks.
      Signed-off-by: default avatarWill Auld <will.auld@intel.com>
      Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
      8fe8ab46
    • Alex Williamson's avatar
      KVM: Fix user memslot overlap check · 5419369e
      Alex Williamson authored
      Prior to memory slot sorting this loop compared all of the user memory
      slots for overlap with new entries.  With memory slot sorting, we're
      just checking some number of entries in the array that may or may not
      be user slots.  Instead, walk all the slots with kvm_for_each_memslot,
      which has the added benefit of terminating early when we hit the first
      empty slot, and skip comparison to private slots.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
      5419369e
  4. 29 Nov, 2012 2 commits
  5. 28 Nov, 2012 19 commits