1. 25 5月, 2018 3 次提交
  2. 04 5月, 2018 1 次提交
  3. 27 4月, 2018 3 次提交
  4. 17 4月, 2018 1 次提交
  5. 26 3月, 2018 2 次提交
    • M
      KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list · 7d8b44c5
      Marc Zyngier 提交于
      vgic_copy_lpi_list() parses the LPI list and picks LPIs targeting
      a given vcpu. We allocate the array containing the intids before taking
      the lpi_list_lock, which means we can have an array size that is not
      equal to the number of LPIs.
      
      This is particularly obvious when looking at the path coming from
      vgic_enable_lpis, which is not a command, and thus can run in parallel
      with commands:
      
      vcpu 0:                                        vcpu 1:
      vgic_enable_lpis
        its_sync_lpi_pending_table
          vgic_copy_lpi_list
            intids = kmalloc_array(irq_count)
                                                     MAPI(lpi targeting vcpu 0)
            list_for_each_entry(lpi_list_head)
              intids[i++] = irq->intid;
      
      At that stage, we will happily overrun the intids array. Boo. An easy
      fix is is to break once the array is full. The MAPI command will update
      the config anyway, and we won't miss a thing. We also make sure that
      lpi_list_count is read exactly once, so that further updates of that
      value will not affect the array bound check.
      
      Cc: stable@vger.kernel.org
      Fixes: ccb1d791 ("KVM: arm64: vgic-its: Fix pending table sync")
      Reviewed-by: NAndre Przywara <andre.przywara@arm.com>
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      7d8b44c5
    • M
      KVM: arm/arm64: vgic: Disallow Active+Pending for level interrupts · 67b5b673
      Marc Zyngier 提交于
      It was recently reported that VFIO mediated devices, and anything
      that VFIO exposes as level interrupts, do no strictly follow the
      expected logic of such interrupts as it only lowers the input
      line when the guest has EOId the interrupt at the GIC level, rather
      than when it Acked the interrupt at the device level.
      
      THe GIC's Active+Pending state is fundamentally incompatible with
      this behaviour, as it prevents KVM from observing the EOI, and in
      turn results in VFIO never dropping the line. This results in an
      interrupt storm in the guest, which it really never expected.
      
      As we cannot really change VFIO to follow the strict rules of level
      signalling, let's forbid the A+P state altogether, as it is in the
      end only an optimization. It ensures that we will transition via
      an invalid state, which we can use to notify VFIO of the EOI.
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Tested-by: NEric Auger <eric.auger@redhat.com>
      Tested-by: NShunyong Yang <shunyong.yang@hxt-semitech.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      67b5b673
  6. 19 3月, 2018 8 次提交
  7. 15 3月, 2018 4 次提交
    • M
      KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid · 16ca6a60
      Marc Zyngier 提交于
      The vgic code is trying to be clever when injecting GICv2 SGIs,
      and will happily populate LRs with the same interrupt number if
      they come from multiple vcpus (after all, they are distinct
      interrupt sources).
      
      Unfortunately, this is against the letter of the architecture,
      and the GICv2 architecture spec says "Each valid interrupt stored
      in the List registers must have a unique VirtualID for that
      virtual CPU interface.". GICv3 has similar (although slightly
      ambiguous) restrictions.
      
      This results in guests locking up when using GICv2-on-GICv3, for
      example. The obvious fix is to stop trying so hard, and inject
      a single vcpu per SGI per guest entry. After all, pending SGIs
      with multiple source vcpus are pretty rare, and are mostly seen
      in scenario where the physical CPUs are severely overcomitted.
      
      But as we now only inject a single instance of a multi-source SGI per
      vcpu entry, we may delay those interrupts for longer than strictly
      necessary, and run the risk of injecting lower priority interrupts
      in the meantime.
      
      In order to address this, we adopt a three stage strategy:
      - If we encounter a multi-source SGI in the AP list while computing
        its depth, we force the list to be sorted
      - When populating the LRs, we prevent the injection of any interrupt
        of lower priority than that of the first multi-source SGI we've
        injected.
      - Finally, the injection of a multi-source SGI triggers the request
        of a maintenance interrupt when there will be no pending interrupt
        in the LRs (HCR_NPIE).
      
      At the point where the last pending interrupt in the LRs switches
      from Pending to Active, the maintenance interrupt will be delivered,
      allowing us to add the remaining SGIs using the same process.
      
      Cc: stable@vger.kernel.org
      Fixes: 0919e84c ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
      Acked-by: NChristoffer Dall <cdall@kernel.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      16ca6a60
    • A
      KVM: arm/arm64: Reduce verbosity of KVM init log · 76600428
      Ard Biesheuvel 提交于
      On my GICv3 system, the following is printed to the kernel log at boot:
      
         kvm [1]: 8-bit VMID
         kvm [1]: IDMAP page: d20e35000
         kvm [1]: HYP VA range: 800000000000:ffffffffffff
         kvm [1]: vgic-v2@2c020000
         kvm [1]: GIC system register CPU interface enabled
         kvm [1]: vgic interrupt IRQ1
         kvm [1]: virtual timer IRQ4
         kvm [1]: Hyp mode initialized successfully
      
      The KVM IDMAP is a mapping of a statically allocated kernel structure,
      and so printing its physical address leaks the physical placement of
      the kernel when physical KASLR in effect. So change the kvm_info() to
      kvm_debug() to remove it from the log output.
      
      While at it, trim the output a bit more: IRQ numbers can be found in
      /proc/interrupts, and the HYP VA and vgic-v2 lines are not highly
      informational either.
      
      Cc: <stable@vger.kernel.org>
      Acked-by: NWill Deacon <will.deacon@arm.com>
      Acked-by: NChristoffer Dall <cdall@kernel.org>
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      76600428
    • C
      KVM: arm/arm64: Reset mapped IRQs on VM reset · 413aa807
      Christoffer Dall 提交于
      We currently don't allow resetting mapped IRQs from userspace, because
      their state is controlled by the hardware.  But we do need to reset the
      state when the VM is reset, so we provide a function for the 'owner' of
      the mapped interrupt to reset the interrupt state.
      
      Currently only the timer uses mapped interrupts, so we call this
      function from the timer reset logic.
      
      Cc: stable@vger.kernel.org
      Fixes: 4c60e360 ("KVM: arm/arm64: Provide a get_input_level for the arch timer")
      Signed-off-by: NChristoffer Dall <cdall@kernel.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      413aa807
    • A
      KVM: arm/arm64: vgic: Add missing irq_lock to vgic_mmio_read_pending · 62b06f8f
      Andre Przywara 提交于
      Our irq_is_pending() helper function accesses multiple members of the
      vgic_irq struct, so we need to hold the lock when calling it.
      Add that requirement as a comment to the definition and take the lock
      around the call in vgic_mmio_read_pending(), where we were missing it
      before.
      
      Fixes: 96b29800 ("KVM: arm/arm64: vgic-new: Add PENDING registers handlers")
      Signed-off-by: NAndre Przywara <andre.przywara@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      62b06f8f
  8. 12 1月, 2018 1 次提交
  9. 02 1月, 2018 5 次提交
    • C
      KVM: arm/arm64: Support VGIC dist pend/active changes for mapped IRQs · df635c5b
      Christoffer Dall 提交于
      For mapped IRQs (with the HW bit set in the LR) we have to follow some
      rules of the architecture.  One of these rules is that VM must not be
      allowed to deactivate a virtual interrupt with the HW bit set unless the
      physical interrupt is also active.
      
      This works fine when injecting mapped interrupts, because we leave it up
      to the injector to either set EOImode==1 or manually set the active
      state of the physical interrupt.
      
      However, the guest can set virtual interrupt to be pending or active by
      writing to the virtual distributor, which could lead to deactivating a
      virtual interrupt with the HW bit set without the physical interrupt
      being active.
      
      We could set the physical interrupt to active whenever we are about to
      enter the VM with a HW interrupt either pending or active, but that
      would be really slow, especially on GICv2.  So we take the long way
      around and do the hard work when needed, which is expected to be
      extremely rare.
      
      When the VM sets the pending state for a HW interrupt on the virtual
      distributor we set the active state on the physical distributor, because
      the virtual interrupt can become active and then the guest can
      deactivate it.
      
      When the VM clears the pending state we also clear it on the physical
      side, because the injector might otherwise raise the interrupt.  We also
      clear the physical active state when the virtual interrupt is not
      active, since otherwise a SPEND/CPEND sequence from the guest would
      prevent signaling of future interrupts.
      
      Changing the state of mapped interrupts from userspace is not supported,
      and it's expected that userspace unmaps devices from VFIO before
      attempting to set the interrupt state, because the interrupt state is
      driven by hardware.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      df635c5b
    • C
      KVM: arm/arm64: Support a vgic interrupt line level sample function · b6909a65
      Christoffer Dall 提交于
      The GIC sometimes need to sample the physical line of a mapped
      interrupt.  As we know this to be notoriously slow, provide a callback
      function for devices (such as the timer) which can do this much faster
      than talking to the distributor, for example by comparing a few
      in-memory values.  Fall back to the good old method of poking the
      physical GIC if no callback is provided.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      b6909a65
    • C
      KVM: arm/arm64: vgic: Support level-triggered mapped interrupts · e40cc57b
      Christoffer Dall 提交于
      Level-triggered mapped IRQs are special because we only observe rising
      edges as input to the VGIC, and we don't set the EOI flag and therefore
      are not told when the level goes down, so that we can re-queue a new
      interrupt when the level goes up.
      
      One way to solve this problem is to side-step the logic of the VGIC and
      special case the validation in the injection path, but it has the
      unfortunate drawback of having to peak into the physical GIC state
      whenever we want to know if the interrupt is pending on the virtual
      distributor.
      
      Instead, we can maintain the current semantics of a level triggered
      interrupt by sort of treating it as an edge-triggered interrupt,
      following from the fact that we only observe an asserting edge.  This
      requires us to be a bit careful when populating the LRs and when folding
      the state back in though:
      
       * We lower the line level when populating the LR, so that when
         subsequently observing an asserting edge, the VGIC will do the right
         thing.
      
       * If the guest never acked the interrupt while running (for example if
         it had masked interrupts at the CPU level while running), we have
         to preserve the pending state of the LR and move it back to the
         line_level field of the struct irq when folding LR state.
      
         If the guest never acked the interrupt while running, but changed the
         device state and lowered the line (again with interrupts masked) then
         we need to observe this change in the line_level.
      
         Both of the above situations are solved by sampling the physical line
         and set the line level when folding the LR back.
      
       * Finally, if the guest never acked the interrupt while running and
         sampling the line reveals that the device state has changed and the
         line has been lowered, we must clear the physical active state, since
         we will otherwise never be told when the interrupt becomes asserted
         again.
      
      This has the added benefit of making the timer optimization patches
      (https://lists.cs.columbia.edu/pipermail/kvmarm/2017-July/026343.html) a
      bit simpler, because the timer code doesn't have to clear the active
      state on the sync anymore.  It also potentially improves the performance
      of the timer implementation because the GIC knows the state or the LR
      and only needs to clear the
      active state when the pending bit in the LR is still set, where the
      timer has to always clear it when returning from running the guest with
      an injected timer interrupt.
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      e40cc57b
    • C
      KVM: arm/arm64: Factor out functionality to get vgic mmio requester_vcpu · 6c1b7521
      Christoffer Dall 提交于
      We are about to distinguish between userspace accesses and mmio traps
      for a number of the mmio handlers.  When the requester vcpu is NULL, it
      means we are handling a userspace access.
      
      Factor out the functionality to get the request vcpu into its own
      function, mostly so we have a common place to document the semantics of
      the return value.
      
      Also take the chance to move the functionality outside of holding a
      spinlock and instead explicitly disable and enable preemption.  This
      supports PREEMPT_RT kernels as well.
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Reviewed-by: NAndre Przywara <andre.przywara@arm.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      6c1b7521
    • V
      KVM: arm: Use PTR_ERR_OR_ZERO() · 4404b336
      Vasyl Gomonovych 提交于
      Fix ptr_ret.cocci warnings:
      virt/kvm/arm/vgic/vgic-its.c:971:1-3: WARNING: PTR_ERR_OR_ZERO can be used
      
      Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
      
      Generated by: scripts/coccinelle/api/ptr_ret.cocci
      Signed-off-by: NVasyl Gomonovych <gomonovych@gmail.com>
      Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
      4404b336
  10. 01 12月, 2017 1 次提交
  11. 29 11月, 2017 6 次提交
  12. 10 11月, 2017 5 次提交