1. 09 1月, 2016 1 次提交
  2. 14 12月, 2015 3 次提交
  3. 12 12月, 2015 1 次提交
  4. 30 11月, 2015 2 次提交
  5. 26 11月, 2015 3 次提交
  6. 25 11月, 2015 2 次提交
    • C
      KVM: arm/arm64: vgic: Trust the LR state for HW IRQs · 9f958c11
      Christoffer Dall 提交于
      We were probing the physial distributor state for the active state of a
      HW virtual IRQ, because we had seen evidence that the LR state was not
      cleared when the guest deactivated a virtual interrupted.
      
      However, this issue turned out to be a software bug in the GIC, which
      was solved by: 84aab5e68c2a5e1e18d81ae8308c3ce25d501b29
      (KVM: arm/arm64: arch_timer: Preserve physical dist. active
      state on LR.active, 2015-11-24)
      
      Therefore, get rid of the complexities and just look at the LR.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      9f958c11
    • C
      KVM: arm/arm64: arch_timer: Preserve physical dist. active state on LR.active · 0e3dfda9
      Christoffer Dall 提交于
      We were incorrectly removing the active state from the physical
      distributor on the timer interrupt when the timer output level was
      deasserted.  We shouldn't be doing this without considering the virtual
      interrupt's active state, because the architecture requires that when an
      LR has the HW bit set and the pending or active bits set, then the
      physical interrupt must also have the corresponding bits set.
      
      This addresses an issue where we have been observing an inconsistency
      between the LR state and the physical distributor state where the LR
      state was active and the physical distributor was not active, which
      shouldn't happen.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      0e3dfda9
  7. 04 11月, 2015 5 次提交
  8. 23 10月, 2015 8 次提交
    • C
      arm/arm64: KVM: Add tracepoints for vgic and timer · e21f0910
      Christoffer Dall 提交于
      The VGIC and timer code for KVM arm/arm64 doesn't have any tracepoints
      or tracepoint infrastructure defined.  Rewriting some of the timer code
      handling showed me how much we need this, so let's add these simple
      trace points once and for all and we can easily expand with additional
      trace points in these files as we go along.
      
      Cc: Wei Huang <wei@redhat.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      e21f0910
    • C
      arm/arm64: KVM: Support edge-triggered forwarded interrupts · 8fe2f19e
      Christoffer Dall 提交于
      We mark edge-triggered interrupts with the HW bit set as queued to
      prevent the VGIC code from injecting LRs with both the Active and
      Pending bits set at the same time while also setting the HW bit,
      because the hardware does not support this.
      
      However, this means that we must also clear the queued flag when we sync
      back a LR where the state on the physical distributor went from active
      to inactive because the guest deactivated the interrupt.  At this point
      we must also check if the interrupt is pending on the distributor, and
      tell the VGIC to queue it again if it is.
      
      Since these actions on the sync path are extremely close to those for
      level-triggered interrupts, rename process_level_irq to
      process_queued_irq, allowing it to cater for both cases.
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      8fe2f19e
    • C
      arm/arm64: KVM: Rework the arch timer to use level-triggered semantics · 4b4b4512
      Christoffer Dall 提交于
      The arch timer currently uses edge-triggered semantics in the sense that
      the line is never sampled by the vgic and lowering the line from the
      timer to the vgic doesn't have any effect on the pending state of
      virtual interrupts in the vgic.  This means that we do not support a
      guest with the otherwise valid behavior of (1) disable interrupts (2)
      enable the timer (3) disable the timer (4) enable interrupts.  Such a
      guest would validly not expect to see any interrupts on real hardware,
      but will see interrupts on KVM.
      
      This patch fixes this shortcoming through the following series of
      changes.
      
      First, we change the flow of the timer/vgic sync/flush operations.  Now
      the timer is always flushed/synced before the vgic, because the vgic
      samples the state of the timer output.  This has the implication that we
      move the timer operations in to non-preempible sections, but that is
      fine after the previous commit getting rid of hrtimer schedules on every
      entry/exit.
      
      Second, we change the internal behavior of the timer, letting the timer
      keep track of its previous output state, and only lower/raise the line
      to the vgic when the state changes.  Note that in theory this could have
      been accomplished more simply by signalling the vgic every time the
      state *potentially* changed, but we don't want to be hitting the vgic
      more often than necessary.
      
      Third, we get rid of the use of the map->active field in the vgic and
      instead simply set the interrupt as active on the physical distributor
      whenever the input to the GIC is asserted and conversely clear the
      physical active state when the input to the GIC is deasserted.
      
      Fourth, and finally, we now initialize the timer PPIs (and all the other
      unused PPIs for now), to be level-triggered, and modify the sync code to
      sample the line state on HW sync and re-inject a new interrupt if it is
      still pending at that time.
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      4b4b4512
    • C
      arm/arm64: KVM: Use appropriate define in VGIC reset code · 54723bb3
      Christoffer Dall 提交于
      We currently initialize the SGIs to be enabled in the VGIC code, but we
      use the VGIC_NR_PPIS define for this purpose, instead of the the more
      natural VGIC_NR_SGIS.  Change this slightly confusing use of the
      defines.
      
      Note: This should have no functional change, as both names are defined
      to the number 16.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      54723bb3
    • C
      arm/arm64: KVM: Implement GICD_ICFGR as RO for PPIs · 8bf9a701
      Christoffer Dall 提交于
      The GICD_ICFGR allows the bits for the SGIs and PPIs to be read only.
      We currently simulate this behavior by writing a hardcoded value to the
      register for the SGIs and PPIs on every write of these bits to the
      register (ignoring what the guest actually wrote), and by writing the
      same value as the reset value to the register.
      
      This is a bit counter-intuitive, as the register is RO for these bits,
      and we can just implement it that way, allowing us to control the value
      of the bits purely in the reset code.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      8bf9a701
    • C
      arm/arm64: KVM: vgic: Factor out level irq processing on guest exit · 9103617d
      Christoffer Dall 提交于
      Currently vgic_process_maintenance() processes dealing with a completed
      level-triggered interrupt directly, but we are soon going to reuse this
      logic for level-triggered mapped interrupts with the HW bit set, so
      move this logic into a separate static function.
      
      Probably the most scary part of this commit is convincing yourself that
      the current flow is safe compared to the old one.  In the following I
      try to list the changes and why they are harmless:
      
        Move vgic_irq_clear_queued after kvm_notify_acked_irq:
          Harmless because the only potential effect of clearing the queued
          flag wrt.  kvm_set_irq is that vgic_update_irq_pending does not set
          the pending bit on the emulated CPU interface or in the
          pending_on_cpu bitmask if the function is called with level=1.
          However, the point of kvm_notify_acked_irq is to call kvm_set_irq
          with level=0, and we set the queued flag again in
          __kvm_vgic_sync_hwstate later on if the level is stil high.
      
        Move vgic_set_lr before kvm_notify_acked_irq:
          Also, harmless because the LR are cpu-local operations and
          kvm_notify_acked only affects the dist
      
        Move vgic_dist_irq_clear_soft_pend after kvm_notify_acked_irq:
          Also harmless, because now we check the level state in the
          clear_soft_pend function and lower the pending bits if the level is
          low.
      Reviewed-by: NEric Auger <eric.auger@linaro.org>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      9103617d
    • C
      arm/arm64: KVM: arch_timer: Only schedule soft timer on vcpu_block · d35268da
      Christoffer Dall 提交于
      We currently schedule a soft timer every time we exit the guest if the
      timer did not expire while running the guest.  This is really not
      necessary, because the only work we do in the timer work function is to
      kick the vcpu.
      
      Kicking the vcpu does two things:
      (1) If the vpcu thread is on a waitqueue, make it runnable and remove it
      from the waitqueue.
      (2) If the vcpu is running on a different physical CPU from the one
      doing the kick, it sends a reschedule IPI.
      
      The second case cannot happen, because the soft timer is only ever
      scheduled when the vcpu is not running.  The first case is only relevant
      when the vcpu thread is on a waitqueue, which is only the case when the
      vcpu thread has called kvm_vcpu_block().
      
      Therefore, we only need to make sure a timer is scheduled for
      kvm_vcpu_block(), which we do by encapsulating all calls to
      kvm_vcpu_block() with kvm_timer_{un}schedule calls.
      
      Additionally, we only schedule a soft timer if the timer is enabled and
      unmasked, since it is useless otherwise.
      
      Note that theoretically userspace can use the SET_ONE_REG interface to
      change registers that should cause the timer to fire, even if the vcpu
      is blocked without a scheduled timer, but this case was not supported
      before this patch and we leave it for future work for now.
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      d35268da
    • C
      KVM: Add kvm_arch_vcpu_{un}blocking callbacks · 3217f7c2
      Christoffer Dall 提交于
      Some times it is useful for architecture implementations of KVM to know
      when the VCPU thread is about to block or when it comes back from
      blocking (arm/arm64 needs to know this to properly implement timers, for
      example).
      
      Therefore provide a generic architecture callback function in line with
      what we do elsewhere for KVM generic-arch interactions.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      3217f7c2
  9. 21 10月, 2015 4 次提交
    • C
      arm/arm64: KVM: Fix disabled distributor operation · 0d997491
      Christoffer Dall 提交于
      We currently do a single update of the vgic state when the distributor
      enable/disable control register is accessed and then bypass updating the
      state for as long as the distributor remains disabled.
      
      This is incorrect, because updating the state does not consider the
      distributor enable bit, and this you can end up in a situation where an
      interrupt is marked as pending on the CPU interface, but not pending on
      the distributor, which is an impossible state to be in, and triggers a
      warning.  Consider for example the following sequence of events:
      
      1. An interrupt is marked as pending on the distributor
         - the interrupt is also forwarded to the CPU interface
      2. The guest turns off the distributor (it's about to do a reboot)
         - we stop updating the CPU interface state from now on
      3. The guest disables the pending interrupt
         - we remove the pending state from the distributor, but don't touch
           the CPU interface, see point 2.
      
      Since the distributor disable bit really means that no interrupts should
      be forwarded to the CPU interface, we modify the code to keep updating
      the internal VGIC state, but always set the CPU interface pending bits
      to zero when the distributor is disabled.
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      0d997491
    • C
      arm/arm64: KVM: Clear map->active on pend/active clear · 544c572e
      Christoffer Dall 提交于
      When a guest reboots or offlines/onlines CPUs, it is not uncommon for it
      to clear the pending and active states of an interrupt through the
      emulated VGIC distributor.  However, since the architected timers are
      defined by the architecture to be level triggered and the guest
      rightfully expects them to be that, but we emulate them as
      edge-triggered, we have to mimic level-triggered behavior for an
      edge-triggered virtual implementation.
      
      We currently do not signal the VGIC when the map->active field is true,
      because it indicates that the guest has already been signalled of the
      interrupt as required.  Normally this field is set to false when the
      guest deactivates the virtual interrupt through the sync path.
      
      We also need to catch the case where the guest deactivates the interrupt
      through the emulated distributor, again allowing guests to boot even if
      the original virtual timer signal hit before the guest's GIC
      initialization sequence is run.
      Reviewed-by: NEric Auger <eric.auger@linaro.org>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      544c572e
    • C
      arm/arm64: KVM: Fix arch timer behavior for disabled interrupts · cff9211e
      Christoffer Dall 提交于
      We have an interesting issue when the guest disables the timer interrupt
      on the VGIC, which happens when turning VCPUs off using PSCI, for
      example.
      
      The problem is that because the guest disables the virtual interrupt at
      the VGIC level, we never inject interrupts to the guest and therefore
      never mark the interrupt as active on the physical distributor.  The
      host also never takes the timer interrupt (we only use the timer device
      to trigger a guest exit and everything else is done in software), so the
      interrupt does not become active through normal means.
      
      The result is that we keep entering the guest with a programmed timer
      that will always fire as soon as we context switch the hardware timer
      state and run the guest, preventing forward progress for the VCPU.
      
      Since the active state on the physical distributor is really part of the
      timer logic, it is the job of our virtual arch timer driver to manage
      this state.
      
      The timer->map->active boolean field indicates whether we have signalled
      this interrupt to the vgic and if that interrupt is still pending or
      active.  As long as that is the case, the hardware doesn't have to
      generate physical interrupts and therefore we mark the interrupt as
      active on the physical distributor.
      
      We also have to restore the pending state of an interrupt that was
      queued to an LR but was retired from the LR for some reason, while
      remaining pending in the LR.
      
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Reported-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      cff9211e
    • P
      KVM: arm/arm64: Do not inject spurious interrupts · 437f9963
      Pavel Fedin 提交于
      When lowering a level-triggered line from userspace, we forgot to lower
      the pending bit on the emulated CPU interface and we also did not
      re-compute the pending_on_cpu bitmap for the CPU affected by the change.
      
      Update vgic_update_irq_pending() to fix the two issues above and also
      raise a warning in vgic_quue_irq_to_lr if we encounter an interrupt
      pending on a CPU which is neither marked active nor pending.
      
        [ Commit text reworked completely - Christoffer ]
      Signed-off-by: NPavel Fedin <p.fedin@samsung.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      437f9963
  10. 16 10月, 2015 4 次提交
  11. 14 10月, 2015 1 次提交
    • K
      kvm: fix waitqueue_active without memory barrier in virt/kvm/async_pf.c · 6003a420
      Kosuke Tatsukawa 提交于
      async_pf_execute() seems to be missing a memory barrier which might
      cause the waker to not notice the waiter and miss sending a wake_up as
      in the following figure.
      
              async_pf_execute                    kvm_vcpu_block
      ------------------------------------------------------------------------
      spin_lock(&vcpu->async_pf.lock);
      if (waitqueue_active(&vcpu->wq))
      /* The CPU might reorder the test for
         the waitqueue up here, before
         prior writes complete */
                                          prepare_to_wait(&vcpu->wq, &wait,
                                            TASK_INTERRUPTIBLE);
                                          /*if (kvm_vcpu_check_block(vcpu) < 0) */
                                           /*if (kvm_arch_vcpu_runnable(vcpu)) { */
                                            ...
                                            return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE &&
                                              !vcpu->arch.apf.halted)
                                              || !list_empty_careful(&vcpu->async_pf.done)
                                           ...
                                           return 0;
      list_add_tail(&apf->link,
        &vcpu->async_pf.done);
      spin_unlock(&vcpu->async_pf.lock);
                                          waited = true;
                                          schedule();
      ------------------------------------------------------------------------
      
      The attached patch adds the missing memory barrier.
      
      I found this issue when I was looking through the linux source code
      for places calling waitqueue_active() before wake_up*(), but without
      preceding memory barriers, after sending a patch to fix a similar
      issue in drivers/tty/n_tty.c  (Details about the original issue can be
      found here: https://lkml.org/lkml/2015/9/28/849).
      Signed-off-by: NKosuke Tatsukawa <tatsu@ab.jp.nec.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      6003a420
  12. 10 10月, 2015 1 次提交
  13. 01 10月, 2015 5 次提交