1. 06 11月, 2017 15 次提交
    • C
      arm/arm64: KVM: Load the timer state when enabling the timer · 4a2c4da1
      Christoffer Dall 提交于
      After being lazy with saving/restoring the timer state, we defer that
      work to vcpu_load and vcpu_put, which ensure that the timer state is
      loaded on the hardware timers whenever the VCPU runs.
      
      Unfortunately, we are failing to do that the first time vcpu_load()
      runs, because the timer has not yet been enabled at that time.  As long
      as the initialized timer state matches what happens to be in the
      hardware (a disabled timer, because we never leave the timer screaming),
      this does not show up as a problem, but is nevertheless incorrect.
      
      The solution is simple; disable preemption while setting the timer to be
      enabled, and call the timer load function when first enabling the timer.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      4a2c4da1
    • C
      KVM: arm/arm64: Rework kvm_timer_should_fire · 1c88ab7e
      Christoffer Dall 提交于
      kvm_timer_should_fire() can be called in two different situations from
      the kvm_vcpu_block().
      
      The first case is before calling kvm_timer_schedule(), used for wait
      polling, and in this case the VCPU thread is running and the timer state
      is loaded onto the hardware so all we have to do is check if the virtual
      interrupt lines are asserted, becasue the timer interrupt handler
      functions will raise those lines as appropriate.
      
      The second case is inside the wait loop of kvm_vcpu_block(), where we
      have already called kvm_timer_schedule() and therefore the hardware will
      be disabled and the software view of the timer state is up to date
      (timer->loaded is false), and so we can simply check if the timer should
      fire by looking at the software state.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      1c88ab7e
    • C
      KVM: arm/arm64: Get rid of kvm_timer_flush_hwstate · 7e90c8e5
      Christoffer Dall 提交于
      Now when both the vtimer and the ptimer when using both the in-kernel
      vgic emulation and a userspace IRQ chip are driven by the timer signals
      and at the vcpu load/put boundaries, instead of recomputing the timer
      state at every entry/exit to/from the guest, we can get entirely rid of
      the flush hwstate function.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      7e90c8e5
    • C
      KVM: arm/arm64: Avoid phys timer emulation in vcpu entry/exit · bbdd52cf
      Christoffer Dall 提交于
      There is no need to schedule and cancel a hrtimer when entering and
      exiting the guest, because we know when the physical timer is going to
      fire when the guest programs it, and we can simply program the hrtimer
      at that point.
      
      Now when the register modifications from the guest go through the
      kvm_arm_timer_set/get_reg functions, which always call
      kvm_timer_update_state(), we can simply consider the timer state in this
      function and schedule and cancel the timers as needed.
      
      This avoids looking at the physical timer emulation state when entering
      and exiting the VCPU, allowing for faster servicing of the VM when
      needed.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      bbdd52cf
    • C
      KVM: arm/arm64: Move phys_timer_emulate function · cda93b7a
      Christoffer Dall 提交于
      We are about to call phys_timer_emulate() from kvm_timer_update_state()
      and modify phys_timer_emulate() at the same time.  Moving the function
      and modifying it in a single patch makes the diff hard to read, so do
      this separately first.
      
      No functional change.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      cda93b7a
    • C
      KVM: arm/arm64: Support EL1 phys timer register access in set/get reg · 5c5196da
      Christoffer Dall 提交于
      Add suport for the physical timer registers in kvm_arm_timer_set_reg and
      kvm_arm_timer_get_reg so that these functions can be reused to interact
      with the rest of the system.
      
      Note that this paves part of the way for the physical timer state
      save/restore, but we still need to add those registers to
      KVM_GET_REG_LIST before we support migrating the physical timer state.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      5c5196da
    • C
      KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit · b103cc3f
      Christoffer Dall 提交于
      We don't need to save and restore the hardware timer state and examine
      if it generates interrupts on on every entry/exit to the guest.  The
      timer hardware is perfectly capable of telling us when it has expired
      by signaling interrupts.
      
      When taking a vtimer interrupt in the host, we don't want to mess with
      the timer configuration, we just want to forward the physical interrupt
      to the guest as a virtual interrupt.  We can use the split priority drop
      and deactivate feature of the GIC to do this, which leaves an EOI'ed
      interrupt active on the physical distributor, making sure we don't keep
      taking timer interrupts which would prevent the guest from running.  We
      can then forward the physical interrupt to the VM using the HW bit in
      the LR of the GIC, like we do already, which lets the guest directly
      deactivate both the physical and virtual timer simultaneously, allowing
      the timer hardware to exit the VM and generate a new physical interrupt
      when the timer output is again asserted later on.
      
      We do need to capture this state when migrating VCPUs between physical
      CPUs, however, which we use the vcpu put/load functions for, which are
      called through preempt notifiers whenever the thread is scheduled away
      from the CPU or called directly if we return from the ioctl to
      userspace.
      
      One caveat is that we have to save and restore the timer state in both
      kvm_timer_vcpu_[put/load] and kvm_timer_[schedule/unschedule], because
      we can have the following flows:
      
        1. kvm_vcpu_block
        2. kvm_timer_schedule
        3. schedule
        4. kvm_timer_vcpu_put (preempt notifier)
        5. schedule (vcpu thread gets scheduled back)
        6. kvm_timer_vcpu_load (preempt notifier)
        7. kvm_timer_unschedule
      
      And a version where we don't actually call schedule:
      
        1. kvm_vcpu_block
        2. kvm_timer_schedule
        7. kvm_timer_unschedule
      
      Since kvm_timer_[schedule/unschedule] may not be followed by put/load,
      but put/load also may be called independently, we call the timer
      save/restore functions from both paths.  Since they rely on the loaded
      flag to never save/restore when unnecessary, this doesn't cause any
      harm, and we ensure that all invokations of either set of functions work
      as intended.
      
      An added benefit beyond not having to read and write the timer sysregs
      on every entry and exit is that we no longer have to actively write the
      active state to the physical distributor, because we configured the
      irq for the vtimer to only get a priority drop when handling the
      interrupt in the GIC driver (we called irq_set_vcpu_affinity()), and
      the interrupt stays active after firing on the host.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      b103cc3f
    • C
      KVM: arm/arm64: Set VCPU affinity for virt timer irq · 40f4cba9
      Christoffer Dall 提交于
      As we are about to take physical interrupts for the virtual timer on the
      host but want to leave those active while running the VM (and let the VM
      deactivate them), we need to set the vtimer PPI affinity accordingly.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      40f4cba9
    • C
      KVM: arm/arm64: Move timer save/restore out of the hyp code · 688c50aa
      Christoffer Dall 提交于
      As we are about to be lazy with saving and restoring the timer
      registers, we prepare by moving all possible timer configuration logic
      out of the hyp code.  All virtual timer registers can be programmed from
      EL1 and since the arch timer is always a level triggered interrupt we
      can safely do this with interrupts disabled in the host kernel on the
      way to the guest without taking vtimer interrupts in the host kernel
      (yet).
      
      The downside is that the cntvoff register can only be programmed from
      hyp mode, so we jump into hyp mode and back to program it.  This is also
      safe, because the host kernel doesn't use the virtual timer in the KVM
      code.  It may add a little performance performance penalty, but only
      until following commits where we move this operation to vcpu load/put.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      688c50aa
    • C
      KVM: arm/arm64: Use separate timer for phys timer emulation · f2a2129e
      Christoffer Dall 提交于
      We were using the same hrtimer for emulating the physical timer and for
      making sure a blocking VCPU thread would be eventually woken up.  That
      worked fine in the previous arch timer design, but as we are about to
      actually use the soft timer expire function for the physical timer
      emulation, change the logic to use a dedicated hrtimer.
      
      This has the added benefit of not having to cancel any work in the sync
      path, which in turn allows us to run the flush and sync with IRQs
      disabled.
      
      Note that the hrtimer used to program the host kernel's timer to
      generate an exit from the guest when the emulated physical timer fires
      never has to inject any work, and to share the soft_timer_cancel()
      function with the bg_timer, we change the function to only cancel any
      pending work if the pointer to the work struct is not null.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      f2a2129e
    • C
      KVM: arm/arm64: Move timer/vgic flush/sync under disabled irq · ee9bb9a1
      Christoffer Dall 提交于
      As we are about to play tricks with the timer to be more lazy in saving
      and restoring state, we need to move the timer sync and flush functions
      under a disabled irq section and since we have to flush the vgic state
      after the timer and PMU state, we do the whole flush/sync sequence with
      disabled irqs.
      
      The only downside is a slightly longer delay before being able to
      process hardware interrupts and run softirqs.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      ee9bb9a1
    • C
      KVM: arm/arm64: Rename soft timer to bg_timer · 14d61fa9
      Christoffer Dall 提交于
      As we are about to introduce a separate hrtimer for the physical timer,
      call this timer bg_timer, because we refer to this timer as the
      background timer in the code and comments elsewhere.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      14d61fa9
    • C
      KVM: arm/arm64: Make timer_arm and timer_disarm helpers more generic · 8409a06f
      Christoffer Dall 提交于
      We are about to add an additional soft timer to the arch timer state for
      a VCPU and would like to be able to reuse the functions to program and
      cancel a timer, so we make them slightly more generic and rename to make
      it more clear that these functions work on soft timers and not the
      hardware resource that this code is managing.
      
      The armed flag on the timer state is only used to assert a condition,
      and we don't rely on this assertion in any meaningful way, so we can
      simply get rid of this flack and slightly reduce complexity.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      8409a06f
    • C
      KVM: arm/arm64: Support calling vgic_update_irq_pending from irq context · 006df0f3
      Christoffer Dall 提交于
      We are about to optimize our timer handling logic which involves
      injecting irqs to the vgic directly from the irq handler.
      
      Unfortunately, the injection path can take any AP list lock and irq lock
      and we must therefore make sure to use spin_lock_irqsave where ever
      interrupts are enabled and we are taking any of those locks, to avoid
      deadlocking between process context and the ISR.
      
      This changes a lot of the VGIC code, but the good news are that the
      changes are mostly mechanical.
      Acked-by: NMarc Zyngier <marc,zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      006df0f3
    • C
      KVM: arm/arm64: Guard kvm_vgic_map_is_active against !vgic_initialized · f39d16cb
      Christoffer Dall 提交于
      If the vgic is not initialized, don't try to grab its spinlocks or
      traverse its data structures.
      
      This is important because we soon have to start considering the active
      state of a virtual interrupts when doing vcpu_load, which may happen
      early on before the vgic is initialized.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      f39d16cb
  2. 05 9月, 2017 5 次提交
  3. 08 8月, 2017 2 次提交
  4. 03 8月, 2017 1 次提交
  5. 25 7月, 2017 3 次提交
  6. 23 6月, 2017 2 次提交
    • T
      arm/arm64: KVM: add guest SEA support · 621f48e4
      Tyler Baicar 提交于
      Currently external aborts are unsupported by the guest abort
      handling. Add handling for SEAs so that the host kernel reports
      SEAs which occur in the guest kernel.
      
      When an SEA occurs in the guest kernel, the guest exits and is
      routed to kvm_handle_guest_abort(). Prior to this patch, a print
      message of an unsupported FSC would be printed and nothing else
      would happen. With this patch, the code gets routed to the APEI
      handling of SEAs in the host kernel to report the SEA information.
      Signed-off-by: NTyler Baicar <tbaicar@codeaurora.org>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Acked-by: NChristoffer Dall <cdall@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      621f48e4
    • J
      KVM: arm/arm64: Signal SIGBUS when stage2 discovers hwpoison memory · 196f878a
      James Morse 提交于
      Once we enable ARCH_SUPPORTS_MEMORY_FAILURE on arm64, notifications for
      broken memory can call memory_failure() in mm/memory-failure.c to offline
      pages of memory, possibly signalling user space processes and notifying all
      the in-kernel users.
      
      memory_failure() has two modes, early and late. Early is used by
      machine-managers like Qemu to receive a notification when a memory error is
      notified to the host. These can then be relayed to the guest before the
      affected page is accessed. To enable this, the process must set
      PR_MCE_KILL_EARLY in PR_MCE_KILL_SET using the prctl() syscall.
      
      Once the early notification has been handled, nothing stops the
      machine-manager or guest from accessing the affected page. If the
      machine-manager does this the page will fail to be mapped and SIGBUS will
      be sent. This patch adds the equivalent path for when the guest accesses
      the page, sending SIGBUS to the machine-manager.
      
      These two signals can be distinguished by the machine-manager using their
      si_code: BUS_MCEERR_AO for 'action optional' early notifications, and
      BUS_MCEERR_AR for 'action required' synchronous/late notifications.
      
      Do as x86 does, and deliver the SIGBUS when we discover pfn ==
      KVM_PFN_ERR_HWPOISON. Use the hugepage size as si_addr_lsb if this vma was
      allocated as a hugepage. Transparent hugepages will be split by
      memory_failure() before we see them here.
      
      Cc: Punit Agrawal <punit.agrawal@arm.com>
      Signed-off-by: NJames Morse <james.morse@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      196f878a
  7. 15 6月, 2017 12 次提交