1. 11 7月, 2014 3 次提交
  2. 28 4月, 2014 1 次提交
    • M
      arm: KVM: fix possible misalignment of PGDs and bounce page · 5d4e08c4
      Mark Salter 提交于
      The kvm/mmu code shared by arm and arm64 uses kalloc() to allocate
      a bounce page (if hypervisor init code crosses page boundary) and
      hypervisor PGDs. The problem is that kalloc() does not guarantee
      the proper alignment. In the case of the bounce page, the page sized
      buffer allocated may also cross a page boundary negating the purpose
      and leading to a hang during kvm initialization. Likewise the PGDs
      allocated may not meet the minimum alignment requirements of the
      underlying MMU. This patch uses __get_free_page() to guarantee the
      worst case alignment needs of the bounce page and PGDs on both arm
      and arm64.
      
      Cc: <stable@vger.kernel.org> # 3.10+
      Signed-off-by: NMark Salter <msalter@redhat.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      5d4e08c4
  3. 03 3月, 2014 4 次提交
  4. 09 1月, 2014 1 次提交
    • M
      arm/arm64: KVM: relax the requirements of VMA alignment for THP · 136d737f
      Marc Zyngier 提交于
      The THP code in KVM/ARM is a bit restrictive in not allowing a THP
      to be used if the VMA is not 2MB aligned. Actually, it is not so much
      the VMA that matters, but the associated memslot:
      
      A process can perfectly mmap a region with no particular alignment
      restriction, and then pass a 2MB aligned address to KVM. In this
      case, KVM will only use this 2MB aligned region, and will ignore
      the range between vma->vm_start and memslot->userspace_addr.
      
      It can also choose to place this memslot at whatever alignment it
      wants in the IPA space. In the end, what matters is the relative
      alignment of the user space and IPA mappings with respect to a
      2M page. They absolutely must be the same if you want to use THP.
      
      Cc: Christoffer Dall <christoffer.dall@linaro.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      136d737f
  5. 12 12月, 2013 1 次提交
  6. 17 11月, 2013 1 次提交
  7. 18 10月, 2013 2 次提交
  8. 14 8月, 2013 1 次提交
  9. 08 8月, 2013 2 次提交
    • M
      arm64: KVM: fix 2-level page tables unmapping · 979acd5e
      Marc Zyngier 提交于
      When using 64kB pages, we only have two levels of page tables,
      meaning that PGD, PUD and PMD are fused. In this case, trying
      to refcount PUDs and PMDs independently is a a complete disaster,
      as they are the same.
      
      We manage to get it right for the allocation (stage2_set_pte uses
      {pmd,pud}_none), but the unmapping path clears both pud and pmd
      refcounts, which fails spectacularly with 2-level page tables.
      
      The fix is to avoid calling clear_pud_entry when both the pmd and
      pud pages are empty. For this, and instead of introducing another
      pud_empty function, consolidate both pte_empty and pmd_empty into
      page_empty (the code is actually identical) and use that to also
      test the validity of the pud.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      979acd5e
    • C
      ARM: KVM: Fix unaligned unmap_range leak · d3840b26
      Christoffer Dall 提交于
      The unmap_range function did not properly cover the case when the start
      address was not aligned to PMD_SIZE or PUD_SIZE and an entire pte table
      or pmd table was cleared, causing us to leak memory when incrementing
      the addr.
      
      The fix is to always move onto the next page table entry boundary
      instead of adding the full size of the VA range covered by the
      corresponding table level entry.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      d3840b26
  10. 27 6月, 2013 1 次提交
  11. 03 6月, 2013 1 次提交
  12. 29 4月, 2013 6 次提交
    • M
      ARM: KVM: perform HYP initilization for hotplugged CPUs · d157f4a5
      Marc Zyngier 提交于
      Now that we have the necessary infrastructure to boot a hotplugged CPU
      at any point in time, wire a CPU notifier that will perform the HYP
      init for the incoming CPU.
      
      Note that this depends on the platform code and/or firmware to boot the
      incoming CPU with HYP mode enabled and return to the kernel by following
      the normal boot path (HYP stub installed).
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      d157f4a5
    • M
      ARM: KVM: switch to a dual-step HYP init code · 5a677ce0
      Marc Zyngier 提交于
      Our HYP init code suffers from two major design issues:
      - it cannot support CPU hotplug, as we tear down the idmap very early
      - it cannot perform a TLB invalidation when switching from init to
        runtime mappings, as pages are manipulated from PL1 exclusively
      
      The hotplug problem mandates that we keep two sets of page tables
      (boot and runtime). The TLB problem mandates that we're able to
      transition from one PGD to another while in HYP, invalidating the TLBs
      in the process.
      
      To be able to do this, we need to share a page between the two page
      tables. A page that will have the same VA in both configurations. All we
      need is a VA that has the following properties:
      - This VA can't be used to represent a kernel mapping.
      - This VA will not conflict with the physical address of the kernel text
      
      The vectors page seems to satisfy this requirement:
      - The kernel never maps anything else there
      - The kernel text being copied at the beginning of the physical memory,
        it is unlikely to use the last 64kB (I doubt we'll ever support KVM
        on a system with something like 4MB of RAM, but patches are very
        welcome).
      
      Let's call this VA the trampoline VA.
      
      Now, we map our init page at 3 locations:
      - idmap in the boot pgd
      - trampoline VA in the boot pgd
      - trampoline VA in the runtime pgd
      
      The init scenario is now the following:
      - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd,
        runtime stack, runtime vectors
      - Enable the MMU with the boot pgd
      - Jump to a target into the trampoline page (remember, this is the same
        physical page!)
      - Now switch to the runtime pgd (same VA, and still the same physical
        page!)
      - Invalidate TLBs
      - Set stack and vectors
      - Profit! (or eret, if you only care about the code).
      
      Note that we keep the boot mapping permanently (it is not strictly an
      idmap anymore) to allow for CPU hotplug in later patches.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      5a677ce0
    • M
      ARM: KVM: rework HYP page table freeing · 4f728276
      Marc Zyngier 提交于
      There is no point in freeing HYP page tables differently from Stage-2.
      They now have the same requirements, and should be dealt with the same way.
      
      Promote unmap_stage2_range to be The One True Way, and get rid of a number
      of nasty bugs in the process (good thing we never actually called free_hyp_pmds
      before...).
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      4f728276
    • M
      ARM: KVM: move to a KVM provided HYP idmap · 2fb41059
      Marc Zyngier 提交于
      After the HYP page table rework, it is pretty easy to let the KVM
      code provide its own idmap, rather than expecting the kernel to
      provide it. It takes actually less code to do so.
      Acked-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      2fb41059
    • M
      ARM: KVM: fix HYP mapping limitations around zero · 3562c76d
      Marc Zyngier 提交于
      The current code for creating HYP mapping doesn't like to wrap
      around zero, which prevents from mapping anything into the last
      page of the virtual address space.
      
      It doesn't take much effort to remove this limitation, making
      the code more consistent with the rest of the kernel in the process.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      3562c76d
    • M
      ARM: KVM: simplify HYP mapping population · 6060df84
      Marc Zyngier 提交于
      The way we populate HYP mappings is a bit convoluted, to say the least.
      Passing a pointer around to keep track of the current PFN is quite
      odd, and we end-up having two different PTE accessors for no good
      reason.
      
      Simplify the whole thing by unifying the two PTE accessors, passing
      a pgprot_t around, and moving the various validity checks to the
      upper layers.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@cs.columbia.edu>
      6060df84
  13. 07 3月, 2013 11 次提交
  14. 25 2月, 2013 1 次提交
  15. 24 1月, 2013 4 次提交
    • C
      KVM: ARM: Handle I/O aborts · 45e96ea6
      Christoffer Dall 提交于
      When the guest accesses I/O memory this will create data abort
      exceptions and they are handled by decoding the HSR information
      (physical address, read/write, length, register) and forwarding reads
      and writes to QEMU which performs the device emulation.
      
      Certain classes of load/store operations do not support the syndrome
      information provided in the HSR.  We don't support decoding these (patches
      are available elsewhere), so we report an error to user space in this case.
      
      This requires changing the general flow somewhat since new calls to run
      the VCPU must check if there's a pending MMIO load and perform the write
      after userspace has made the data available.
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      Reviewed-by: NMarcelo Tosatti <mtosatti@redhat.com>
      Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <c.dall@virtualopensystems.com>
      45e96ea6
    • C
      KVM: ARM: Handle guest faults in KVM · 94f8e641
      Christoffer Dall 提交于
      Handles the guest faults in KVM by mapping in corresponding user pages
      in the 2nd stage page tables.
      
      We invalidate the instruction cache by MVA whenever we map a page to the
      guest (no, we cannot only do it when we have an iabt because the guest
      may happily read/write a page before hitting the icache) if the hardware
      uses VIPT or PIPT.  In the latter case, we can invalidate only that
      physical page.  In the first case, all bets are off and we simply must
      invalidate the whole affair.  Not that VIVT icaches are tagged with
      vmids, and we are out of the woods on that one.  Alexander Graf was nice
      enough to remind us of this massive pain.
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      Reviewed-by: NMarcelo Tosatti <mtosatti@redhat.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <c.dall@virtualopensystems.com>
      94f8e641
    • C
      KVM: ARM: Memory virtualization setup · d5d8184d
      Christoffer Dall 提交于
      This commit introduces the framework for guest memory management
      through the use of 2nd stage translation. Each VM has a pointer
      to a level-1 table (the pgd field in struct kvm_arch) which is
      used for the 2nd stage translations. Entries are added when handling
      guest faults (later patch) and the table itself can be allocated and
      freed through the following functions implemented in
      arch/arm/kvm/arm_mmu.c:
       - kvm_alloc_stage2_pgd(struct kvm *kvm);
       - kvm_free_stage2_pgd(struct kvm *kvm);
      
      Each entry in TLBs and caches are tagged with a VMID identifier in
      addition to ASIDs. The VMIDs are assigned consecutively to VMs in the
      order that VMs are executed, and caches and tlbs are invalidated when
      the VMID space has been used to allow for more than 255 simultaenously
      running guests.
      
      The 2nd stage pgd is allocated in kvm_arch_init_vm(). The table is
      freed in kvm_arch_destroy_vm(). Both functions are called from the main
      KVM code.
      
      We pre-allocate page table memory to be able to synchronize using a
      spinlock and be called under rcu_read_lock from the MMU notifiers.  We
      steal the mmu_memory_cache implementation from x86 and adapt for our
      specific usage.
      
      We support MMU notifiers (thanks to Marc Zyngier) through
      kvm_unmap_hva and kvm_set_spte_hva.
      
      Finally, define kvm_phys_addr_ioremap() to map a device at a guest IPA,
      which is used by VGIC support to map the virtual CPU interface registers
      to the guest. This support is added by Marc Zyngier.
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      Reviewed-by: NMarcelo Tosatti <mtosatti@redhat.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <c.dall@virtualopensystems.com>
      d5d8184d
    • C
      KVM: ARM: Hypervisor initialization · 342cd0ab
      Christoffer Dall 提交于
      Sets up KVM code to handle all exceptions taken to Hyp mode.
      
      When the kernel is booted in Hyp mode, calling an hvc instruction with r0
      pointing to the new vectors, the HVBAR is changed to the the vector pointers.
      This allows subsystems (like KVM here) to execute code in Hyp-mode with the
      MMU disabled.
      
      We initialize other Hyp-mode registers and enables the MMU for Hyp-mode from
      the id-mapped hyp initialization code. Afterwards, the HVBAR is changed to
      point to KVM Hyp vectors used to catch guest faults and to switch to Hyp mode
      to perform a world-switch into a KVM guest.
      
      Also provides memory mapping code to map required code pages, data structures,
      and I/O regions  accessed in Hyp mode at the same virtual address as the host
      kernel virtual addresses, but which conforms to the architectural requirements
      for translations in Hyp mode. This interface is added in arch/arm/kvm/arm_mmu.c
      and comprises:
       - create_hyp_mappings(from, to);
       - create_hyp_io_mappings(from, to, phys_addr);
       - free_hyp_pmds();
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      Reviewed-by: NMarcelo Tosatti <mtosatti@redhat.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <c.dall@virtualopensystems.com>
      342cd0ab