linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: cdall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC 4/7] arm64: irqflags: Use ICC sysregs to implement IRQ masking
Date: Tue, 17 Oct 2017 11:12:42 +0200	[thread overview]
Message-ID: <20171017091242.GA7810@lvm> (raw)
In-Reply-To: <86952124-b669-2e97-76fe-2aa30d5735e1@arm.com>

On Tue, Oct 17, 2017 at 09:36:51AM +0100, Julien Thierry wrote:
> 
> 
> On 16/10/17 22:18, Christoffer Dall wrote:
> >On Wed, Oct 11, 2017 at 02:00:59PM +0100, Julien Thierry wrote:
> >>From: Daniel Thompson <daniel.thompson@linaro.org>
> >>
> >>Currently irqflags is implemented using the PSR's I bit. It is possible
> >>to implement irqflags by using the co-processor interface to the GIC.
> >>Using the co-processor interface makes it feasible to simulate NMIs
> >>using GIC interrupt prioritization.
> >>
> >>This patch changes the irqflags macros to modify, save and restore
> >>ICC_PMR_EL1. This has a substantial knock on effect for the rest of
> >>the kernel. There are four reasons for this:
> >>
> >>1. The state of the PMR becomes part of the interrupt context and must be
> >>    saved and restored during exceptions. It is saved on the stack as part
> >>    of the saved context when an interrupt/exception is taken.
> >>
> >>2. The hardware automatically masks the I bit (at boot, during traps, etc).
> >>    When the I bit is set by hardware we must add code to switch from I
> >>    bit masking and PMR masking:
> >>        - For IRQs, this is done after the interrupt has been acknowledged
> >>        	 avoiding the need to unmask.
> >>        - For other exceptions, this is done right after saving the context.
> >>
> >>3. Some instructions, such as wfi, require that the PMR not be used
> >>    for interrupt masking. Before calling these instructions we must
> >>    switch from PMR masking to I bit masking.
> >>    This is also the case when KVM runs a guest, if the CPU receives
> >>    an interrupt from the host, interrupts must not be masked in PMR
> >>    otherwise the GIC will not signal it to the CPU.
> >>
> >>4. We use the alternatives system to allow a single kernel to boot and
> >>    be switched to the alternative masking approach at runtime.
> >>
> >>Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
> >>[julien.thierry at arm.com: changes reflected in commit,
> >>			 message, fixes, renaming]
> >>Signed-off-by: Julien Thierry <julien.thierry@arm.com>
> >>Cc: Catalin Marinas <catalin.marinas@arm.com>
> >>Cc: Will Deacon <will.deacon@arm.com>
> >>Cc: Christoffer Dall <christoffer.dall@linaro.org>
> >>Cc: Marc Zyngier <marc.zyngier@arm.com>
> >>Cc: Thomas Gleixner <tglx@linutronix.de>
> >>Cc: Jason Cooper <jason@lakedaemon.net>
> >---
> >
> >I just gave a quick look to the KVM part here but didn't get into
> >whether this rather invasive change is warranted or not (it's definitely
> >entertaining though).
> >
> 
> I appreciate you looking into this, it wasn't very clear to me how to deal
> with that for KVM.
> 
> >[...]
> >
> >
> >>diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> >>index e923b58..070e8a5 100644
> >>--- a/arch/arm64/include/asm/kvm_host.h
> >>+++ b/arch/arm64/include/asm/kvm_host.h
> >>@@ -38,6 +38,10 @@
> >>  #include <kvm/arm_arch_timer.h>
> >>  #include <kvm/arm_pmu.h>
> >>
> >>+#ifdef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
> >>+#include <asm/arch_gicv3.h>
> >>+#endif
> >>+
> >>  #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
> >>
> >>  #define KVM_VCPU_MAX_FEATURES 4
> >>@@ -332,7 +336,30 @@ int kvm_unmap_hva_range(struct kvm *kvm,
> >>  void kvm_arm_resume_guest(struct kvm *kvm);
> >>
> >>  u64 __kvm_call_hyp(void *hypfn, ...);
> >>+
> >>+#ifdef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
> >>+/*
> >>+ * If we use PMR to disable interrupts, interrupts happening while the
> >
> >I would describe this as 'masking' interrupts, as opposed to 'disabling'
> >interrupts, in general, and probably we can be more precise by
> >categorizing interrupts as 'normal' vs. 'priority (NMIs)' or something
> >like that.
> >
> 
> Right, I'll do that.
> 
> >>+ * guest is executing will not be signaled to the host by the GIC  (and
> >
> >signaled to the CPU.  (Whether this then causes an exception to EL2
> >depends on the HCR_EL2.IMO flag and what KVM does with that exception).
> >
> 
> True, I'll fix that.
> 
> >>+ * any call to a waiting kvm_kick_many_cpus will likely cause a
> >>+ * deadlock).
> >
> >This kick thing is an unccessary specific example to bring out here, I
> >don't think it adds to the general understanding.
> >
> 
> Yes, makes sense.
> 
> >>+ * We need to switch back to using PSR.I.
> >>+ */
> >>+#define kvm_call_hyp(f, ...)						\
> >>+	({								\
> >>+		u64 res;						\
> >>+		unsigned long flags;					\
> >>+									\
> >>+		flags = arch_local_irq_save();				\
> >>+		gic_end_pmr_masking();					\
> >>+		res = __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__);	\
> >>+		gic_start_pmr_masking();				\
> >>+		arch_local_irq_restore(flags);				\
> >>+		res;							\
> >
> >This is in the critical path, so ideally this could instead be done
> >inside the function, because the trap will set PSTATE.I already, so it
> >should be possible to reduce this to a set of save/clear/restore
> >operations after __kvm_call_hyp.
> 
> Hmmm, you are talking about the function called by __kvm_call_hyp, right?
> 
> But this means we'll need to add the save/clear/restore to each function
> that can be called by __kvm_call_hyp, no?

No, you only need to do this in the case where you run the guedt,
__kvm_vcpu_run, because all the other callers don't need to be able to
take interrupts as they are under control of the host.

> 
> Also in the VHE case we don't have the trap setting the PSTATE.I (the code
> calling kvm_call_hyp disables interrupts before entering the guest, but now
> the function disabling interrupts is just masking them with PMR).
> 

Yes, for VHE you'd have to do something more.  One option would be to
disable interrupts using PSTATE.I in kvm_arch_vcpu_ioctl_run() for VHE,
another option is to simply mask interrupts in the PSTATE only for VHE
in __kvm_vcpu_run.

> >
> >>+	})
> >>+#else
> >>  #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
> >>+#endif
> >>
> >>  void force_vm_exit(const cpumask_t *mask);
> >>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> >>@@ -349,6 +376,9 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
> >>  				       unsigned long hyp_stack_ptr,
> >>  				       unsigned long vector_ptr)
> >>  {
> >>+#ifdef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
> >>+	unsigned long flags;
> >>+#endif
> >>  	/*
> >>  	 * Call initialization code, and switch to the full blown HYP code.
> >>  	 * If the cpucaps haven't been finalized yet, something has gone very
> >>@@ -356,7 +386,17 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
> >>  	 * cpus_have_const_cap() wrapper.
> >>  	 */
> >>  	BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
> >>+#ifdef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
> >>+	flags = arch_local_irq_save();
> >>+	gic_end_pmr_masking();
> >>+#endif
> >>+
> >>  	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
> >>+
> >>+#ifdef CONFIG_USE_ICC_SYSREGS_FOR_IRQFLAGS
> >>+	gic_start_pmr_masking();
> >>+	arch_local_irq_restore(flags);
> >>+#endif
> >
> >I don't think you need any of this, because I don't think you'd ever
> >need to handle interrupts while initializing hyp mode.
> >
> 
> I was more worried about getting an "NMI" during the EL2 initialisation
> rather than missing the masked interrupts. Do you know whether this might be
> an issue here or not?
> 

For non-VHE it won't be an issue, because making a hyp call will mask
interrupts using PSTATE.I, and for VHE we don't do any work here, so
it's not an issue there either.


Thanks,
-Christoffer

  reply	other threads:[~2017-10-17  9:12 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-11 13:00 [RFC 0/7] arm64: provide pseudo NMI with GICv3 Julien Thierry
2017-10-11 13:00 ` [RFC 1/7] arm64: irqflags: Reorder the fiq & async macros Julien Thierry
2017-10-11 13:00 ` [RFC 2/7] arm64: cpufeature: Allow early detect of specific features Julien Thierry
2017-10-11 13:00 ` [RFC 3/7] arm64: alternative: Apply alternatives early in boot process Julien Thierry
2017-11-13 17:34   ` Suzuki K Poulose
2017-11-13 17:39     ` Suzuki K Poulose
2017-10-11 13:00 ` [RFC 4/7] arm64: irqflags: Use ICC sysregs to implement IRQ masking Julien Thierry
2017-10-16 21:18   ` Christoffer Dall
2017-10-17  8:36     ` Julien Thierry
2017-10-17  9:12       ` Christoffer Dall [this message]
2017-11-03 11:57         ` Julien Thierry
2017-11-03 14:30           ` Marc Zyngier
2017-10-11 13:01 ` [RFC 5/7] irqchip/gic: Add functions to access irq priorities Julien Thierry
2017-10-11 13:01 ` [RFC 6/7] arm64: Detect current view of GIC priorities Julien Thierry
2017-11-03 14:02   ` Marc Zyngier
2017-10-11 13:01 ` [RFC 7/7] arm64: Add support for pseudo-NMIs Julien Thierry
2017-10-11 15:55 ` [RFC 0/7] arm64: provide pseudo NMI with GICv3 Daniel Thompson
2017-10-11 16:10   ` Julien Thierry
2017-11-03 11:50 ` Julien Thierry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171017091242.GA7810@lvm \
    --to=cdall@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).