Re: [PATCH v6 1/6] arm/arm64: KVM: Introduce armv7 fp/simd vcpu fields and helpers

2016-01-05 Thread Christoffer Dall
On Sat, Dec 26, 2015 at 01:54:55PM -0800, Mario Smarduch wrote:
> Add helper functions to enable access to fp/smid on guest entry and save host
> fpexc on vcpu put, check if fp/simd registers are dirty and add new vcpu
> fields.
> 
> Signed-off-by: Mario Smarduch 
> ---
>  arch/arm/include/asm/kvm_emulate.h   | 42 
> 
>  arch/arm/include/asm/kvm_host.h  |  6 ++
>  arch/arm64/include/asm/kvm_emulate.h |  8 +++
>  3 files changed, 56 insertions(+)
> 
> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> b/arch/arm/include/asm/kvm_emulate.h
> index 3095df0..d4d9da1 100644
> --- a/arch/arm/include/asm/kvm_emulate.h
> +++ b/arch/arm/include/asm/kvm_emulate.h
> @@ -24,6 +24,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include "../vfp/vfpinstr.h"

this looks dodgy...

can you move vfpinstr.h instead?

>  
>  unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
>  unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
> @@ -255,4 +257,44 @@ static inline unsigned long 
> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
>   }
>  }
>  
> +#ifdef CONFIG_VFPv3
> +/* Called from vcpu_load - save fpexc and enable guest access to fp/simd 
> unit */

the comment is misleading, you're not enabling guest access to the
fp/simd unit, you're just setting the enabled bit to ensure guest
accesses trap.

> +static inline void vcpu_trap_vfp_enable(struct kvm_vcpu *vcpu)
> +{
> + u32 fpexc;
> +
> + /* Save host fpexc, and enable guest access to fp unit */
> + fpexc = fmrx(FPEXC);
> + vcpu->arch.host_fpexc = fpexc;
> + fpexc |= FPEXC_EN;
> + fmxr(FPEXC, fpexc);
> +
> + /* Configure HCPTR to trap on tracing and fp/simd access */
> + vcpu->arch.hcptr = HCPTR_TTA | HCPTR_TCP(10)  | HCPTR_TCP(11);
> +}
> +
> +/* Called from vcpu_put - restore host fpexc */

I would probably get rid of the "Called from" stuff and just describe
what these functions do locally.  Comments like this are likely to be
out of date soon'ish.

> +static inline void vcpu_restore_host_fpexc(struct kvm_vcpu *vcpu)
> +{
> + fmxr(FPEXC, vcpu->arch.host_fpexc);
> +}
> +
> +/* If trap bits are reset then fp/simd registers are dirty */
> +static inline bool vcpu_vfp_isdirty(struct kvm_vcpu *vcpu)
> +{
> + return !(vcpu->arch.hcptr & (HCPTR_TCP(10) | HCPTR_TCP(11)));
> +}
> +#else
> +static inline void vcpu_trap_vfp_enable(struct kvm_vcpu *vcpu)
> +{
> + vcpu->arch.hcptr = HCPTR_TTA;
> +}
> +
> +static inline void vcpu_restore_host_fpexc(struct kvm_vcpu *vcpu) {}
> +static inline bool vcpu_vfp_isdirty(struct kvm_vcpu *vcpu)
> +{
> + return false;
> +}
> +#endif

this kind of feels like it belongs in its own C-file instead of a header
file, perhaps arch/arm/kvm/vfp.C.

Marc, what do you think?

> +
>  #endif /* __ARM_KVM_EMULATE_H__ */
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index f9f2779..d3ef58a 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -105,6 +105,12 @@ struct kvm_vcpu_arch {
>   /* HYP trapping configuration */
>   u32 hcr;
>  
> + /* HYP Co-processor fp/simd and trace trapping configuration */
> + u32 hcptr;
> +
> + /* Save host FPEXC register to later restore on vcpu put */
> + u32 host_fpexc;
> +
>   /* Interrupt related fields */
>   u32 irq_lines;  /* IRQ and FIQ levels */
>  
> diff --git a/arch/arm64/include/asm/kvm_emulate.h 
> b/arch/arm64/include/asm/kvm_emulate.h
> index 3066328..ffe8ccf 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -299,4 +299,12 @@ static inline unsigned long 
> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
>   return data;/* Leave LE untouched */
>  }
>  
> +static inline void vcpu_trap_vfp_enable(struct kvm_vcpu *vcpu) {}
> +static inline void vcpu_restore_host_fpexc(struct kvm_vcpu *vcpu) {}
> +
> +static inline bool vcpu_vfp_isdirty(struct kvm_vcpu *vcpu)
> +{
> + return false;
> +}
> +
>  #endif /* __ARM64_KVM_EMULATE_H__ */
> -- 
> 1.9.1
> 

Thanks,
-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 3/3] KVM/arm/arm64: enable enhanced armv8 fp/simd lazy switch

2015-12-22 Thread Christoffer Dall
On Mon, Dec 21, 2015 at 11:34:25AM -0800, Mario Smarduch wrote:
> 
> 
> On 12/18/2015 11:45 PM, Christoffer Dall wrote:
> > On Fri, Dec 18, 2015 at 05:17:00PM -0800, Mario Smarduch wrote:
> >> On 12/18/2015 5:54 AM, Christoffer Dall wrote:
> >>> On Sun, Dec 06, 2015 at 05:07:14PM -0800, Mario Smarduch wrote:
> >>>> This patch tracks armv7 and armv8 fp/simd hardware state with cptr_el2 
> >>>> register.
> >>>> On vcpu_load for 32 bit guests enable FP access, and enable fp/simd
> >>>> trapping for 32 and 64 bit guests. On first fp/simd access trap to 
> >>>> handler 
> >>>> to save host and restore guest context, and clear trapping bits to 
> >>>> enable vcpu 
> >>>> lazy mode. On vcpu_put if trap bits are clear save guest and restore 
> >>>> host 
> >>>> context and also save 32 bit guest fpexc register.
> >>>>
> >>>> Signed-off-by: Mario Smarduch <m.smard...@samsung.com>
> >>>> ---
> >>>>  arch/arm/include/asm/kvm_emulate.h   |   5 ++
> >>>>  arch/arm/include/asm/kvm_host.h  |   2 +
> >>>>  arch/arm/kvm/arm.c   |  20 +--
> >>>>  arch/arm64/include/asm/kvm_asm.h |   2 +
> >>>>  arch/arm64/include/asm/kvm_emulate.h |  15 +++--
> >>>>  arch/arm64/include/asm/kvm_host.h|  16 +-
> >>>>  arch/arm64/kernel/asm-offsets.c  |   1 +
> >>>>  arch/arm64/kvm/Makefile  |   3 +-
> >>>>  arch/arm64/kvm/fpsimd_switch.S   |  38 
> >>>>  arch/arm64/kvm/hyp.S | 108 
> >>>> +--
> >>>>  arch/arm64/kvm/hyp_head.S|  48 
> >>>>  11 files changed, 181 insertions(+), 77 deletions(-)
> >>>>  create mode 100644 arch/arm64/kvm/fpsimd_switch.S
> >>>>  create mode 100644 arch/arm64/kvm/hyp_head.S
> >>>>
> >>>> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> >>>> b/arch/arm/include/asm/kvm_emulate.h
> >>>> index 3de11a2..13feed5 100644
> >>>> --- a/arch/arm/include/asm/kvm_emulate.h
> >>>> +++ b/arch/arm/include/asm/kvm_emulate.h
> >>>> @@ -243,6 +243,11 @@ static inline unsigned long 
> >>>> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
> >>>>  }
> >>>>  }
> >>>>  
> >>>> +static inline bool kvm_guest_vcpu_is_32bit(struct kvm_vcpu *vcpu)
> >>>> +{
> >>>> +return true;
> >>>> +}
> >>>> +
> >>>>  #ifdef CONFIG_VFPv3
> >>>>  /* Called from vcpu_load - save fpexc and enable guest access to 
> >>>> fp/simd unit */
> >>>>  static inline void kvm_enable_vcpu_fpexc(struct kvm_vcpu *vcpu)
> >>>> diff --git a/arch/arm/include/asm/kvm_host.h 
> >>>> b/arch/arm/include/asm/kvm_host.h
> >>>> index ecc883a..720ae51 100644
> >>>> --- a/arch/arm/include/asm/kvm_host.h
> >>>> +++ b/arch/arm/include/asm/kvm_host.h
> >>>> @@ -227,6 +227,8 @@ int kvm_perf_teardown(void);
> >>>>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> >>>>  
> >>>>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long 
> >>>> mpidr);
> >>>> +
> >>>> +static inline void kvm_save_guest_vcpu_fpexc(struct kvm_vcpu *vcpu) {}
> >>>>  void kvm_restore_host_vfp_state(struct kvm_vcpu *);
> >>>>  
> >>>>  static inline void kvm_arch_hardware_disable(void) {}
> >>>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >>>> index 1de07ab..dd59f8a 100644
> >>>> --- a/arch/arm/kvm/arm.c
> >>>> +++ b/arch/arm/kvm/arm.c
> >>>> @@ -292,8 +292,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
> >>>> cpu)
> >>>>  
> >>>>  kvm_arm_set_running_vcpu(vcpu);
> >>>>  
> >>>> -/*  Save and enable FPEXC before we load guest context */
> >>>> -kvm_enable_vcpu_fpexc(vcpu);
> >>>> +/*
> >>>> + * For 32bit guest executing on arm64, enable fp/simd access in
> >>>> + * EL2. On arm32 save host fpexc and then enable fp/simd access.
> >>>> + */
> >>>> +i

Re: [PATCH 1/2] arm: KVM: Do not update PC if the trap handler has updated it

2015-12-22 Thread Christoffer Dall
On Tue, Dec 22, 2015 at 11:08:10AM +, Peter Maydell wrote:
> On 22 December 2015 at 09:55, Marc Zyngier  wrote:
> > Assuming we trap a coprocessor access, and decide that the access
> > is illegal, we will inject an exception in the guest. In this
> > case, we shouldn't increment the PC, or the vcpu will miss the
> > first instruction of the handler, leading to a mildly confused
> > guest.
> >
> > Solve this by snapshoting PC before the access is performed,
> > and checking if it has moved or not before incrementing it.
> >
> > Reported-by: Shannon Zhao 
> > Signed-off-by: Marc Zyngier 
> > ---
> >  arch/arm/kvm/coproc.c | 14 --
> >  1 file changed, 12 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
> > index f3d88dc..f4ad2f2 100644
> > --- a/arch/arm/kvm/coproc.c
> > +++ b/arch/arm/kvm/coproc.c
> > @@ -447,12 +447,22 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
> > r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
> >
> > if (likely(r)) {
> > +   unsigned long pc = *vcpu_pc(vcpu);
> > +
> > /* If we don't have an accessor, we should never get here! 
> > */
> > BUG_ON(!r->access);
> >
> > if (likely(r->access(vcpu, params, r))) {
> > -   /* Skip instruction, since it was emulated */
> > -   kvm_skip_instr(vcpu, 
> > kvm_vcpu_trap_il_is32bit(vcpu));
> > +   /*
> > +* Skip the instruction if it was emulated
> > +* without PC having changed. This allows us
> > +* to detect a fault being injected
> > +* (incrementing the PC here would cause the
> > +* vcpu to skip the first instruction of its
> > +* fault handler).
> > +*/
> > +   if (pc == *vcpu_pc(vcpu))
> > +   kvm_skip_instr(vcpu, 
> > kvm_vcpu_trap_il_is32bit(vcpu));
> 
> Won't this result in our incorrectly skipping the first insn
> in the fault handler if the original offending instruction
> was itself the first insn in the fault handler?
> 
Wouldn't that then loop with the exception forever?

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 19/19] KVM: ARM64: Add a new kvm ARM PMU device

2015-12-18 Thread Christoffer Dall
On Thu, Dec 17, 2015 at 03:22:50PM +0800, Shannon Zhao wrote:
> 
> 
> On 2015/12/17 4:33, Christoffer Dall wrote:
> > On Wed, Dec 16, 2015 at 04:06:49PM +0800, Shannon Zhao wrote:
> >> Hi,
> >>
> >> On 2015/12/16 15:31, Shannon Zhao wrote:
> >>>>>>>>> But in this case, you're returning an error if it is *not* 
> >>>>>>>>> initialized.
> >>>>>>>>> I understand that in that case you cannot return an interrupt 
> >>>>>>>>> number (-1
> >>>>>>>>> would be weird), but returning -EBUSY feels even more weird.
> >>>>>>>>>
> >>>>>>>>> I'd settle for -ENOXIO, or something similar. Anyone having a 
> >>>>>>>>> better idea?
> >>>>>>>>>
> >>>>> ENXIO or ENODEV would be my choice too, and add that to the
> >>>>> Documentation clearly describing when this error code is used.
> >>>>>
> >>>>> By the way, why do you loop over all VCPUS to set the same value when
> >>>>> you can't do anything per VCPU anyway?  It seems to me it's either a
> >>>>> per-VM property (that you can store on the VM data structure) or it's a
> >>>>> true per-VCPU property?
> >>> This is a per-VCPU property. PMU interrupt could be PPI or SPI. For PPI
> >>> the interrupt numbers are same for each vcpu, while for SPI they are
> >>> different, so it needs to set them separately. I planned to support both
> >>> PPI and SPI. I think I should add support for SPI at this moment and let
> >>> users (QEMU) to set these interrupts for each one.
> >>
> >> How about below vPMU Documentation?
> >>
> >> ARM Virtual Performance Monitor Unit (vPMU)
> >> ===
> >>
> >> Device types supported:
> >>   KVM_DEV_TYPE_ARM_PMU_V3 ARM Performance Monitor Unit v3
> >>
> >> Instantiate one PMU instance for per VCPU through this API.
> >>
> >> Groups:
> >>   KVM_DEV_ARM_PMU_GRP_IRQ
> >>   Attributes:
> >> The attr field of kvm_device_attr encodes two values:
> >> bits: | 63  32 | 31  0 |
> >> values:   | vcpu_index |  irq_num  |
> BTW, I change this Attribute to below format and pass vcpu_index through
> this Attribute while pass irq_num through kvm_device_attr.addr.
> Is it fine?
> 
> bits: | 63  32 | 31   0 |
> values:   |  reserved  | vcpu_index |
> 
> >> The irq_num describes the PMU overflow interrupt number for the
> >> specified
> >> vcpu_index vcpu. This interrupt could be a PPI or SPI, but for one
> >> VM the
> >> interrupt type must be same for each vcpu.
> > 
> > some formatting snafus that I expect come from pasting the text in an
> > e-mail client.
> > 
> >>
> >>   Errors:
> >> -ENXIO: Getting or setting this attribute is not yet supported
> > 
> > 'not yet supported' as in something we'll implement later, or as in you
> > need to call this other function before you can access this state?
> > 
> Since only when the group is not KVM_DEV_ARM_PMU_GRP_IRQ, it will return
> -ENXIO. So what about this?
> 
> "-ENXIO: Unsupported attribute group"
> 
better,

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v6] arm/arm64: KVM: Detect vGIC presence at runtime

2015-12-18 Thread Christoffer Dall
PE_ARM_VGIC_V2);
>   }
>   case KVM_ARM_SET_DEVICE_ADDR: {
> @@ -,8 +1120,17 @@ static int init_hyp_mode(void)
>* Init HYP view of VGIC
>*/
>   err = kvm_vgic_hyp_init();
> - if (err)
> + switch (err) {
> + case 0:
> + vgic_present = true;
> + break;
> + case -ENODEV:
> + case -ENXIO:
> + vgic_present = false;
> + break;
> + default:
>   goto out_free_context;
> + }
>  
>   /*
>* Init HYP architected timer support
> -- 
> 2.4.4
> 

Assuming the commit message gets a bit of love:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 1/3] KVM/arm: add hooks for armv7 fp/simd lazy switch support

2015-12-18 Thread Christoffer Dall
On Sun, Dec 06, 2015 at 05:07:12PM -0800, Mario Smarduch wrote:
> This patch adds vcpu fields to configure hcptr trap register which is also 
> used 
> to determine if fp/simd registers are dirty. Adds a field to save host FPEXC, 
> and offsets associated offsets.

offsets offsets?

> 
> Signed-off-by: Mario Smarduch 
> ---
>  arch/arm/include/asm/kvm_host.h | 6 ++
>  arch/arm/kernel/asm-offsets.c   | 2 ++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 3df1e97..09bb1f2 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -104,6 +104,12 @@ struct kvm_vcpu_arch {
>   /* HYP trapping configuration */
>   u32 hcr;
>  
> + /* HYP Co-processor fp/simd and trace trapping configuration */
> + u32 hcptr;
> +
> + /* Save host FPEXC register to later restore on vcpu put */
> + u32 host_fpexc;
> +
>   /* Interrupt related fields */
>   u32 irq_lines;  /* IRQ and FIQ levels */
>  
> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
> index 871b826..28ebd4c 100644
> --- a/arch/arm/kernel/asm-offsets.c
> +++ b/arch/arm/kernel/asm-offsets.c
> @@ -185,6 +185,8 @@ int main(void)
>DEFINE(VCPU_PC,offsetof(struct kvm_vcpu, 
> arch.regs.usr_regs.ARM_pc));
>DEFINE(VCPU_CPSR,  offsetof(struct kvm_vcpu, 
> arch.regs.usr_regs.ARM_cpsr));
>DEFINE(VCPU_HCR,   offsetof(struct kvm_vcpu, arch.hcr));
> +  DEFINE(VCPU_HCPTR, offsetof(struct kvm_vcpu, arch.hcptr));
> +  DEFINE(VCPU_VFP_HOST_FPEXC,offsetof(struct kvm_vcpu, 
> arch.host_fpexc));

this makes me think this needs a good rebase on world-switch in C, which
is now in kvmarm/next...

>DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
>DEFINE(VCPU_HSR,   offsetof(struct kvm_vcpu, arch.fault.hsr));
>DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar));

this patch is hard to review on its own as I don't see how this is used,
but ok...

> -- 
> 1.9.1
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 3/3] KVM/arm/arm64: enable enhanced armv8 fp/simd lazy switch

2015-12-18 Thread Christoffer Dall
On Sun, Dec 06, 2015 at 05:07:14PM -0800, Mario Smarduch wrote:
> This patch tracks armv7 and armv8 fp/simd hardware state with cptr_el2 
> register.
> On vcpu_load for 32 bit guests enable FP access, and enable fp/simd
> trapping for 32 and 64 bit guests. On first fp/simd access trap to handler 
> to save host and restore guest context, and clear trapping bits to enable 
> vcpu 
> lazy mode. On vcpu_put if trap bits are clear save guest and restore host 
> context and also save 32 bit guest fpexc register.
> 
> Signed-off-by: Mario Smarduch 
> ---
>  arch/arm/include/asm/kvm_emulate.h   |   5 ++
>  arch/arm/include/asm/kvm_host.h  |   2 +
>  arch/arm/kvm/arm.c   |  20 +--
>  arch/arm64/include/asm/kvm_asm.h |   2 +
>  arch/arm64/include/asm/kvm_emulate.h |  15 +++--
>  arch/arm64/include/asm/kvm_host.h|  16 +-
>  arch/arm64/kernel/asm-offsets.c  |   1 +
>  arch/arm64/kvm/Makefile  |   3 +-
>  arch/arm64/kvm/fpsimd_switch.S   |  38 
>  arch/arm64/kvm/hyp.S | 108 
> +--
>  arch/arm64/kvm/hyp_head.S|  48 
>  11 files changed, 181 insertions(+), 77 deletions(-)
>  create mode 100644 arch/arm64/kvm/fpsimd_switch.S
>  create mode 100644 arch/arm64/kvm/hyp_head.S
> 
> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> b/arch/arm/include/asm/kvm_emulate.h
> index 3de11a2..13feed5 100644
> --- a/arch/arm/include/asm/kvm_emulate.h
> +++ b/arch/arm/include/asm/kvm_emulate.h
> @@ -243,6 +243,11 @@ static inline unsigned long 
> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
>   }
>  }
>  
> +static inline bool kvm_guest_vcpu_is_32bit(struct kvm_vcpu *vcpu)
> +{
> + return true;
> +}
> +
>  #ifdef CONFIG_VFPv3
>  /* Called from vcpu_load - save fpexc and enable guest access to fp/simd 
> unit */
>  static inline void kvm_enable_vcpu_fpexc(struct kvm_vcpu *vcpu)
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index ecc883a..720ae51 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -227,6 +227,8 @@ int kvm_perf_teardown(void);
>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
>  
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
> +
> +static inline void kvm_save_guest_vcpu_fpexc(struct kvm_vcpu *vcpu) {}
>  void kvm_restore_host_vfp_state(struct kvm_vcpu *);
>  
>  static inline void kvm_arch_hardware_disable(void) {}
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 1de07ab..dd59f8a 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -292,8 +292,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  
>   kvm_arm_set_running_vcpu(vcpu);
>  
> - /*  Save and enable FPEXC before we load guest context */
> - kvm_enable_vcpu_fpexc(vcpu);
> + /*
> +  * For 32bit guest executing on arm64, enable fp/simd access in
> +  * EL2. On arm32 save host fpexc and then enable fp/simd access.
> +  */
> + if (kvm_guest_vcpu_is_32bit(vcpu))
> + kvm_enable_vcpu_fpexc(vcpu);
>  
>   /* reset hyp cptr register to trap on tracing and vfp/simd access*/
>   vcpu_reset_cptr(vcpu);
> @@ -302,10 +306,18 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  {
>   /* If the fp/simd registers are dirty save guest, restore host. */
> - if (kvm_vcpu_vfp_isdirty(vcpu))
> + if (kvm_vcpu_vfp_isdirty(vcpu)) {
>   kvm_restore_host_vfp_state(vcpu);
>  
> - /* Restore host FPEXC trashed in vcpu_load */
> + /*
> +  * For 32bit guest on arm64 save the guest fpexc register
> +  * in EL2 mode.
> +  */
> + if (kvm_guest_vcpu_is_32bit(vcpu))
> + kvm_save_guest_vcpu_fpexc(vcpu);
> + }
> +
> + /* For arm32 restore host FPEXC trashed in vcpu_load. */
>   kvm_restore_host_fpexc(vcpu);
>  
>   /*
> diff --git a/arch/arm64/include/asm/kvm_asm.h 
> b/arch/arm64/include/asm/kvm_asm.h
> index 5e37710..d53d069 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -117,6 +117,8 @@ extern char __kvm_hyp_vector[];
>  extern void __kvm_flush_vm_context(void);
>  extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
>  extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
> +extern void __kvm_vcpu_enable_fpexc32(void);
> +extern void __kvm_vcpu_save_fpexc32(struct kvm_vcpu *vcpu);
>  
>  extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/arm64/include/asm/kvm_emulate.h 
> b/arch/arm64/include/asm/kvm_emulate.h
> index 8dccbd7..bbbee9d 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -290,13 +290,20 @@ static inline unsigned long 
> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
>   return data;   

Re: [PATCH v5 2/3] KVM/arm/arm64: enable enhanced armv7 fp/simd lazy switch

2015-12-18 Thread Christoffer Dall
oc_a15.o coproc_a7.o mmio.o psci.o perf.o 
> fpsimd_switch.o
>  obj-y += $(KVM)/arm/vgic.o
>  obj-y += $(KVM)/arm/vgic-v2.o
>  obj-y += $(KVM)/arm/vgic-v2-emul.o
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index dc017ad..1de07ab 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -291,10 +291,23 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>   vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
>  
>   kvm_arm_set_running_vcpu(vcpu);
> +
> + /*  Save and enable FPEXC before we load guest context */
> + kvm_enable_vcpu_fpexc(vcpu);

hmmm, not really sure the 'enable' part of this name is the right choice
when looking at this.  kvm_prepare_vcpu_fpexc ?

> +
> + /* reset hyp cptr register to trap on tracing and vfp/simd access*/
> + vcpu_reset_cptr(vcpu);

alternatively you could combine the two functions above into a single
function called something like "vcpu_trap_vfp_enable()" or
"vcpu_load_configure_vfp()"

(I sort of feel like we have reserved the _reset_ namespace for stuff we
actually do at VCPU reset.)


>  }
>  
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  {
> + /* If the fp/simd registers are dirty save guest, restore host. */
> + if (kvm_vcpu_vfp_isdirty(vcpu))
> + kvm_restore_host_vfp_state(vcpu);
> +
> +     /* Restore host FPEXC trashed in vcpu_load */
> + kvm_restore_host_fpexc(vcpu);
> +
>   /*
>* The arch-generic KVM code expects the cpu field of a vcpu to be -1
>* if the vcpu is no longer assigned to a cpu.  This is used for the
> diff --git a/arch/arm/kvm/fpsimd_switch.S b/arch/arm/kvm/fpsimd_switch.S
> new file mode 100644
> index 000..d297c54
> --- /dev/null
> +++ b/arch/arm/kvm/fpsimd_switch.S
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright (C) 2012 - Virtual Open Systems and Columbia University
> + * Author: Christoffer Dall <c.d...@virtualopensystems.com>

Not quite, this is new code, so you should just claim copyright and
authorship I believe.

> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "interrupts_head.S"
> +
> + .text
> +/**
> +  * void kvm_restore_host_vfp_state(struct vcpu *vcpu) -
> +  * This function is called from host to save the guest, and restore host
> +  * fp/simd hardware context. It's placed outside of hyp start/end 
> region.
> +  */
> +ENTRY(kvm_restore_host_vfp_state)
> +#ifdef CONFIG_VFPv3
> + push{r4-r7}
> +
> + add r7, r0, #VCPU_VFP_GUEST
> + store_vfp_state r7
> +
> + add r7, r0, #VCPU_VFP_HOST
> + ldr r7, [r7]
> + restore_vfp_state r7
> +
> + pop {r4-r7}
> +#endif
> + bx  lr
> +ENDPROC(kvm_restore_host_vfp_state)
> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
> index 900ef6d..8e25431 100644
> --- a/arch/arm/kvm/interrupts.S
> +++ b/arch/arm/kvm/interrupts.S
> @@ -116,22 +116,15 @@ ENTRY(__kvm_vcpu_run)
>   read_cp15_state store_to_vcpu = 0
>   write_cp15_state read_from_vcpu = 1
>  
> - @ If the host kernel has not been configured with VFPv3 support,
> - @ then it is safer if we deny guests from using it as well.
> -#ifdef CONFIG_VFPv3
> - @ Set FPEXC_EN so the guest doesn't trap floating point instructions
> - VFPFMRX r2, FPEXC   @ VMRS
> - push{r2}
> - orr r2, r2, #FPEXC_EN
> - VFPFMXR FPEXC, r2   @ VMSR
> -#endif
> + @ Enable tracing and possibly fp/simd trapping

Configure trapping of access to tracing and fp/simd registers

> + ldr r4, [vcpu, #VCPU_HCPTR]
> + set_hcptr vmentry, #0, r4

if we store something called HCPTR on the VCPU, then that should really
be HCPTR, so I don't see why we need a macro and this is not just a
write to the HCPTR directly?

>  
>   @ Configure Hyp-role
>   configure_hyp_role vmentry
>  
>   @ Trap coprocessor CRx accesses
>   set_hstr vmentry
> - set_hcptr vmentry, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
>   set_hdcr vmentry
>  
>   @ Write configured ID register into MIDR alias
> @@ -170

Re: [PATCH v5 3/3] KVM/arm/arm64: enable enhanced armv8 fp/simd lazy switch

2015-12-18 Thread Christoffer Dall
On Fri, Dec 18, 2015 at 05:17:00PM -0800, Mario Smarduch wrote:
> On 12/18/2015 5:54 AM, Christoffer Dall wrote:
> > On Sun, Dec 06, 2015 at 05:07:14PM -0800, Mario Smarduch wrote:
> >> This patch tracks armv7 and armv8 fp/simd hardware state with cptr_el2 
> >> register.
> >> On vcpu_load for 32 bit guests enable FP access, and enable fp/simd
> >> trapping for 32 and 64 bit guests. On first fp/simd access trap to handler 
> >> to save host and restore guest context, and clear trapping bits to enable 
> >> vcpu 
> >> lazy mode. On vcpu_put if trap bits are clear save guest and restore host 
> >> context and also save 32 bit guest fpexc register.
> >>
> >> Signed-off-by: Mario Smarduch <m.smard...@samsung.com>
> >> ---
> >>  arch/arm/include/asm/kvm_emulate.h   |   5 ++
> >>  arch/arm/include/asm/kvm_host.h  |   2 +
> >>  arch/arm/kvm/arm.c   |  20 +--
> >>  arch/arm64/include/asm/kvm_asm.h |   2 +
> >>  arch/arm64/include/asm/kvm_emulate.h |  15 +++--
> >>  arch/arm64/include/asm/kvm_host.h|  16 +-
> >>  arch/arm64/kernel/asm-offsets.c  |   1 +
> >>  arch/arm64/kvm/Makefile  |   3 +-
> >>  arch/arm64/kvm/fpsimd_switch.S   |  38 
> >>  arch/arm64/kvm/hyp.S | 108 
> >> +--
> >>  arch/arm64/kvm/hyp_head.S|  48 
> >>  11 files changed, 181 insertions(+), 77 deletions(-)
> >>  create mode 100644 arch/arm64/kvm/fpsimd_switch.S
> >>  create mode 100644 arch/arm64/kvm/hyp_head.S
> >>
> >> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> >> b/arch/arm/include/asm/kvm_emulate.h
> >> index 3de11a2..13feed5 100644
> >> --- a/arch/arm/include/asm/kvm_emulate.h
> >> +++ b/arch/arm/include/asm/kvm_emulate.h
> >> @@ -243,6 +243,11 @@ static inline unsigned long 
> >> vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
> >>}
> >>  }
> >>  
> >> +static inline bool kvm_guest_vcpu_is_32bit(struct kvm_vcpu *vcpu)
> >> +{
> >> +  return true;
> >> +}
> >> +
> >>  #ifdef CONFIG_VFPv3
> >>  /* Called from vcpu_load - save fpexc and enable guest access to fp/simd 
> >> unit */
> >>  static inline void kvm_enable_vcpu_fpexc(struct kvm_vcpu *vcpu)
> >> diff --git a/arch/arm/include/asm/kvm_host.h 
> >> b/arch/arm/include/asm/kvm_host.h
> >> index ecc883a..720ae51 100644
> >> --- a/arch/arm/include/asm/kvm_host.h
> >> +++ b/arch/arm/include/asm/kvm_host.h
> >> @@ -227,6 +227,8 @@ int kvm_perf_teardown(void);
> >>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> >>  
> >>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
> >> +
> >> +static inline void kvm_save_guest_vcpu_fpexc(struct kvm_vcpu *vcpu) {}
> >>  void kvm_restore_host_vfp_state(struct kvm_vcpu *);
> >>  
> >>  static inline void kvm_arch_hardware_disable(void) {}
> >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >> index 1de07ab..dd59f8a 100644
> >> --- a/arch/arm/kvm/arm.c
> >> +++ b/arch/arm/kvm/arm.c
> >> @@ -292,8 +292,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
> >> cpu)
> >>  
> >>kvm_arm_set_running_vcpu(vcpu);
> >>  
> >> -  /*  Save and enable FPEXC before we load guest context */
> >> -  kvm_enable_vcpu_fpexc(vcpu);
> >> +  /*
> >> +   * For 32bit guest executing on arm64, enable fp/simd access in
> >> +   * EL2. On arm32 save host fpexc and then enable fp/simd access.
> >> +   */
> >> +  if (kvm_guest_vcpu_is_32bit(vcpu))
> >> +  kvm_enable_vcpu_fpexc(vcpu);
> >>  
> >>/* reset hyp cptr register to trap on tracing and vfp/simd access*/
> >>vcpu_reset_cptr(vcpu);
> >> @@ -302,10 +306,18 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
> >> cpu)
> >>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >>  {
> >>/* If the fp/simd registers are dirty save guest, restore host. */
> >> -  if (kvm_vcpu_vfp_isdirty(vcpu))
> >> +  if (kvm_vcpu_vfp_isdirty(vcpu)) {
> >>kvm_restore_host_vfp_state(vcpu);
> >>  
> >> -  /* Restore host FPEXC trashed in vcpu_load */
> >> +  /*
> >> +   * For 32bit guest on arm64 save the guest fpexc register
> >> +   * in EL2 mode.
> 

Re: [PATCH v7 19/19] KVM: ARM64: Add a new kvm ARM PMU device

2015-12-16 Thread Christoffer Dall
On Wed, Dec 16, 2015 at 04:06:49PM +0800, Shannon Zhao wrote:
> Hi,
> 
> On 2015/12/16 15:31, Shannon Zhao wrote:
>  >> > But in this case, you're returning an error if it is *not* 
>  >> > initialized.
>  >> > I understand that in that case you cannot return an interrupt 
>  >> > number (-1
>  >> > would be weird), but returning -EBUSY feels even more weird.
>  >> > 
>  >> > I'd settle for -ENOXIO, or something similar. Anyone having a 
>  >> > better idea?
>  >> > 
> >> > ENXIO or ENODEV would be my choice too, and add that to the
> >> > Documentation clearly describing when this error code is used.
> >> > 
> >> > By the way, why do you loop over all VCPUS to set the same value when
> >> > you can't do anything per VCPU anyway?  It seems to me it's either a
> >> > per-VM property (that you can store on the VM data structure) or it's a
> >> > true per-VCPU property?
> > This is a per-VCPU property. PMU interrupt could be PPI or SPI. For PPI
> > the interrupt numbers are same for each vcpu, while for SPI they are
> > different, so it needs to set them separately. I planned to support both
> > PPI and SPI. I think I should add support for SPI at this moment and let
> > users (QEMU) to set these interrupts for each one.
> 
> How about below vPMU Documentation?
> 
> ARM Virtual Performance Monitor Unit (vPMU)
> ===
> 
> Device types supported:
>   KVM_DEV_TYPE_ARM_PMU_V3 ARM Performance Monitor Unit v3
> 
> Instantiate one PMU instance for per VCPU through this API.
> 
> Groups:
>   KVM_DEV_ARM_PMU_GRP_IRQ
>   Attributes:
> The attr field of kvm_device_attr encodes two values:
> bits: | 63  32 | 31  0 |
> values:   | vcpu_index |  irq_num  |
> The irq_num describes the PMU overflow interrupt number for the
> specified
> vcpu_index vcpu. This interrupt could be a PPI or SPI, but for one
> VM the
> interrupt type must be same for each vcpu.

some formatting snafus that I expect come from pasting the text in an
e-mail client.

> 
>   Errors:
> -ENXIO: Getting or setting this attribute is not yet supported

'not yet supported' as in something we'll implement later, or as in you
need to call this other function before you can access this state?

> -ENODEV: Getting the PMU overflow interrupt number while it's not set
> -EBUSY: The PMU overflow interrupt is already set
> -EINVAL: Invalid vcpu_index or irq_num supplied
> 
> 
Otherwise looks good.

Thanks,
-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] arm64: KVM: debug: Remove spurious inline attributes

2015-12-16 Thread Christoffer Dall
On Wed, Dec 16, 2015 at 03:49:23PM +, Marc Zyngier wrote:
> The debug trapping code is pretty heavy on the "inline" attribute,
> but most functions are actually referenced in the sysreg tables,
> making the inlining imposible.
> 
> Removing the useless inline qualifier seems the right thing to do,
> having verified that the output code is similar.

To quote Rusty when he reviewd some of my first KVM patches:
  "I consider inline the register keyword of the 90s"

You can take that as an:

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: ARM64/KVM: Bad page state in process iperf

2015-12-15 Thread Christoffer Dall
On Tue, Dec 15, 2015 at 03:46:03AM +, Bhushan Bharat wrote:
> 
> Hi All,
> 
> I am running "iperf" in KVM guest on ARM64 machine and observing below crash.

Which host/guest kernel version is this?

Which hardware?

-Christoffer

> 
> =
> $iperf -c 3.3.3.3 -P 4 -t 0 -i 5 -w 90k
> 
> Client connecting to 3.3.3.3, TCP port 5001
> TCP window size:  180 KByte (WARNING: requested 90.0 KByte)
> 
> [  3] local 3.3.3.1 port 51131 connected with 3.3.3.3 port 5001
> [  6] local 3.3.3.1 port 51134 connected with 3.3.3.3 port 5001
> [  5] local 3.3.3.1 port 51133 connected with 3.3.3.3 port 5001
> [  4] local 3.3.3.1 port 51132 connected with 3.3.3.3 port 5001
> [   53.088567] random: nonblocking pool is initialized
> [ ID] Interval   Transfer Bandwidth
> [  3]  0.0- 5.0 sec   638 MBytes  1.07 Gbits/sec
> [  4] 35.0-40.0 sec  1.66 GBytes  2.85 Gbits/sec
> [  5] 40.0-45.0 sec  1.11 GBytes  1.90 Gbits/sec
> [  4] 40.0-45.0 sec  1.16 GBytes  1.99 Gbits/sec
> [   98.895207] BUG: Bad page state in process iperf  pfn:0a584
> [   98.896164] page:78296100 count:-1 mapcount:0 mapping:  
> (null) index:0x0
> [   98.897436] flags: 0x0()
> [   98.897885] page dumped because: nonzero _count
> [   98.898640] Modules linked in:
> [   98.899178] CPU: 0 PID: 1639 Comm: iperf Not tainted 4.1.8-00461-ge5431ad 
> #141
> [   98.900302] Hardware name: linux,dummy-virt (DT)
> [   98.901014] Call trace:
> [   98.901406] [] dump_backtrace+0x0/0x12c
> [   98.902522] [] show_stack+0x10/0x1c
> [   98.903441] [] dump_stack+0x8c/0xdc
> [   98.904202] [] bad_page+0xc4/0x114
> [   98.904945] [] get_page_from_freelist+0x590/0x63c
> [   98.905871] [] __alloc_pages_nodemask+0xec/0x794
> [   98.906791] [] skb_page_frag_refill+0x70/0xa8
> [   98.907678] [] sk_page_frag_refill+0x20/0xd0
> [   98.908550] [] tcp_sendmsg+0x1f8/0x9a8
> [   98.909368] [] inet_sendmsg+0x5c/0xd0
> [   98.910178] [] sock_sendmsg+0x14/0x58
> [   98.911027] [] sock_write_iter+0x64/0xbc
> [   98.912119] [] __vfs_write+0xac/0x10c
> [   98.913126] [] vfs_write+0x90/0x1a0
> [   98.913963] [] SyS_write+0x40/0xa0
> 
> ---
> ___
> kvmarm mailing list
> kvm...@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 19/19] KVM: ARM64: Add a new kvm ARM PMU device

2015-12-15 Thread Christoffer Dall
On Tue, Dec 15, 2015 at 03:59:31PM +, Marc Zyngier wrote:
> On 15/12/15 15:50, Shannon Zhao wrote:
> > 
> > 
> > On 2015/12/15 23:33, Marc Zyngier wrote:
> >> On 15/12/15 08:49, Shannon Zhao wrote:
>  From: Shannon Zhao
> 
>  Add a new kvm device type KVM_DEV_TYPE_ARM_PMU_V3 for ARM PMU. Implement
>  the kvm_device_ops for it.
> 
>  Signed-off-by: Shannon Zhao
>  ---
>   Documentation/virtual/kvm/devices/arm-pmu.txt |  16 
>   arch/arm64/include/uapi/asm/kvm.h |   3 +
>   include/linux/kvm_host.h  |   1 +
>   include/uapi/linux/kvm.h  |   2 +
>   virt/kvm/arm/pmu.c| 115 
>  ++
>   virt/kvm/kvm_main.c   |   4 +
>   6 files changed, 141 insertions(+)
>   create mode 100644 Documentation/virtual/kvm/devices/arm-pmu.txt
> 
>  diff --git a/Documentation/virtual/kvm/devices/arm-pmu.txt 
>  b/Documentation/virtual/kvm/devices/arm-pmu.txt
>  new file mode 100644
>  index 000..5121f1f
>  --- /dev/null
>  +++ b/Documentation/virtual/kvm/devices/arm-pmu.txt
>  @@ -0,0 +1,16 @@
>  +ARM Virtual Performance Monitor Unit (vPMU)
>  +===
>  +
>  +Device types supported:
>  +  KVM_DEV_TYPE_ARM_PMU_V3 ARM Performance Monitor Unit v3
>  +
>  +Instantiate one PMU instance for per VCPU through this API.
>  +
>  +Groups:
>  +  KVM_DEV_ARM_PMU_GRP_IRQ
>  +  Attributes:
>  +A value describing the interrupt number of PMU overflow interrupt. 
>  This
>  +interrupt should be a PPI.
>  +
>  +  Errors:
>  +-EINVAL: Value set is out of the expected range (from 16 to 31)
>  diff --git a/arch/arm64/include/uapi/asm/kvm.h 
>  b/arch/arm64/include/uapi/asm/kvm.h
>  index 2d4ca4b..568afa2 100644
>  --- a/arch/arm64/include/uapi/asm/kvm.h
>  +++ b/arch/arm64/include/uapi/asm/kvm.h
>  @@ -204,6 +204,9 @@ struct kvm_arch_memory_slot {
>   #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
>   #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
> 
>  +/* Device Control API: ARM PMU */
>  +#define KVM_DEV_ARM_PMU_GRP_IRQ 0
>  +
>   /* KVM_IRQ_LINE irq field index values */
>   #define KVM_ARM_IRQ_TYPE_SHIFT  24
>   #define KVM_ARM_IRQ_TYPE_MASK   0xff
>  diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>  index c923350..608dea6 100644
>  --- a/include/linux/kvm_host.h
>  +++ b/include/linux/kvm_host.h
>  @@ -1161,6 +1161,7 @@ extern struct kvm_device_ops kvm_mpic_ops;
>   extern struct kvm_device_ops kvm_xics_ops;
>   extern struct kvm_device_ops kvm_arm_vgic_v2_ops;
>   extern struct kvm_device_ops kvm_arm_vgic_v3_ops;
>  +extern struct kvm_device_ops kvm_arm_pmu_ops;
> 
>   #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT
> 
>  diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>  index 03f3618..4ba6fdd 100644
>  --- a/include/uapi/linux/kvm.h
>  +++ b/include/uapi/linux/kvm.h
>  @@ -1032,6 +1032,8 @@ enum kvm_device_type {
>   #define KVM_DEV_TYPE_FLIC   KVM_DEV_TYPE_FLIC
>   KVM_DEV_TYPE_ARM_VGIC_V3,
>   #define KVM_DEV_TYPE_ARM_VGIC_V3KVM_DEV_TYPE_ARM_VGIC_V3
>  +KVM_DEV_TYPE_ARM_PMU_V3,
>  +#define KVM_DEV_TYPE_ARM_PMU_V3 KVM_DEV_TYPE_ARM_PMU_V3
>   KVM_DEV_TYPE_MAX,
>   };
> 
>  diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
>  index d113ee4..1965d0d 100644
>  --- a/virt/kvm/arm/pmu.c
>  +++ b/virt/kvm/arm/pmu.c
>  @@ -19,6 +19,7 @@
>   #include 
>   #include 
>   #include 
>  +#include 
>   #include 
>   #include 
>   #include 
>  @@ -357,3 +358,117 @@ void kvm_pmu_set_counter_event_type(struct 
>  kvm_vcpu *vcpu, u64 data,
> 
>   pmc->perf_event = event;
>   }
>  +
>  +static inline bool kvm_arm_pmu_initialized(struct kvm_vcpu *vcpu)
>  +{
>  +return vcpu->arch.pmu.irq_num != -1;
>  +}
>  +
>  +static int kvm_arm_pmu_irq_access(struct kvm *kvm, int *irq, bool 
>  is_set)
>  +{
>  +int j;
>  +struct kvm_vcpu *vcpu;
>  +
>  +kvm_for_each_vcpu(j, vcpu, kvm) {
>  +struct kvm_pmu *pmu = >arch.pmu;
>  +
>  +if (!is_set) {
>  +if (!kvm_arm_pmu_initialized(vcpu))
>  +return -EBUSY;
> >> Returning -EBUSY is a bit odd. Maybe -EINVAL? But this seems weird
> >> anyway. Actually, why would you return an error in this case?
> >>
> > While this is a unexpected operation from user space and it's already 
> > initialized and working, so I 

Re: [PATCH v3 22/22] arm64: KVM: Remove weak attributes

2015-12-14 Thread Christoffer Dall
On Mon, Dec 07, 2015 at 10:53:38AM +, Marc Zyngier wrote:
> As we've now switched to the new world switch implementation,
> remove the weak attributes, as nobody is supposed to override
> it anymore.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 10/22] arm64: KVM: Implement guest entry

2015-12-14 Thread Christoffer Dall
ading comment again?  Or misplaced at least?

> + stp x4, x5,   [x2, #CPU_XREG_OFFSET(4)]
> + stp x6, x7,   [x2, #CPU_XREG_OFFSET(6)]
> + stp x8, x9,   [x2, #CPU_XREG_OFFSET(8)]
> + stp x10, x11, [x2, #CPU_XREG_OFFSET(10)]
> + stp x12, x13, [x2, #CPU_XREG_OFFSET(12)]
> + stp x14, x15, [x2, #CPU_XREG_OFFSET(14)]
> + stp x16, x17, [x2, #CPU_XREG_OFFSET(16)]
> + str x18,  [x2, #CPU_XREG_OFFSET(18)]
> +
> + ldp x6, x7, [sp], #16   // x2, x3
> + ldp x4, x5, [sp], #16   // x0, x1
> +
> + stp x4, x5, [x2, #CPU_XREG_OFFSET(0)]
> + stp x6, x7, [x2, #CPU_XREG_OFFSET(2)]
> +
> + save_callee_saved_regs x2
> +
> + // Restore vcpu & host_ctxt from the stack
> + // (preserving return code in x1)
> + ldp x0, x2, [sp], #16
> + // Now restore the host regs
> + restore_callee_saved_regs x2
> +
> + mov x0, x1
> + ret
> +ENDPROC(__guest_exit)
> +
> + /* Insert fault handling here */
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index 454e46f..0809653 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -52,5 +52,7 @@ void __debug_restore_state(struct kvm_vcpu *vcpu,
>  void __debug_cond_save_host_state(struct kvm_vcpu *vcpu);
>  void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu);
>  
> +u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
> +
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> -- 
> 2.1.4
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 02/22] arm64: KVM: Add a HYP-specific header file

2015-12-11 Thread Christoffer Dall
On Mon, Dec 07, 2015 at 10:53:18AM +, Marc Zyngier wrote:
> In order to expose the various EL2 services that are private to
> the hypervisor, add a new hyp.h file.
> 
> So far, it only contains mundane things such as section annotation
> and VA manipulation.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 06/22] arm64: KVM: Implement timer save/restore

2015-12-11 Thread Christoffer Dall
On Mon, Dec 07, 2015 at 10:53:22AM +, Marc Zyngier wrote:
> Implement the timer save restore as a direct translation of
> the assembly code version.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 11/22] arm64: KVM: Add patchable function selector

2015-12-11 Thread Christoffer Dall
On Mon, Dec 07, 2015 at 10:53:27AM +, Marc Zyngier wrote:
> KVM so far relies on code patching, and is likely to use it more
> in the future. The main issue is that our alternative system works
> at the instruction level, while we'd like to have alternatives at
> the function level.
> 
> In order to cope with this, add the "hyp_alternate_select" macro that
> outputs a brief sequence of code that in turn can be patched, allowing
> an alternative function to be selected.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 03/22] arm64: KVM: Implement vgic-v2 save/restore

2015-12-11 Thread Christoffer Dall
gt;kvm);
> + struct vgic_v2_cpu_if *cpu_if = >arch.vgic_cpu.vgic_v2;
> + struct vgic_dist *vgic = >arch.vgic;
> + void __iomem *base = kern_hyp_va(vgic->vctrl_base);
> + int i, nr_lr;
> +
> + if (!base)
> +     return;
> +
> + writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR);
> + writel_relaxed(cpu_if->vgic_vmcr, base + GICH_VMCR);
> + writel_relaxed(cpu_if->vgic_apr, base + GICH_APR);
> +
> + nr_lr = vcpu->arch.vgic_cpu.nr_lr;
> + for (i = 0; i < nr_lr; i++)

nit: why do you need the nr_lr variable?  it may make the code easier to
read I guess.

> + writel_relaxed(cpu_if->vgic_lr[i], base + GICH_LR0 + (i * 4));
> +}
> -- 
> 2.1.4
> 

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 04/22] KVM: arm/arm64: vgic-v3: Make the LR indexing macro public

2015-12-11 Thread Christoffer Dall
On Mon, Dec 07, 2015 at 10:53:20AM +, Marc Zyngier wrote:
> We store GICv3 LRs in reverse order so that the CPU can save/restore
> them in rever order as well (don't ask why, the design is crazy),

s/rever/reverse/

> and yet generate memory traffic that doesn't completely suck.
> 
> We need this macro to be available to the C version of save/restore.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> ---
>  include/kvm/arm_vgic.h |  6 ++
>  virt/kvm/arm/vgic-v3.c | 10 ++
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index d2f4147..13a3d53 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -279,6 +279,12 @@ struct vgic_v2_cpu_if {
>   u32 vgic_lr[VGIC_V2_MAX_LRS];
>  };
>  
> +/*
> + * LRs are stored in reverse order in memory. make sure we index them

s/make/Make/  or s/\./,

> + * correctly.
> + */
> +#define VGIC_V3_LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr)
> +
>  struct vgic_v3_cpu_if {
>  #ifdef CONFIG_KVM_ARM_VGIC_V3
>   u32 vgic_hcr;
> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
> index 487d635..3813d23 100644
> --- a/virt/kvm/arm/vgic-v3.c
> +++ b/virt/kvm/arm/vgic-v3.c
> @@ -36,18 +36,12 @@
>  #define GICH_LR_PHYSID_CPUID (7UL << GICH_LR_PHYSID_CPUID_SHIFT)
>  #define ICH_LR_VIRTUALID_MASK(BIT_ULL(32) - 1)
>  
> -/*
> - * LRs are stored in reverse order in memory. make sure we index them
> - * correctly.
> - */
> -#define LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr)
> -
>  static u32 ich_vtr_el2;
>  
>  static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr)
>  {
>   struct vgic_lr lr_desc;
> - u64 val = vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)];
> + u64 val = vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[VGIC_V3_LR_INDEX(lr)];
>  
>   if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
>   lr_desc.irq = val & ICH_LR_VIRTUALID_MASK;
> @@ -111,7 +105,7 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
>   lr_val |= ((u64)lr_desc.hwirq) << ICH_LR_PHYS_ID_SHIFT;
>   }
>  
> - vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val;
> + vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[VGIC_V3_LR_INDEX(lr)] = lr_val;
>  
>   if (!(lr_desc.state & LR_STATE_MASK))
>   vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr);
> -- 
> 2.1.4
> 

Otherwise:
Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 05/22] arm64: KVM: Implement vgic-v3 save/restore

2015-12-11 Thread Christoffer Dall
cpu_if->vgic_lr[VGIC_V3_LR_INDEX(8)], ICH_LR8_EL2);
> + case 7:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(7)], ICH_LR7_EL2);
> + case 6:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(6)], ICH_LR6_EL2);
> + case 5:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(5)], ICH_LR5_EL2);
> + case 4:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(4)], ICH_LR4_EL2);
> + case 3:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(3)], ICH_LR3_EL2);
> + case 2:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(2)], ICH_LR2_EL2);
> + case 1:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(1)], ICH_LR1_EL2);
> + case 0:
> + write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(0)], ICH_LR0_EL2);
> + }
> +
> + /*
> +  * Ensures that the above will have reached the
> +  * (re)distributors. This ensure the guest will read the

You fixed the wrong instance of 'ensure' ;)

> +  * correct values from the memory-mapped interface.
> +  */
> + isb();
> + dsb(sy);
> +
> + /*
> +  * Prevent the guest from touching the GIC system registers if
> +  * SRE isn't enabled for GICv3 emulation.
> +  */
> + if (!cpu_if->vgic_sre) {
> + write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
> +  ICC_SRE_EL2);
> + }
> +}
> +
> +u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void)
> +{
> + return read_gicreg(ICH_VTR_EL2);
> +}

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] KVM: arm/arm64: vgic: Fix kvm_vgic_map_is_active's dist check

2015-12-10 Thread Christoffer Dall
External inputs to the vgic from time to time need to poke into the
state of a virtual interrupt, the prime example is the architected timer
code.

Since the IRQ's active state can be represented in two places; the LR or
the distributor, we first loop over the LRs but if not active in the LRs
we just return if *any* IRQ is active on the VCPU in question.

This is of course bogus, as we should check if the specific IRQ in
quesiton is active on the distributor instead.

Reported-by: Eric Auger <eric.au...@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 65461f8..7a2f449 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1114,7 +1114,7 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct 
irq_phys_map *map)
return true;
}
 
-   return dist_active_irq(vcpu);
+   return vgic_irq_is_active(vcpu, map->virt_irq);
 }
 
 /*
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 18/21] KVM: ARM64: Add PMU overflow interrupt routing

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 10:22:04AM +, Marc Zyngier wrote:
> On 02/12/15 09:49, Shannon Zhao wrote:
> > 
> > 
> > On 2015/12/2 16:45, Marc Zyngier wrote:
> >> On 02/12/15 02:40, Shannon Zhao wrote:
> >>>>
> >>>>
> >>>> On 2015/12/2 0:57, Marc Zyngier wrote:
> >>>>>> On 01/12/15 16:26, Shannon Zhao wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 2015/12/1 23:41, Marc Zyngier wrote:
> >>>>>>>>>>>> The reason is that when guest clear the overflow register, it 
> >>>>>>>>>>>> will trap
> >>>>>>>>>>>>>> to kvm and call kvm_pmu_sync_hwstate() as you see above. At 
> >>>>>>>>>>>>>> this moment,
> >>>>>>>>>>>>>> the overflow register is still overflowed(that is some bit is 
> >>>>>>>>>>>>>> still 1).
> >>>>>>>>>>>>>> So We need to use some flag to mark we already inject this 
> >>>>>>>>>>>>>> interrupt.
> >>>>>>>>>>>>>> And if during guest handling the overflow, there is a new 
> >>>>>>>>>>>>>> overflow
> >>>>>>>>>>>>>> happening, the pmu->irq_pending will be set ture by
> >>>>>>>>>>>>>> kvm_pmu_perf_overflow(), then it needs to inject this new 
> >>>>>>>>>>>>>> interrupt, right?
> >>>>>>>>>> I don't think so. This is a level interrupt, so the level should 
> >>>>>>>>>> stay
> >>>>>>>>>> high as long as the guest hasn't cleared all possible sources for 
> >>>>>>>>>> that
> >>>>>>>>>> interrupt.
> >>>>>>>>>>
> >>>>>>>>>> For your example, the guest writes to PMOVSCLR to clear the 
> >>>>>>>>>> overflow
> >>>>>>>>>> caused by a given counter. If the status is now 0, the interrupt 
> >>>>>>>>>> line
> >>>>>>>>>> drops. If the status is still non zero, the line stays high. And I
> >>>>>>>>>> believe that writing a 1 to PMOVSSET would actually trigger an
> >>>>>>>>>> interrupt, or keep it high if it has already high.
> >>>>>>>>>>
> >>>>>>>> Right, writing 1 to PMOVSSET will trigger an interrupt.
> >>>>>>>>
> >>>>>>>>>> In essence, do not try to maintain side state. I've been bitten.
> >>>>>>>>
> >>>>>>>> So on VM entry, it check if PMOVSSET is zero. If not, call 
> >>>>>>>> kvm_vgic_inject_irq to set the level high. If so, set the level low.
> >>>>>>>> On VM exit, it seems there is nothing to do.
> >>>>>>
> >>>>>> It is even simpler than that:
> >>>>>>
> >>>>>> - When you get an overflow, you inject an interrupt with the level set 
> >>>>>> to 1.
> >>>>>> - When the overflow register gets cleared, you inject the same 
> >>>>>> interrupt
> >>>>>> with the level set to 0.
> >>>>>>
> >>>>>> I don't think you need to do anything else, and the world switch should
> >>>>>> be left untouched.
> >>>>>>
> >>>>
> >>>> On 2015/7/17 23:28, Christoffer Dall wrote:>> > +
> >>>> kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
> >>>>>>>>>> +  pmu->irq_num, 1);
> >>>>>> what context is this overflow handler function?  kvm_vgic_inject_irq
> >>>>>> grabs a mutex, so it can sleep...
> >>>>>>
> >>>>>> from a quick glance at the perf core code, it looks like this is in
> >>>>>> interrupt context, so that call to kvm_vgic_inject_irq looks bad.
> >>>>>>
> >>>>
> >>>> But as Christoffer said before, it's not good to call
> >>>> kvm_vgic_inject_irq directly in interrupt context. So if we just kick
> >>>> the vcpu here and call kvm_vgic_inject_irq on VM entry, is this fine?
> >> Possibly. I'm slightly worried that inject_irq itself is going to kick
> >> the vcpu again for no good reason. 
> > Yes, this will introduce a extra kick. What's the impact of kicking a
> > kicked vcpu?
> 
> As long as you only kick yourself, it shouldn't be much (trying to
> decipher vcpu_kick).
> 

The behavior of vcpu_kick really depends on a number of things:

 - If you're kicking yourself, nothing happens.
 - If you're kicking a sleeping vcpu, wake it up
 - If you're kicking a running vcpu, send it a physical IPI
 - If the vcpu is not running, and not sleeping (so still runnable)
   don't do anything, just wait until it gets scheduled.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 10/21] arm64: KVM: Add patchable function selector

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 01:19:22PM +, Marc Zyngier wrote:
> On 02/12/15 11:53, Christoffer Dall wrote:
> > On Wed, Dec 02, 2015 at 09:47:43AM +, Marc Zyngier wrote:
> >> On 02/12/15 09:27, Christoffer Dall wrote:
> >>> On Tue, Dec 01, 2015 at 06:51:00PM +, Marc Zyngier wrote:
> >>>> On 01/12/15 15:39, Christoffer Dall wrote:
> >>>>> On Fri, Nov 27, 2015 at 06:50:04PM +, Marc Zyngier wrote:
> >>>>>> KVM so far relies on code patching, and is likely to use it more
> >>>>>> in the future. The main issue is that our alternative system works
> >>>>>> at the instruction level, while we'd like to have alternatives at
> >>>>>> the function level.
> >>>>>>
> >>>>>> In order to cope with this, add the "hyp_alternate_select" macro that
> >>>>>> outputs a brief sequence of code that in turn can be patched, allowing
> >>>>>> al alternative function to be selected.
> >>>>>
> >>>>> s/al/an/ ?
> >>>>>
> >>>>>>
> >>>>>> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >>>>>> ---
> >>>>>>  arch/arm64/kvm/hyp/hyp.h | 16 
> >>>>>>  1 file changed, 16 insertions(+)
> >>>>>>
> >>>>>> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >>>>>> index 7ac8e11..f0427ee 100644
> >>>>>> --- a/arch/arm64/kvm/hyp/hyp.h
> >>>>>> +++ b/arch/arm64/kvm/hyp/hyp.h
> >>>>>> @@ -27,6 +27,22 @@
> >>>>>>  
> >>>>>>  #define kern_hyp_va(v) (typeof(v))((unsigned long)v & 
> >>>>>> HYP_PAGE_OFFSET_MASK)
> >>>>>>  
> >>>>>> +/*
> >>>>>> + * Generates patchable code sequences that are used to switch between
> >>>>>> + * two implementations of a function, depending on the availability of
> >>>>>> + * a feature.
> >>>>>> + */
> >>>>>
> >>>>> This looks right to me, but I'm a bit unclear what the types of this is
> >>>>> and how to use it.
> >>>>>
> >>>>> Are orig and alt function pointers and cond is a CONFIG_FOO ?  fname is
> >>>>> a symbol, which is defined as a prototype somewhere and then implemented
> >>>>> here, or?
> >>>>>
> >>>>> Perhaps a Usage: part of the docs would be helpful.
> >>>>
> >>>> How about:
> >>>>
> >>>> @fname: a symbol name that will be defined as a function returning a
> >>>> function pointer whose type will match @orig and @alt
> >>>> @orig: A pointer to the default function, as returned by @fname when
> >>>> @cond doesn't hold
> >>>> @alt: A pointer to the alternate function, as returned by @fname when
> >>>> @cond holds
> >>>> @cond: a CPU feature (as described in asm/cpufeature.h)
> >>>
> >>> looks good.
> >>>
> >>>>
> >>>>>
> >>>>>> +#define hyp_alternate_select(fname, orig, alt, cond)  
> >>>>>> \
> >>>>>> +typeof(orig) * __hyp_text fname(void) 
> >>>>>> \
> >>>>>> +{ 
> >>>>>> \
> >>>>>> +  typeof(alt) *val = orig;
> >>>>>> \
> >>>>>> +  asm volatile(ALTERNATIVE("nop   \n",
> >>>>>> \
> >>>>>> +   "mov   %0, %1  \n",
> >>>>>> \
> >>>>>> +   cond)  
> >>>>>> \
> >>>>>> +   : "+r" (val) : "r" (alt)); 
> >>>>>> \
> >>>>>> +  return val; 
> >>>>>> \
> >>>>>> +}
> >>>>>> +
> >>>>>>  void __vgic_v2_save_state(struct kvm_vcpu *

Re: [PATCH v2 21/21] arm64: KVM: Remove weak attributes

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 03:21:49PM +, Marc Zyngier wrote:
> On 02/12/15 11:47, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:50:15PM +, Marc Zyngier wrote:
> >> As we've now switched to the new world switch implementation,
> >> remove the weak attributes, as nobody is supposed to override
> >> it anymore.
> > 
> > Why not remove the aliases and change the callers?
> 
> This is likely to be a bigger patch, and it would affect the 32bit as
> well. So far, I'm choosing to keep things the same. Another solution
> would be to completely drop the aliases, and just rename the new
> function to have the old names.
> 
> I don't mind either way.
> 
I didn't think of the 32-bit side.  I think eventually we should get rid
of the aliases and just have the funcitons named as they are called, but
there's no rush.  We can wait until we've the done the 32-bit side if
you prefer.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 12/21] arm64: KVM: Implement fpsimd save/restore

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 03:29:50PM +, Marc Zyngier wrote:
> On 02/12/15 11:53, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:50:06PM +, Marc Zyngier wrote:
> >> Implement the fpsimd save restore, keeping the lazy part in
> >> assembler (as returning to C would be overkill).
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/Makefile|  1 +
> >>  arch/arm64/kvm/hyp/entry.S | 32 +++-
> >>  arch/arm64/kvm/hyp/fpsimd.S| 33 +
> >>  arch/arm64/kvm/hyp/hyp.h   |  7 +++
> >>  arch/arm64/kvm/hyp/switch.c|  8 
> >>  arch/arm64/kvm/hyp/sysreg-sr.c |  2 +-
> >>  6 files changed, 81 insertions(+), 2 deletions(-)
> >>  create mode 100644 arch/arm64/kvm/hyp/fpsimd.S
> >>
> >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> >> index 9c11b0f..56238d0 100644
> >> --- a/arch/arm64/kvm/hyp/Makefile
> >> +++ b/arch/arm64/kvm/hyp/Makefile
> >> @@ -9,3 +9,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += entry.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += switch.o
> >> +obj-$(CONFIG_KVM_ARM_HOST) += fpsimd.o
> >> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> >> index 2c4449a..7552922 100644
> >> --- a/arch/arm64/kvm/hyp/entry.S
> >> +++ b/arch/arm64/kvm/hyp/entry.S
> >> @@ -27,6 +27,7 @@
> >>  
> >>  #define CPU_GP_REG_OFFSET(x)  (CPU_GP_REGS + x)
> >>  #define CPU_XREG_OFFSET(x)CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 
> >> 8*x)
> >> +#define CPU_SYSREG_OFFSET(x)  (CPU_SYSREGS + 8*x)
> >>  
> >>.text
> >>.pushsection.hyp.text, "ax"
> >> @@ -152,4 +153,33 @@ ENTRY(__guest_exit)
> >>ret
> >>  ENDPROC(__guest_exit)
> >>  
> >> -  /* Insert fault handling here */
> >> +ENTRY(__fpsimd_guest_restore)
> >> +  pushx4, lr
> >> +
> >> +  mrs x2, cptr_el2
> >> +  bic x2, x2, #CPTR_EL2_TFP
> >> +  msr cptr_el2, x2
> >> +  isb
> >> +
> >> +  mrs x3, tpidr_el2
> >> +
> >> +  ldr x0, [x3, #VCPU_HOST_CONTEXT]
> >> +  kern_hyp_va x0
> >> +  add x0, x0, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
> >> +  bl  __fpsimd_save_state
> >> +
> >> +  add x2, x3, #VCPU_CONTEXT
> >> +  add x0, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
> >> +  bl  __fpsimd_restore_state
> >> +
> >> +  mrs x1, hcr_el2
> >> +  tbnzx1, #HCR_RW_SHIFT, 1f
> > 
> > nit: Add a comment along the lines of:
> > // Skip restoring fpexc32 for AArch64 guests
> > 
> >> +  ldr x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
> >> +  msr fpexc32_el2, x4
> >> +1:
> >> +  pop x4, lr
> >> +  pop x2, x3
> >> +  pop x0, x1
> >> +
> >> +  eret
> >> +ENDPROC(__fpsimd_guest_restore)
> >> diff --git a/arch/arm64/kvm/hyp/fpsimd.S b/arch/arm64/kvm/hyp/fpsimd.S
> >> new file mode 100644
> >> index 000..da3f22c
> >> --- /dev/null
> >> +++ b/arch/arm64/kvm/hyp/fpsimd.S
> >> @@ -0,0 +1,33 @@
> >> +/*
> >> + * Copyright (C) 2015 - ARM Ltd
> >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >> + */
> >> +
> >> +#include 
> >> +
> >> +#include 
> >> +
> >> +  .text
> >> +  .pushsection.hyp.text, "ax"
> >> +
> >> +ENTRY(__fpsimd_save_state)
> >> +  fpsimd_save x0, 1
> >> +  ret
> >> +ENDPROC(__fpsimd_s

Re: [PATCH] KVM: arm/arm64: vgic: make vgic_io_ops static

2015-12-02 Thread Christoffer Dall
On Thu, Nov 12, 2015 at 07:59:14PM +0800, Jisheng Zhang wrote:
> vgic_io_ops is only referenced within vgic.c, so it can be declared
> static.
> 
> Signed-off-by: Jisheng Zhang 

Applied to queue,
-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] KVM: arm/arm64: Revert to old way of checking for device mapping in stage2_flush_ptes().

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 08:04:42PM +0100, Ard Biesheuvel wrote:
> On 2 December 2015 at 19:50, Christoffer Dall
> <christoffer.d...@linaro.org> wrote:
> > On Tue, Dec 01, 2015 at 04:03:52PM +0300, Pavel Fedin wrote:
> >> This function takes stage-II physical addresses (A.K.A. IPA), on input, not
> >> real physical addresses. This causes kvm_is_device_pfn() to return wrong
> >> values, depending on how much guest and host memory maps match. This
> >> results in completely broken KVM on some boards. The problem has been
> >> caught on Samsung proprietary hardware.
> >>
> >> Cc: sta...@vger.kernel.org
> >
> > cc'ing stable doesn't make sense here as the bug was introduced in
> > v4.4-rc3 and we didn't release v4.4 yet...
> >
> >> Fixes: e6fab5442345 ("ARM/arm64: KVM: test properly for a PTE's 
> >> uncachedness")
> >>
> >> Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
> >> ---
> >>  arch/arm/kvm/mmu.c | 3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> >> index 7dace90..51ad98f 100644
> >> --- a/arch/arm/kvm/mmu.c
> >> +++ b/arch/arm/kvm/mmu.c
> >> @@ -310,7 +310,8 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t 
> >> *pmd,
> >>
> >>   pte = pte_offset_kernel(pmd, addr);
> >>   do {
> >> - if (!pte_none(*pte) && 
> >> !kvm_is_device_pfn(__phys_to_pfn(addr)))
> >> + if (!pte_none(*pte) &&
> >> + (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
> >>   kvm_flush_dcache_pte(*pte);
> >>   } while (pte++, addr += PAGE_SIZE, addr != end);
> >>  }
> >
> > You are right that there was a bug in the fix, but your fix is not the
> > right one.
> >
> > Either we have to apply an actual mask and the compare against the value
> > (yes, I know, because of the UXN bit we get lucky so far, but that's too
> > brittle), or we should do a translation fo the gfn to a pfn.  Is there
> > anything preventing us to do the following?
> >
> > if (!pte_none(*pte) && !kvm_is_device_pfn(pte_pfn(*pte)))
> >
> 
> Yes, that looks better. I got confused by addr being a 'phys_addr_t'

Yeah, that's what I thought when I saw this.  Admittedly we could have a
typedef for the IPA, but oh well...

> but obviously, the address inside the PTE is the one we need to test
> for device-ness, so I think we should replace both instances with this
> 

care to send a patch by any chance?

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] KVM: arm/arm64: Revert to old way of checking for device mapping in stage2_flush_ptes().

2015-12-02 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 04:03:52PM +0300, Pavel Fedin wrote:
> This function takes stage-II physical addresses (A.K.A. IPA), on input, not
> real physical addresses. This causes kvm_is_device_pfn() to return wrong
> values, depending on how much guest and host memory maps match. This
> results in completely broken KVM on some boards. The problem has been
> caught on Samsung proprietary hardware.
> 
> Cc: sta...@vger.kernel.org

cc'ing stable doesn't make sense here as the bug was introduced in
v4.4-rc3 and we didn't release v4.4 yet...

> Fixes: e6fab5442345 ("ARM/arm64: KVM: test properly for a PTE's uncachedness")
> 
> Signed-off-by: Pavel Fedin 
> ---
>  arch/arm/kvm/mmu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 7dace90..51ad98f 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -310,7 +310,8 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
>  
>   pte = pte_offset_kernel(pmd, addr);
>   do {
> - if (!pte_none(*pte) && !kvm_is_device_pfn(__phys_to_pfn(addr)))
> + if (!pte_none(*pte) &&
> + (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
>   kvm_flush_dcache_pte(*pte);
>   } while (pte++, addr += PAGE_SIZE, addr != end);
>  }

You are right that there was a bug in the fix, but your fix is not the
right one.

Either we have to apply an actual mask and the compare against the value
(yes, I know, because of the UXN bit we get lucky so far, but that's too
brittle), or we should do a translation fo the gfn to a pfn.  Is there
anything preventing us to do the following?

if (!pte_none(*pte) && !kvm_is_device_pfn(pte_pfn(*pte)))

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 10/21] arm64: KVM: Add patchable function selector

2015-12-02 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 06:51:00PM +, Marc Zyngier wrote:
> On 01/12/15 15:39, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:50:04PM +, Marc Zyngier wrote:
> >> KVM so far relies on code patching, and is likely to use it more
> >> in the future. The main issue is that our alternative system works
> >> at the instruction level, while we'd like to have alternatives at
> >> the function level.
> >>
> >> In order to cope with this, add the "hyp_alternate_select" macro that
> >> outputs a brief sequence of code that in turn can be patched, allowing
> >> al alternative function to be selected.
> > 
> > s/al/an/ ?
> > 
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/hyp.h | 16 
> >>  1 file changed, 16 insertions(+)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >> index 7ac8e11..f0427ee 100644
> >> --- a/arch/arm64/kvm/hyp/hyp.h
> >> +++ b/arch/arm64/kvm/hyp/hyp.h
> >> @@ -27,6 +27,22 @@
> >>  
> >>  #define kern_hyp_va(v) (typeof(v))((unsigned long)v & 
> >> HYP_PAGE_OFFSET_MASK)
> >>  
> >> +/*
> >> + * Generates patchable code sequences that are used to switch between
> >> + * two implementations of a function, depending on the availability of
> >> + * a feature.
> >> + */
> > 
> > This looks right to me, but I'm a bit unclear what the types of this is
> > and how to use it.
> > 
> > Are orig and alt function pointers and cond is a CONFIG_FOO ?  fname is
> > a symbol, which is defined as a prototype somewhere and then implemented
> > here, or?
> > 
> > Perhaps a Usage: part of the docs would be helpful.
> 
> How about:
> 
> @fname: a symbol name that will be defined as a function returning a
> function pointer whose type will match @orig and @alt
> @orig: A pointer to the default function, as returned by @fname when
> @cond doesn't hold
> @alt: A pointer to the alternate function, as returned by @fname when
> @cond holds
> @cond: a CPU feature (as described in asm/cpufeature.h)

looks good.

> 
> > 
> >> +#define hyp_alternate_select(fname, orig, alt, cond)  
> >> \
> >> +typeof(orig) * __hyp_text fname(void) 
> >> \
> >> +{ \
> >> +  typeof(alt) *val = orig;\
> >> +  asm volatile(ALTERNATIVE("nop   \n",\
> >> +   "mov   %0, %1  \n",\
> >> +   cond)  \
> >> +   : "+r" (val) : "r" (alt)); \
> >> +  return val; \
> >> +}
> >> +
> >>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> >>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> >>  
> >> -- 
> >> 2.1.4
> >>
> > 
> > I haven't thought much about how all of this is implemented, but from my
> > point of views the ideal situation would be something like:
> > 
> > void foo(int a, int b)
> > {
> > ALTERNATIVE_IF_NOT CONFIG_BAR
> > foo_legacy(a, b);
> > ALTERNATIVE_ELSE
> > foo_new(a, b);
> > ALTERNATIVE_END
> > }
> > 
> > I realize this may be impossible because the C code could implement all
> > sort of fun stuff around the actual function calls, but would there be
> > some way to annotate the functions and find the actual branch statement
> > and change the target?
> 
> The main issue is that C doesn't give you any access to the branch
> function itself, except for the asm-goto statements. It also makes it
> very hard to preserve the return type. For your idea to work, we'd need
> some support in the compiler itself. I'm sure that it is doable, just
> not by me! ;-)

Not by me either, I'm just asking stupid questions - as always.

> 
> This is why I've ended up creating something that returns a function
> *pointer*, because that's something that exists in the language (no new
> concept). I simply made sure I could return it at minimal cost.
> 

I don't have a problem with this either.  I'm curious though, how much
of a performance improvement (and why) we get from doing this as opposed
to a simple if-statement?

Thanks,
-Christoffer

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 16/21] arm64: KVM: Add compatibility aliases

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:10PM +, Marc Zyngier wrote:
> So far, we've implemented the new world switch with a completely
> different namespace, so that we could have both implementation
> compiled in.
> 
> Let's take things one step further by adding weak aliases that
> have the same names as the original implementation. The weak
> attributes allows the new implementation to be overriden by the
> old one, and everything still work.

Do I understand correctly that the whole point of this is to keep
everything compiling nicely while at the same time being able to split
the patches so that you can have an isolated "remove old code" patch
that doesn't have to change the callers?

If so, I think explaining this rationale would be helpful in the commit
message in case we have to go back and track these changes in connection
with a regression and don't remember why we did things this way.

Maybe I'm being over-cautious though...

Otherwise:

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>

> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> ---
>  arch/arm64/kvm/hyp/debug-sr.c   | 3 +++
>  arch/arm64/kvm/hyp/hyp-entry.S  | 3 +++
>  arch/arm64/kvm/hyp/switch.c | 3 +++
>  arch/arm64/kvm/hyp/tlb.c| 9 +
>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 3 +++
>  5 files changed, 21 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> index a0b2b99..afd0a53 100644
> --- a/arch/arm64/kvm/hyp/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> @@ -128,3 +128,6 @@ u32 __hyp_text __debug_read_mdcr_el2(void)
>  {
>   return read_sysreg(mdcr_el2);
>  }
> +
> +__alias(__debug_read_mdcr_el2)
> +u32 __weak __kvm_get_mdcr_el2(void);
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index 39d6935..ace919b 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -184,6 +184,8 @@ ENDPROC(\label)
>  
>   .align 11
>  
> + .weak   __kvm_hyp_vector
> +ENTRY(__kvm_hyp_vector)
>  ENTRY(__hyp_vector)
>   ventry  el2t_sync_invalid   // Synchronous EL2t
>   ventry  el2t_irq_invalid// IRQ EL2t
> @@ -205,3 +207,4 @@ ENTRY(__hyp_vector)
>   ventry  el1_fiq_invalid // FIQ 32-bit EL1
>   ventry  el1_error_invalid   // Error 32-bit EL1
>  ENDPROC(__hyp_vector)
> +ENDPROC(__kvm_hyp_vector)
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 7b81089..c8ba370 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -141,6 +141,9 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>   return exit_code;
>  }
>  
> +__alias(__guest_run)
> +int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu);
> +
>  static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx 
> ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
>  
>  void __hyp_text __noreturn __hyp_panic(void)
> diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
> index d4a07d0..2c279a8 100644
> --- a/arch/arm64/kvm/hyp/tlb.c
> +++ b/arch/arm64/kvm/hyp/tlb.c
> @@ -47,6 +47,9 @@ void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, 
> phys_addr_t ipa)
>   write_sysreg(0, vttbr_el2);
>  }
>  
> +__alias(__tlb_flush_vmid_ipa)
> +void __weak __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
> +
>  void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
>  {
>   dsb(ishst);
> @@ -63,6 +66,9 @@ void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
>   write_sysreg(0, vttbr_el2);
>  }
>  
> +__alias(__tlb_flush_vmid)
> +void __weak __kvm_tlb_flush_vmid(struct kvm *kvm);
> +
>  void __hyp_text __tlb_flush_vm_context(void)
>  {
>   dsb(ishst);
> @@ -70,3 +76,6 @@ void __hyp_text __tlb_flush_vm_context(void)
>"ic ialluis  ": : );
>   dsb(ish);
>  }
> +
> +__alias(__tlb_flush_vm_context)
> +void __weak __kvm_flush_vm_context(void);
> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> index b490db5..1b0eedb 100644
> --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> @@ -220,3 +220,6 @@ u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void)
>  {
>   return read_gicreg(ICH_VTR_EL2);
>  }
> +
> +__alias(__vgic_v3_read_ich_vtr_el2)
> +u64 __weak __vgic_v3_get_ich_vtr_el2(void);
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 12/21] arm64: KVM: Implement fpsimd save/restore

2015-12-02 Thread Christoffer Dall
gt; --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -88,6 +88,7 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *host_ctxt;
>   struct kvm_cpu_context *guest_ctxt;
> + bool fp_enabled;
>   u64 exit_code;
>  
>   vcpu = kern_hyp_va(vcpu);
> @@ -117,6 +118,8 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>   exit_code = __guest_enter(vcpu, host_ctxt);
>   /* And we're baaack! */
>  
> + fp_enabled = __fpsimd_enabled();
> +

what does 'enabled' really mean here?  Isn't it really
__fpsimd_is_dirty() or __fpsimd_is_guest() or something like that (I
suck at naming too).

>   __sysreg_save_state(guest_ctxt);
>   __sysreg32_save_state(vcpu);
>   __timer_save_state(vcpu);
> @@ -127,6 +130,11 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>  
>   __sysreg_restore_state(host_ctxt);
>  
> + if (fp_enabled) {
> + __fpsimd_save_state(_ctxt->gp_regs.fp_regs);
> + __fpsimd_restore_state(_ctxt->gp_regs.fp_regs);
> + }
> +
>   __debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
>   __debug_cond_restore_host_state(vcpu);
>  
> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index 3f81a4d..41b9d30 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -103,7 +103,7 @@ void __hyp_text __sysreg32_save_state(struct kvm_vcpu 
> *vcpu)
>   sysreg[DACR32_EL2] = read_sysreg(dacr32_el2);
>   sysreg[IFSR32_EL2] = read_sysreg(ifsr32_el2);
>  
> - if (!(read_sysreg(cptr_el2) & CPTR_EL2_TFP))
> + if (__fpsimd_enabled())
>   sysreg[FPEXC32_EL2] = read_sysreg(fpexc32_el2);
>  
>   if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
> -- 
> 2.1.4
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 13/21] arm64: KVM: Implement TLB handling

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:07PM +, Marc Zyngier wrote:
> Implement the TLB handling as a direct translation of the assembly
> code version.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> ---
>  arch/arm64/kvm/hyp/Makefile |  1 +
>  arch/arm64/kvm/hyp/tlb.c| 72 
> +
>  2 files changed, 73 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/tlb.c
> 
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> index 56238d0..1a529f5 100644
> --- a/arch/arm64/kvm/hyp/Makefile
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += entry.o
>  obj-$(CONFIG_KVM_ARM_HOST) += switch.o
>  obj-$(CONFIG_KVM_ARM_HOST) += fpsimd.o
> +obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
> diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
> new file mode 100644
> index 000..d4a07d0
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/tlb.c
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright (C) 2015 - ARM Ltd
> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "hyp.h"
> +
> +void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
> +{
> + dsb(ishst);
> +
> + /* Switch to requested VMID */
> + kvm = kern_hyp_va(kvm);
> + write_sysreg(kvm->arch.vttbr, vttbr_el2);
> + isb();
> +
> + /*
> +  * We could do so much better if we had the VA as well.
> +  * Instead, we invalidate Stage-2 for this IPA, and the
> +  * whole of Stage-1. Weep...
> +  */
> + ipa >>= 12;
> + asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
> + dsb(ish);

nit: missing white space

> + /*
> +  * We have to ensure completion of the invalidation at Stage-2,
> +  * since a table walk on another CPU could refill a TLB with a
> +  * complete (S1 + S2) walk based on the old Stage-2 mapping if
> +  * the Stage-1 invalidation happened first.
> +  */

nit: isn't that comment targeting the dsb(ish) above as in the asm code
and should be moved above that line?

> + asm volatile("tlbi vmalle1is" : : );
> + dsb(ish);
> + isb();
> +
> + write_sysreg(0, vttbr_el2);
> +}
> +
> +void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
> +{
> + dsb(ishst);
> +
> + /* Switch to requested VMID */
> + kvm = kern_hyp_va(kvm);
> + write_sysreg(kvm->arch.vttbr, vttbr_el2);
> + isb();
> +
> + asm volatile("tlbi vmalls12e1is" : : );
> + dsb(ish);
> + isb();
> +
> + write_sysreg(0, vttbr_el2);
> +}
> +
> +void __hyp_text __tlb_flush_vm_context(void)
> +{
> + dsb(ishst);
> + asm volatile("tlbi alle1is  \n"
> +  "ic ialluis  ": : );
> + dsb(ish);
> +}
> -- 
> 2.1.4
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 15/21] arm64: KVM: Add panic handling

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:09PM +, Marc Zyngier wrote:
> Add the panic handler, together with the small bits of assembly
> code to call the kernel's panic implementation.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp-entry.S | 11 ++-
>  arch/arm64/kvm/hyp/hyp.h   |  1 +
>  arch/arm64/kvm/hyp/switch.c| 30 ++
>  3 files changed, 41 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index 8334407..39d6935 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -150,7 +150,16 @@ el1_irq:
>   mov x1, #ARM_EXCEPTION_IRQ
>   b   __guest_exit
>  
> -.macro invalid_vectorlabel, target = __kvm_hyp_panic
> +ENTRY(__hyp_do_panic)
> + mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
> +   PSR_MODE_EL1h)
> + msr spsr_el2, lr
> + ldr lr, =panic
> + msr elr_el2, lr
> + eret
> +ENDPROC(__hyp_do_panic)
> +
> +.macro invalid_vectorlabel, target = __hyp_panic
>   .align  2
>  \label:
>   b \target
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index 18365dd..87f16fa 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -74,6 +74,7 @@ static inline bool __fpsimd_enabled(void)
>  }
>  
>  u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
> +void __noreturn __hyp_do_panic(unsigned long, ...);
>  
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 8affc19..7b81089 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -140,3 +140,33 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>  
>   return exit_code;
>  }
> +
> +static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx 
> ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
> +
> +void __hyp_text __noreturn __hyp_panic(void)
> +{
> + unsigned long str_va = (unsigned long)__hyp_panic_string;
> + u64 spsr = read_sysreg(spsr_el2);
> + u64 elr = read_sysreg(elr_el2);
> + u64 par = read_sysreg(par_el1);
> +
> + if (read_sysreg(vttbr_el2)) {
> + struct kvm_vcpu *vcpu;
> + struct kvm_cpu_context *host_ctxt;
> +
> + vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2);
> + host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
> + __deactivate_traps(vcpu);
> + __deactivate_vm(vcpu);
> + __sysreg_restore_state(host_ctxt);
> + }
> +
> + /* Call panic for real */
> + __hyp_do_panic(str_va - HYP_PAGE_OFFSET + PAGE_OFFSET,

is the first parameter hyp_kern_va(str_va) ?  If so, can you add that
define instead?

> +spsr,  elr,
> +    read_sysreg(esr_el2),   read_sysreg(far_el2),
> +read_sysreg(hpfar_el2), par,
> +(void *)read_sysreg(tpidr_el2));
> +
> + unreachable();
> +}
> -- 
> 2.1.4
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 10/21] arm64: KVM: Add patchable function selector

2015-12-02 Thread Christoffer Dall
On Wed, Dec 02, 2015 at 09:47:43AM +, Marc Zyngier wrote:
> On 02/12/15 09:27, Christoffer Dall wrote:
> > On Tue, Dec 01, 2015 at 06:51:00PM +, Marc Zyngier wrote:
> >> On 01/12/15 15:39, Christoffer Dall wrote:
> >>> On Fri, Nov 27, 2015 at 06:50:04PM +, Marc Zyngier wrote:
> >>>> KVM so far relies on code patching, and is likely to use it more
> >>>> in the future. The main issue is that our alternative system works
> >>>> at the instruction level, while we'd like to have alternatives at
> >>>> the function level.
> >>>>
> >>>> In order to cope with this, add the "hyp_alternate_select" macro that
> >>>> outputs a brief sequence of code that in turn can be patched, allowing
> >>>> al alternative function to be selected.
> >>>
> >>> s/al/an/ ?
> >>>
> >>>>
> >>>> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >>>> ---
> >>>>  arch/arm64/kvm/hyp/hyp.h | 16 
> >>>>  1 file changed, 16 insertions(+)
> >>>>
> >>>> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >>>> index 7ac8e11..f0427ee 100644
> >>>> --- a/arch/arm64/kvm/hyp/hyp.h
> >>>> +++ b/arch/arm64/kvm/hyp/hyp.h
> >>>> @@ -27,6 +27,22 @@
> >>>>  
> >>>>  #define kern_hyp_va(v) (typeof(v))((unsigned long)v & 
> >>>> HYP_PAGE_OFFSET_MASK)
> >>>>  
> >>>> +/*
> >>>> + * Generates patchable code sequences that are used to switch between
> >>>> + * two implementations of a function, depending on the availability of
> >>>> + * a feature.
> >>>> + */
> >>>
> >>> This looks right to me, but I'm a bit unclear what the types of this is
> >>> and how to use it.
> >>>
> >>> Are orig and alt function pointers and cond is a CONFIG_FOO ?  fname is
> >>> a symbol, which is defined as a prototype somewhere and then implemented
> >>> here, or?
> >>>
> >>> Perhaps a Usage: part of the docs would be helpful.
> >>
> >> How about:
> >>
> >> @fname: a symbol name that will be defined as a function returning a
> >> function pointer whose type will match @orig and @alt
> >> @orig: A pointer to the default function, as returned by @fname when
> >> @cond doesn't hold
> >> @alt: A pointer to the alternate function, as returned by @fname when
> >> @cond holds
> >> @cond: a CPU feature (as described in asm/cpufeature.h)
> > 
> > looks good.
> > 
> >>
> >>>
> >>>> +#define hyp_alternate_select(fname, orig, alt, cond)
> >>>> \
> >>>> +typeof(orig) * __hyp_text fname(void)   
> >>>> \
> >>>> +{   
> >>>> \
> >>>> +typeof(alt) *val = orig;
> >>>> \
> >>>> +asm volatile(ALTERNATIVE("nop   \n",
> >>>> \
> >>>> + "mov   %0, %1  \n",
> >>>> \
> >>>> + cond)  
> >>>> \
> >>>> + : "+r" (val) : "r" (alt)); 
> >>>> \
> >>>> +return val; 
> >>>> \
> >>>> +}
> >>>> +
> >>>>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> >>>>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> >>>>  
> >>>> -- 
> >>>> 2.1.4
> >>>>
> >>>
> >>> I haven't thought much about how all of this is implemented, but from my
> >>> point of views the ideal situation would be something like:
> >>>
> >>> void foo(int a, int b)
> >>> {
> >>>   ALTERNATIVE_IF_NOT CONFIG_BAR
> >>>   foo_legacy(a, b);
> >>>   ALTERNATIVE_ELSE
> >>>   foo_new(a, b);
> >>>   ALTERNATIVE_END
> >>> }
> >>>
> >>> I realize this may be impossible because the 

Re: [PATCH v2 14/21] arm64: KVM: HYP mode entry points

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:08PM +, Marc Zyngier wrote:
> Add the entry points for HYP mode (both for hypercalls and
> exception handling).
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 21/21] arm64: KVM: Remove weak attributes

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:15PM +, Marc Zyngier wrote:
> As we've now switched to the new world switch implementation,
> remove the weak attributes, as nobody is supposed to override
> it anymore.

Why not remove the aliases and change the callers?

-Christoffer

> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/debug-sr.c   |  5 ++---
>  arch/arm64/kvm/hyp/hyp-entry.S  |  3 ---
>  arch/arm64/kvm/hyp/switch.c |  5 ++---
>  arch/arm64/kvm/hyp/tlb.c| 16 +++-
>  arch/arm64/kvm/hyp/vgic-v3-sr.c |  5 ++---
>  5 files changed, 13 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> index 774a3f69..747546b 100644
> --- a/arch/arm64/kvm/hyp/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> @@ -125,10 +125,9 @@ void __hyp_text __debug_cond_restore_host_state(struct 
> kvm_vcpu *vcpu)
>   }
>  }
>  
> -u32 __hyp_text __debug_read_mdcr_el2(void)
> +static u32 __hyp_text __debug_read_mdcr_el2(void)
>  {
>   return read_sysreg(mdcr_el2);
>  }
>  
> -__alias(__debug_read_mdcr_el2)
> -u32 __weak __kvm_get_mdcr_el2(void);
> +__alias(__debug_read_mdcr_el2) u32 __kvm_get_mdcr_el2(void);
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index ace919b..bbc0be1 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -184,9 +184,7 @@ ENDPROC(\label)
>  
>   .align 11
>  
> - .weak   __kvm_hyp_vector
>  ENTRY(__kvm_hyp_vector)
> -ENTRY(__hyp_vector)
>   ventry  el2t_sync_invalid   // Synchronous EL2t
>   ventry  el2t_irq_invalid// IRQ EL2t
>   ventry  el2t_fiq_invalid// FIQ EL2t
> @@ -206,5 +204,4 @@ ENTRY(__hyp_vector)
>   ventry  el1_irq // IRQ 32-bit EL1
>   ventry  el1_fiq_invalid // FIQ 32-bit EL1
>   ventry  el1_error_invalid   // Error 32-bit EL1
> -ENDPROC(__hyp_vector)
>  ENDPROC(__kvm_hyp_vector)
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index c8ba370..1154d66 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -84,7 +84,7 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu 
> *vcpu)
>   __vgic_call_restore_state()(vcpu);
>  }
>  
> -int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
> +static int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *host_ctxt;
>   struct kvm_cpu_context *guest_ctxt;
> @@ -141,8 +141,7 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
>   return exit_code;
>  }
>  
> -__alias(__guest_run)
> -int __weak __kvm_vcpu_run(struct kvm_vcpu *vcpu);
> +__alias(__guest_run) int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
>  
>  static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx 
> ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
>  
> diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
> index 2c279a8..250e06c 100644
> --- a/arch/arm64/kvm/hyp/tlb.c
> +++ b/arch/arm64/kvm/hyp/tlb.c
> @@ -17,7 +17,7 @@
>  
>  #include "hyp.h"
>  
> -void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
> +static void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
>  {
>   dsb(ishst);
>  
> @@ -47,10 +47,10 @@ void __hyp_text __tlb_flush_vmid_ipa(struct kvm *kvm, 
> phys_addr_t ipa)
>   write_sysreg(0, vttbr_el2);
>  }
>  
> -__alias(__tlb_flush_vmid_ipa)
> -void __weak __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
> +__alias(__tlb_flush_vmid_ipa) void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm,
> + phys_addr_t ipa);
>  
> -void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
> +static void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
>  {
>   dsb(ishst);
>  
> @@ -66,10 +66,9 @@ void __hyp_text __tlb_flush_vmid(struct kvm *kvm)
>   write_sysreg(0, vttbr_el2);
>  }
>  
> -__alias(__tlb_flush_vmid)
> -void __weak __kvm_tlb_flush_vmid(struct kvm *kvm);
> +__alias(__tlb_flush_vmid) void __kvm_tlb_flush_vmid(struct kvm *kvm);
>  
> -void __hyp_text __tlb_flush_vm_context(void)
> +static void __hyp_text __tlb_flush_vm_context(void)
>  {
>   dsb(ishst);
>   asm volatile("tlbi alle1is  \n"
> @@ -77,5 +76,4 @@ void __hyp_text __tlb_flush_vm_context(void)
>   dsb(ish);
>  }
>  
> -__alias(__tlb_flush_vm_context)
> -void __weak __kvm_flush_vm_context(void);
> +__alias(__tlb_flush_vm_context) void __kvm_flush_vm_context(void);
> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> index 1b0eedb..82a4f4b 100644
> --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> @@ -216,10 +216,9 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu 
> *vcpu)
>   }
>  }
>  
> -u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void)
> +static u64 __hyp_text 

Re: [PATCH v2 20/21] arm64: KVM: Cleanup asm-offset.c

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:14PM +, Marc Zyngier wrote:
> As we've now rewritten most of our code-base in C, most of the
> KVM-specific code in asm-offset.c is useless. Delete-time again!
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 19/21] arm64: KVM: Turn system register numbers to an enum

2015-12-02 Thread Christoffer Dall
FSET(x) (CPU_GP_REGS + x)
>  #define CPU_XREG_OFFSET(x)   CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
> -#define CPU_SYSREG_OFFSET(x) (CPU_SYSREGS + 8*x)
>  
>   .text
>   .pushsection.hyp.text, "ax"
> @@ -174,7 +173,7 @@ ENTRY(__fpsimd_guest_restore)
>  
>   mrs x1, hcr_el2
>   tbnzx1, #HCR_RW_SHIFT, 1f
> - ldr x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
> + ldr     x4, [x3, #VCPU_FPEXC32_EL2]
>   msr fpexc32_el2, x4
>  1:
>   pop x4, lr
> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index 41b9d30..b893c45 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  
>  #include "hyp.h"
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 87a64e8..0db5311 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
> index 487d635..c8506a2 100644
> --- a/virt/kvm/arm/vgic-v3.c
> +++ b/virt/kvm/arm/vgic-v3.c
> @@ -28,6 +28,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  /* These are for GICv2 emulation only */
> -- 
> 2.1.4
> 

Apart from the comment:

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 18/21] arm64: KVM: Move away from the assembly version of the world switch

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:12PM +, Marc Zyngier wrote:
> This is it. We remove all of the code that has now been rewritten.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 17/21] arm64: KVM: Map the kernel RO section into HYP

2015-12-02 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:11PM +, Marc Zyngier wrote:
> In order to run C code in HYP, we must make sure that the kernel's
> RO section in mapped into HYP (otherwise things break badly).
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>

Acked-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 00/21] arm64: KVM: world switch in C

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 05:51:46PM +, Marc Zyngier wrote:
> On 01/12/15 12:00, Christoffer Dall wrote:
> > On Tue, Dec 01, 2015 at 09:58:23AM +, Marc Zyngier wrote:
> >> On 30/11/15 20:33, Christoffer Dall wrote:
> >>> On Fri, Nov 27, 2015 at 06:49:54PM +, Marc Zyngier wrote:
> >>>> Once upon a time, the KVM/arm64 world switch was a nice, clean, lean
> >>>> and mean piece of hand-crafted assembly code. Over time, features have
> >>>> crept in, the code has become harder to maintain, and the smallest
> >>>> change is a pain to introduce. The VHE patches are a prime example of
> >>>> why this doesn't work anymore.
> >>>>
> >>>> This series rewrites most of the existing assembly code in C, but keeps
> >>>> the existing code structure in place (most function names will look
> >>>> familiar to the reader). The biggest change is that we don't have to
> >>>> deal with a static register allocation (the compiler does it for us),
> >>>> we can easily follow structure and pointers, and only the lowest level
> >>>> is still in assembly code. Oh, and a negative diffstat.
> >>>>
> >>>> There is still a healthy dose of inline assembly (system register
> >>>> accessors, runtime code patching), but I've tried not to make it too
> >>>> invasive. The generated code, while not exactly brilliant, doesn't
> >>>> look too shaby. I do expect a small performance degradation, but I
> >>>> believe this is something we can improve over time (my initial
> >>>> measurements don't show any obvious regression though).
> >>>
> >>> I ran this through my experimental setup on m400 and got this:
> >>
> >> [...]
> >>
> >>> What this tells me is that we do take a noticable hit on the
> >>> world-switch path, which shows up in the TCP_RR and hackbench workloads,
> >>> which have a high precision in their output.
> >>>
> >>> Note that the memcached number is well within its variability between
> >>> individual benchmark runs, where it varies to 12% of its average in over
> >>> 80% of the executions.
> >>>
> >>> I don't think this is a showstopper thought, but we could consider
> >>> looking more closely at a breakdown of the world-switch path and verify
> >>> if/where we are really taking a hit.
> >>
> >> Thanks for doing so, very interesting. As a data point, what compiler
> >> are you using? I'd expect some variability based on the compiler version...
> >>
> > I used the following (compiling natively on the m400):
> > 
> > gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1)
> 
> For what it is worth, I've ran hackbench on my Seattle B0 (8xA57 2GHz),
> with a 4 vcpu VM and got the following results (10 runs per kernel
> version, same configuration):
> 
> v4.4-rc3-wsinc: Average 31.750
> 32.459
> 32.124
> 32.435
> 31.940
> 31.085
> 31.804
> 31.862
> 30.985
> 31.450
> 31.359
> 
> v4.4-rc3: Average 31.954
> 31.806
> 31.598
> 32.697
> 31.472
> 31.410
> 32.562
> 31.938
> 31.932
> 31.672
> 32.459
> 
> This is with GCC as produced by Linaro:
> aarch64-linux-gnu-gcc (Linaro GCC 5.1-2015.08) 5.1.1 20150608
> 
> It could well be that your compiler generates worse code than the one I
> use, or that the code it outputs is badly tuned for XGene. I guess I
> need to unearth my Mustang to find out...
> 
Worth investigating I suppose.  At any rate, the conclusion stays the
same; we should proceed with these patches.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 09/21] arm64: KVM: Implement guest entry

2015-12-01 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:03PM +, Marc Zyngier wrote:
> Contrary to the previous patch, the guest entry is fairly different
> from its assembly counterpart, mostly because it is only concerned
> with saving/restoring the GP registers, and nothing else.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/Makefile |   1 +
>  arch/arm64/kvm/hyp/entry.S  | 155 
> 
>  arch/arm64/kvm/hyp/hyp.h|   2 +
>  3 files changed, 158 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/entry.S
> 
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> index ec14cac..1e1ff06 100644
> --- a/arch/arm64/kvm/hyp/Makefile
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> +obj-$(CONFIG_KVM_ARM_HOST) += entry.o
> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> new file mode 100644
> index 000..2c4449a
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/entry.S
> @@ -0,0 +1,155 @@
> +/*
> + * Copyright (C) 2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x)
> +#define CPU_XREG_OFFSET(x)   CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
> +
> + .text
> + .pushsection.hyp.text, "ax"
> +
> +.macro save_common_regs ctxt
> + stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
> + stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
> + stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
> + stp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
> + stp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
> + stp x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
> +.endm
> +
> +.macro restore_common_regs ctxt
> + ldp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
> + ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
> + ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
> + ldp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
> + ldp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
> + ldp x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
> +.endm
> +
> +.macro save_host_regs reg
> + save_common_regs \reg
> +.endm
> +
> +.macro restore_host_regs reg
> + restore_common_regs \reg
> +.endm
> +
> +.macro save_guest_regs
> + // x0 is the vcpu address
> + // x1 is the return code, do not corrupt!
> + // x2 is the cpu context

this is confusing because the caller says x2 is free, so are these the
inputs or invariants preserved in the function, or?

note that you'll avoid this kind of confusion by inlining this stuff in
__guest_exit.

> + // x3 is a tmp register
> + // Guest's x0-x3 are on the stack
> +
> + add x2, x0, #VCPU_CONTEXT
> +
> + // Compute base to save registers

misleading comment?

> + stp x4, x5,   [x2, #CPU_XREG_OFFSET(4)]
> + stp x6, x7,   [x2, #CPU_XREG_OFFSET(6)]
> + stp x8, x9,   [x2, #CPU_XREG_OFFSET(8)]
> + stp x10, x11, [x2, #CPU_XREG_OFFSET(10)]
> + stp x12, x13, [x2, #CPU_XREG_OFFSET(12)]
> + stp x14, x15, [x2, #CPU_XREG_OFFSET(14)]
> + stp x16, x17, [x2, #CPU_XREG_OFFSET(16)]
> + str x18,  [x2, #CPU_XREG_OFFSET(18)]
> +
> + pop x6, x7  // x2, x3
> + pop x4, x5  // x0, x1

hard to review when I haven't seen the code that calls this, but I'll
assume we store things in register order on the stack.

> +
> + stp x4, x5, [x2, #CPU_XREG_OFFSET(0)]
> + stp x6, x7, [x2, #CPU_XREG_OFFSET(2)]
> +
> + save_common_regs x2
> +.endm
> +
> +.macro restore_guest_regs
> + // Assume vcpu in x0, clobbers everything else

nit: clobbers everything (x0 gets nuked too)

> +
> + add x2, x0, #VCPU_CONTEXT
> +
> + // Prepare x0-x3 for later restore
> + ldp x4, x5, [x2, #CPU_XREG_OFFSET(0)]
> + ldp x6, x7, [x2, #CPU_XREG_OFFSET(2)]
> + pushx4, x5  // Push x0-x3 on the stack
> + pushx6, x7

why do you need x2 and x3 later? can't you just make do with x0 and x1
and move the cpu context pointer to x1 ?

> +
> + // x4-x18
> + 

Re: [PATCH v2 10/21] arm64: KVM: Add patchable function selector

2015-12-01 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:04PM +, Marc Zyngier wrote:
> KVM so far relies on code patching, and is likely to use it more
> in the future. The main issue is that our alternative system works
> at the instruction level, while we'd like to have alternatives at
> the function level.
> 
> In order to cope with this, add the "hyp_alternate_select" macro that
> outputs a brief sequence of code that in turn can be patched, allowing
> al alternative function to be selected.

s/al/an/ ?

> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/hyp.h | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index 7ac8e11..f0427ee 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -27,6 +27,22 @@
>  
>  #define kern_hyp_va(v) (typeof(v))((unsigned long)v & HYP_PAGE_OFFSET_MASK)
>  
> +/*
> + * Generates patchable code sequences that are used to switch between
> + * two implementations of a function, depending on the availability of
> + * a feature.
> + */

This looks right to me, but I'm a bit unclear what the types of this is
and how to use it.

Are orig and alt function pointers and cond is a CONFIG_FOO ?  fname is
a symbol, which is defined as a prototype somewhere and then implemented
here, or?

Perhaps a Usage: part of the docs would be helpful.


> +#define hyp_alternate_select(fname, orig, alt, cond) \
> +typeof(orig) * __hyp_text fname(void)
> \
> +{\
> + typeof(alt) *val = orig;\
> + asm volatile(ALTERNATIVE("nop   \n",\
> +  "mov   %0, %1  \n",\
> +  cond)  \
> +  : "+r" (val) : "r" (alt)); \
> + return val; \
> +}
> +
>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
>  
> -- 
> 2.1.4
> 

I haven't thought much about how all of this is implemented, but from my
point of views the ideal situation would be something like:

void foo(int a, int b)
{
ALTERNATIVE_IF_NOT CONFIG_BAR
foo_legacy(a, b);
ALTERNATIVE_ELSE
foo_new(a, b);
ALTERNATIVE_END
}

I realize this may be impossible because the C code could implement all
sort of fun stuff around the actual function calls, but would there be
some way to annotate the functions and find the actual branch statement
and change the target?

Apologies if this question is just outright ridiculous.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 08/21] arm64: KVM: Implement debug save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 03:01:16PM +, Marc Zyngier wrote:
> On 01/12/15 14:47, Christoffer Dall wrote:
> > On Tue, Dec 01, 2015 at 01:06:31PM +, Marc Zyngier wrote:
> >> On 01/12/15 12:56, Christoffer Dall wrote:
> >>> On Fri, Nov 27, 2015 at 06:50:02PM +, Marc Zyngier wrote:
> >>>> Implement the debug save restore as a direct translation of
> >>>> the assembly code version.
> >>>>
> >>>> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >>>> ---
> >>>>  arch/arm64/kvm/hyp/Makefile   |   1 +
> >>>>  arch/arm64/kvm/hyp/debug-sr.c | 130 
> >>>> ++
> >>>>  arch/arm64/kvm/hyp/hyp.h  |   9 +++
> >>>>  3 files changed, 140 insertions(+)
> >>>>  create mode 100644 arch/arm64/kvm/hyp/debug-sr.c
> >>>>
> >>>> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> >>>> index ec94200..ec14cac 100644
> >>>> --- a/arch/arm64/kvm/hyp/Makefile
> >>>> +++ b/arch/arm64/kvm/hyp/Makefile
> >>>> @@ -6,3 +6,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> >>>>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> >>>>  obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
> >>>>  obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
> >>>> +obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> >>>> diff --git a/arch/arm64/kvm/hyp/debug-sr.c 
> >>>> b/arch/arm64/kvm/hyp/debug-sr.c
> >>>> new file mode 100644
> >>>> index 000..a0b2b99
> >>>> --- /dev/null
> >>>> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> >>>> @@ -0,0 +1,130 @@
> >>>> +/*
> >>>> + * Copyright (C) 2015 - ARM Ltd
> >>>> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >>>> + *
> >>>> + * This program is free software; you can redistribute it and/or modify
> >>>> + * it under the terms of the GNU General Public License version 2 as
> >>>> + * published by the Free Software Foundation.
> >>>> + *
> >>>> + * This program is distributed in the hope that it will be useful,
> >>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>>> + * GNU General Public License for more details.
> >>>> + *
> >>>> + * You should have received a copy of the GNU General Public License
> >>>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >>>> + */
> >>>> +
> >>>> +#include 
> >>>> +#include 
> >>>> +
> >>>> +#include 
> >>>> +
> >>>> +#include "hyp.h"
> >>>> +
> >>>> +#define read_debug(r,n) read_sysreg(r##n##_el1)
> >>>> +#define write_debug(v,r,n)  write_sysreg(v, r##n##_el1)
> >>>> +
> >>>> +#define save_debug(ptr,reg,nr)  
> >>>> \
> >>>> +switch (nr) {   
> >>>> \
> >>>> +case 15:ptr[15] = read_debug(reg, 15);  
> >>>> \
> >>>> +case 14:ptr[14] = read_debug(reg, 14);  
> >>>> \
> >>>> +case 13:ptr[13] = read_debug(reg, 13);  
> >>>> \
> >>>> +case 12:ptr[12] = read_debug(reg, 12);  
> >>>> \
> >>>> +case 11:ptr[11] = read_debug(reg, 11);  
> >>>> \
> >>>> +case 10:ptr[10] = read_debug(reg, 10);  
> >>>> \
> >>>> +case 9: ptr[9] = read_debug(reg, 9);
> >>>> \
> >>>> +case 8: ptr[8] = read_debug(reg, 8);
> >>>> \
> >>>> +case 7: ptr[7] = read_debug(reg, 7);
> >>>> \
> >>>> +case 6: ptr[6] = read_debug(reg, 6);
> >>>> \
> >>>> +case 5: ptr[5] = read_debug(reg, 5);
> >>>> \
> >>>> +case 

Re: [PATCH v2 07/21] arm64: KVM: Implement 32bit system register save/restore

2015-12-01 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:01PM +, Marc Zyngier wrote:
> Implement the 32bit system register save restore as a direct
> translation of the assembly code version.
> 
> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp.h   |  2 ++
>  arch/arm64/kvm/hyp/sysreg-sr.c | 41 +
>  2 files changed, 43 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index 087d3a5..4639330 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -38,6 +38,8 @@ void __timer_restore_state(struct kvm_vcpu *vcpu);
>  
>  void __sysreg_save_state(struct kvm_cpu_context *ctxt);
>  void __sysreg_restore_state(struct kvm_cpu_context *ctxt);
> +void __sysreg32_save_state(struct kvm_vcpu *vcpu);
> +void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
>  
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
> index add8fcb..3f81a4d 100644
> --- a/arch/arm64/kvm/hyp/sysreg-sr.c
> +++ b/arch/arm64/kvm/hyp/sysreg-sr.c
> @@ -88,3 +88,44 @@ void __hyp_text __sysreg_restore_state(struct 
> kvm_cpu_context *ctxt)
>   write_sysreg(ctxt->gp_regs.elr_el1, elr_el1);
>   write_sysreg(ctxt->gp_regs.spsr[KVM_SPSR_EL1], spsr_el1);
>  }
> +
> +void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
> +{
> + if (!(read_sysreg(hcr_el2) & HCR_RW)) {

nit: I would probably invert the check and return early.

> + u64 *spsr = vcpu->arch.ctxt.gp_regs.spsr;
> + u64 *sysreg = vcpu->arch.ctxt.sys_regs;
> +
> + spsr[KVM_SPSR_ABT] = read_sysreg(spsr_abt);
> + spsr[KVM_SPSR_UND] = read_sysreg(spsr_und);
> + spsr[KVM_SPSR_IRQ] = read_sysreg(spsr_irq);
> + spsr[KVM_SPSR_FIQ] = read_sysreg(spsr_fiq);
> +
> + sysreg[DACR32_EL2] = read_sysreg(dacr32_el2);
> + sysreg[IFSR32_EL2] = read_sysreg(ifsr32_el2);
> +
> + if (!(read_sysreg(cptr_el2) & CPTR_EL2_TFP))
> + sysreg[FPEXC32_EL2] = read_sysreg(fpexc32_el2);
> +
> + if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
> + sysreg[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
> + }
> +}
> +
> +void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
> +{
> + if (!(read_sysreg(hcr_el2) & HCR_RW)) {

same here

> + u64 *spsr = vcpu->arch.ctxt.gp_regs.spsr;
> + u64 *sysreg = vcpu->arch.ctxt.sys_regs;
> +
> + write_sysreg(spsr[KVM_SPSR_ABT], spsr_abt);
> + write_sysreg(spsr[KVM_SPSR_UND], spsr_und);
> + write_sysreg(spsr[KVM_SPSR_IRQ], spsr_irq);
> + write_sysreg(spsr[KVM_SPSR_FIQ], spsr_fiq);
> +  

nit: white space

> + write_sysreg(sysreg[DACR32_EL2], dacr32_el2);
> + write_sysreg(sysreg[IFSR32_EL2], ifsr32_el2);
> +
> + if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
> + write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
> + }
> +}
> -- 
> 2.1.4
> 

Otherwise:

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 06/21] arm64: KVM: Implement system register save/restore

2015-12-01 Thread Christoffer Dall
; + write_sysreg(ctxt->sys_regs[SCTLR_EL1],   sctlr_el1);
> + write_sysreg(ctxt->sys_regs[ACTLR_EL1],   actlr_el1);
> + write_sysreg(ctxt->sys_regs[CPACR_EL1],   cpacr_el1);
> + write_sysreg(ctxt->sys_regs[TTBR0_EL1],   ttbr0_el1);
> + write_sysreg(ctxt->sys_regs[TTBR1_EL1],   ttbr1_el1);
> + write_sysreg(ctxt->sys_regs[TCR_EL1], tcr_el1);
> + write_sysreg(ctxt->sys_regs[ESR_EL1], esr_el1);
> + write_sysreg(ctxt->sys_regs[AFSR0_EL1],   afsr0_el1);
> + write_sysreg(ctxt->sys_regs[AFSR1_EL1],   afsr1_el1);
> + write_sysreg(ctxt->sys_regs[FAR_EL1], far_el1);
> + write_sysreg(ctxt->sys_regs[MAIR_EL1],mair_el1);
> + write_sysreg(ctxt->sys_regs[VBAR_EL1],vbar_el1);
> + write_sysreg(ctxt->sys_regs[CONTEXTIDR_EL1], contextidr_el1);
> + write_sysreg(ctxt->sys_regs[TPIDR_EL0],   tpidr_el0);
> + write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
> + write_sysreg(ctxt->sys_regs[TPIDR_EL1],   tpidr_el1);
> + write_sysreg(ctxt->sys_regs[AMAIR_EL1],   amair_el1);
> + write_sysreg(ctxt->sys_regs[CNTKCTL_EL1], cntkctl_el1);
> + write_sysreg(ctxt->sys_regs[PAR_EL1], par_el1);
> + write_sysreg(ctxt->sys_regs[MDSCR_EL1],   mdscr_el1);
> +
> + write_sysreg(ctxt->gp_regs.regs.sp, sp_el0);
> + write_sysreg(ctxt->gp_regs.regs.pc, elr_el2);
> + write_sysreg(ctxt->gp_regs.regs.pstate, spsr_el2);
> + write_sysreg(ctxt->gp_regs.sp_el1,  sp_el1);
> + write_sysreg(ctxt->gp_regs.elr_el1, elr_el1);
> + write_sysreg(ctxt->gp_regs.spsr[KVM_SPSR_EL1], spsr_el1);
> +}
> -- 
> 2.1.4
> 

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 11/21] arm64: KVM: Implement the core world switch

2015-12-01 Thread Christoffer Dall
sysreg(vcpu, tpidr_el2);
> +
> + host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
> + guest_ctxt = >arch.ctxt;
> +
> + __sysreg_save_state(host_ctxt);
> + __debug_cond_save_host_state(vcpu);
> +
> + __activate_traps(vcpu);
> + __activate_vm(vcpu);
> +
> + __vgic_restore_state(vcpu);
> + __timer_restore_state(vcpu);
> +
> + /*
> +  * We must restore the 32-bit state before the sysregs, thanks
> +  * to Cortex-A57 erratum #852523.
> +  */
> + __sysreg32_restore_state(vcpu);
> + __sysreg_restore_state(guest_ctxt);
> + __debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), 
> guest_ctxt);
> +
> + /* Jump in the fire! */
> + exit_code = __guest_enter(vcpu, host_ctxt);
> +     /* And we're baaack! */
> +
> + __sysreg_save_state(guest_ctxt);
> + __sysreg32_save_state(vcpu);
> + __timer_save_state(vcpu);
> + __vgic_save_state(vcpu);
> +
> + __deactivate_traps(vcpu);
> + __deactivate_vm(vcpu);
> +
> + __sysreg_restore_state(host_ctxt);
> +
> + __debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
> + __debug_cond_restore_host_state(vcpu);
> +
> + return exit_code;
> +}
> -- 
> 2.1.4
> 

Looks very nice!

Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 04/21] arm64: KVM: Implement vgic-v3 save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 12:44:26PM +0100, Christoffer Dall wrote:
> On Tue, Dec 01, 2015 at 11:32:20AM +, Marc Zyngier wrote:
> > On 30/11/15 19:50, Christoffer Dall wrote:
> > > On Fri, Nov 27, 2015 at 06:49:58PM +, Marc Zyngier wrote:
> > >> Implement the vgic-v3 save restore as a direct translation of
> > >> the assembly code version.
> > >>
> > >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> > >> ---
> > >>  arch/arm64/kvm/hyp/Makefile |   1 +
> > >>  arch/arm64/kvm/hyp/hyp.h|   3 +
> > >>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 222 
> > >> 
> > >>  3 files changed, 226 insertions(+)
> > >>  create mode 100644 arch/arm64/kvm/hyp/vgic-v3-sr.c
> > >>
> > >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> > >> index d8d5968..d1e38ce 100644
> > >> --- a/arch/arm64/kvm/hyp/Makefile
> > >> +++ b/arch/arm64/kvm/hyp/Makefile
> > >> @@ -3,3 +3,4 @@
> > >>  #
> > >>  
> > >>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> > >> +obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> > >> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> > >> index 78f25c4..a31cb6e 100644
> > >> --- a/arch/arm64/kvm/hyp/hyp.h
> > >> +++ b/arch/arm64/kvm/hyp/hyp.h
> > >> @@ -30,5 +30,8 @@
> > >>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> > >>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> > >>  
> > >> +void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
> > >> +void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
> > >> +
> > >>  #endif /* __ARM64_KVM_HYP_H__ */
> > >>  
> > >> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c 
> > >> b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> > >> new file mode 100644
> > >> index 000..b490db5
> > >> --- /dev/null
> > >> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> > >> @@ -0,0 +1,222 @@
> > >> +/*
> > >> + * Copyright (C) 2012-2015 - ARM Ltd
> > >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> > >> + *
> > >> + * This program is free software; you can redistribute it and/or modify
> > >> + * it under the terms of the GNU General Public License version 2 as
> > >> + * published by the Free Software Foundation.
> > >> + *
> > >> + * This program is distributed in the hope that it will be useful,
> > >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > >> + * GNU General Public License for more details.
> > >> + *
> > >> + * You should have received a copy of the GNU General Public License
> > >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> > >> + */
> > >> +
> > >> +#include 
> > >> +#include 
> > >> +#include 
> > >> +
> > >> +#include 
> > >> +
> > >> +#include "hyp.h"
> > >> +
> > >> +/*
> > >> + * We store LRs in reverse order to let the CPU deal with streaming
> > >> + * access. Use this macro to make it look saner...
> > >> + */
> > >> +#define LR_OFFSET(n)(15 - n)
> > >> +
> > >> +#define read_gicreg(r)  
> > >> \
> > >> +({  
> > >> \
> > >> +u64 reg;
> > >> \
> > >> +asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); 
> > >> \
> > >> +reg;
> > >> \
> > >> +})
> > >> +
> > >> +#define write_gicreg(v,r)   
> > >> \
> > >> +do {
> > >> \
> > >> +u64 __val = (v);
> > >> \
> > >> +asm volatile("msr_s " __stringify(r) ", %0" : : "r" 
> > 

Re: [PATCH v2 04/21] arm64: KVM: Implement vgic-v3 save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 11:32:20AM +, Marc Zyngier wrote:
> On 30/11/15 19:50, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:49:58PM +, Marc Zyngier wrote:
> >> Implement the vgic-v3 save restore as a direct translation of
> >> the assembly code version.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/Makefile |   1 +
> >>  arch/arm64/kvm/hyp/hyp.h|   3 +
> >>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 222 
> >> 
> >>  3 files changed, 226 insertions(+)
> >>  create mode 100644 arch/arm64/kvm/hyp/vgic-v3-sr.c
> >>
> >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> >> index d8d5968..d1e38ce 100644
> >> --- a/arch/arm64/kvm/hyp/Makefile
> >> +++ b/arch/arm64/kvm/hyp/Makefile
> >> @@ -3,3 +3,4 @@
> >>  #
> >>  
> >>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> >> +obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> >> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >> index 78f25c4..a31cb6e 100644
> >> --- a/arch/arm64/kvm/hyp/hyp.h
> >> +++ b/arch/arm64/kvm/hyp/hyp.h
> >> @@ -30,5 +30,8 @@
> >>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> >>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> >>  
> >> +void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
> >> +void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
> >> +
> >>  #endif /* __ARM64_KVM_HYP_H__ */
> >>  
> >> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c 
> >> b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> >> new file mode 100644
> >> index 000..b490db5
> >> --- /dev/null
> >> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> >> @@ -0,0 +1,222 @@
> >> +/*
> >> + * Copyright (C) 2012-2015 - ARM Ltd
> >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >> + */
> >> +
> >> +#include 
> >> +#include 
> >> +#include 
> >> +
> >> +#include 
> >> +
> >> +#include "hyp.h"
> >> +
> >> +/*
> >> + * We store LRs in reverse order to let the CPU deal with streaming
> >> + * access. Use this macro to make it look saner...
> >> + */
> >> +#define LR_OFFSET(n)  (15 - n)
> >> +
> >> +#define read_gicreg(r)
> >> \
> >> +  ({  \
> >> +  u64 reg;\
> >> +  asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
> >> +  reg;\
> >> +  })
> >> +
> >> +#define write_gicreg(v,r) \
> >> +  do {\
> >> +  u64 __val = (v);\
> >> +  asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
> >> +  } while (0)
> > 
> > remind me what the msr_s and mrs_s do compared to msr and mrs?
> 
> They do the same job, only for the system registers which are not in the
> original ARMv8 architecture spec, and most likely not implemented by
> old(er) compilers.
> 
> > are these the reason why we need separate macros to access the gic
> > registers compared to 'normal' sysregs?
> 
> Indeed.
> 
> >> +
> >> +/* vcpu is already in the HYP VA space */
> >> +void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
> >> +{
> >> +  struct vgic_v3_cpu_if *cpu_if = >arch.vgic_cpu.vgic_v3;
>

Re: [PATCH v2 08/21] arm64: KVM: Implement debug save/restore

2015-12-01 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:50:02PM +, Marc Zyngier wrote:
> Implement the debug save restore as a direct translation of
> the assembly code version.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/Makefile   |   1 +
>  arch/arm64/kvm/hyp/debug-sr.c | 130 
> ++
>  arch/arm64/kvm/hyp/hyp.h  |   9 +++
>  3 files changed, 140 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/debug-sr.c
> 
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> index ec94200..ec14cac 100644
> --- a/arch/arm64/kvm/hyp/Makefile
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
> +obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> new file mode 100644
> index 000..a0b2b99
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> @@ -0,0 +1,130 @@
> +/*
> + * Copyright (C) 2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "hyp.h"
> +
> +#define read_debug(r,n)  read_sysreg(r##n##_el1)
> +#define write_debug(v,r,n)   write_sysreg(v, r##n##_el1)
> +
> +#define save_debug(ptr,reg,nr)   
> \
> + switch (nr) {   \
> + case 15:ptr[15] = read_debug(reg, 15);  \
> + case 14:ptr[14] = read_debug(reg, 14);  \
> + case 13:ptr[13] = read_debug(reg, 13);  \
> + case 12:ptr[12] = read_debug(reg, 12);  \
> + case 11:ptr[11] = read_debug(reg, 11);  \
> + case 10:ptr[10] = read_debug(reg, 10);  \
> + case 9: ptr[9] = read_debug(reg, 9);\
> + case 8: ptr[8] = read_debug(reg, 8);\
> + case 7: ptr[7] = read_debug(reg, 7);\
> + case 6: ptr[6] = read_debug(reg, 6);\
> + case 5: ptr[5] = read_debug(reg, 5);\
> + case 4: ptr[4] = read_debug(reg, 4);\
> + case 3: ptr[3] = read_debug(reg, 3);\
> + case 2: ptr[2] = read_debug(reg, 2);\
> + case 1: ptr[1] = read_debug(reg, 1);\
> + default:ptr[0] = read_debug(reg, 0);\
> + }
> +
> +#define restore_debug(ptr,reg,nr)\
> + switch (nr) {   \
> + case 15:write_debug(ptr[15], reg, 15);  \
> + case 14:write_debug(ptr[14], reg, 14);  \
> + case 13:write_debug(ptr[13], reg, 13);  \
> + case 12:write_debug(ptr[12], reg, 12);  \
> + case 11:write_debug(ptr[11], reg, 11);  \
> + case 10:write_debug(ptr[10], reg, 10);  \
> + case 9: write_debug(ptr[9], reg, 9);\
> + case 8: write_debug(ptr[8], reg, 8);\
> + case 7: write_debug(ptr[7], reg, 7);\
> + case 6: write_debug(ptr[6], reg, 6);\
> + case 5: write_debug(ptr[5], reg, 5);\
> + case 4: write_debug(ptr[4], reg, 4);\
> + case 3: write_debug(ptr[3], reg, 3);\
> + case 2: write_debug(ptr[2], reg, 2);\
> + case 1: write_debug(ptr[1], reg, 1);\
> + default:write_debug(ptr[0], reg, 0);\
> + }
> +
> +void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
> +struct kvm_guest_debug_arch *dbg,
> +struct kvm_cpu_context *ctxt)
> +{
> + if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY) {
> + u64 

Re: [PATCH v2 00/21] arm64: KVM: world switch in C

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 09:58:23AM +, Marc Zyngier wrote:
> On 30/11/15 20:33, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:49:54PM +, Marc Zyngier wrote:
> >> Once upon a time, the KVM/arm64 world switch was a nice, clean, lean
> >> and mean piece of hand-crafted assembly code. Over time, features have
> >> crept in, the code has become harder to maintain, and the smallest
> >> change is a pain to introduce. The VHE patches are a prime example of
> >> why this doesn't work anymore.
> >>
> >> This series rewrites most of the existing assembly code in C, but keeps
> >> the existing code structure in place (most function names will look
> >> familiar to the reader). The biggest change is that we don't have to
> >> deal with a static register allocation (the compiler does it for us),
> >> we can easily follow structure and pointers, and only the lowest level
> >> is still in assembly code. Oh, and a negative diffstat.
> >>
> >> There is still a healthy dose of inline assembly (system register
> >> accessors, runtime code patching), but I've tried not to make it too
> >> invasive. The generated code, while not exactly brilliant, doesn't
> >> look too shaby. I do expect a small performance degradation, but I
> >> believe this is something we can improve over time (my initial
> >> measurements don't show any obvious regression though).
> > 
> > I ran this through my experimental setup on m400 and got this:
> 
> [...]
> 
> > What this tells me is that we do take a noticable hit on the
> > world-switch path, which shows up in the TCP_RR and hackbench workloads,
> > which have a high precision in their output.
> > 
> > Note that the memcached number is well within its variability between
> > individual benchmark runs, where it varies to 12% of its average in over
> > 80% of the executions.
> > 
> > I don't think this is a showstopper thought, but we could consider
> > looking more closely at a breakdown of the world-switch path and verify
> > if/where we are really taking a hit.
> 
> Thanks for doing so, very interesting. As a data point, what compiler
> are you using? I'd expect some variability based on the compiler version...
> 
I used the following (compiling natively on the m400):

gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1)


-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 04/21] arm64: KVM: Implement vgic-v3 save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 11:57:16AM +, Marc Zyngier wrote:
> On 01/12/15 11:50, Christoffer Dall wrote:
> > On Tue, Dec 01, 2015 at 12:44:26PM +0100, Christoffer Dall wrote:
> >> On Tue, Dec 01, 2015 at 11:32:20AM +, Marc Zyngier wrote:
> >>> On 30/11/15 19:50, Christoffer Dall wrote:
> >>>> On Fri, Nov 27, 2015 at 06:49:58PM +, Marc Zyngier wrote:
> >>>>> Implement the vgic-v3 save restore as a direct translation of
> >>>>> the assembly code version.
> >>>>>
> >>>>> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >>>>> ---
> >>>>>  arch/arm64/kvm/hyp/Makefile |   1 +
> >>>>>  arch/arm64/kvm/hyp/hyp.h|   3 +
> >>>>>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 222 
> >>>>> 
> >>>>>  3 files changed, 226 insertions(+)
> >>>>>  create mode 100644 arch/arm64/kvm/hyp/vgic-v3-sr.c
> >>>>>
> >>>>> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> >>>>> index d8d5968..d1e38ce 100644
> >>>>> --- a/arch/arm64/kvm/hyp/Makefile
> >>>>> +++ b/arch/arm64/kvm/hyp/Makefile
> >>>>> @@ -3,3 +3,4 @@
> >>>>>  #
> >>>>>  
> >>>>>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> >>>>> +obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> >>>>> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >>>>> index 78f25c4..a31cb6e 100644
> >>>>> --- a/arch/arm64/kvm/hyp/hyp.h
> >>>>> +++ b/arch/arm64/kvm/hyp/hyp.h
> >>>>> @@ -30,5 +30,8 @@
> >>>>>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> >>>>>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> >>>>>  
> >>>>> +void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
> >>>>> +void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
> >>>>> +
> >>>>>  #endif /* __ARM64_KVM_HYP_H__ */
> >>>>>  
> >>>>> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c 
> >>>>> b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> >>>>> new file mode 100644
> >>>>> index 000..b490db5
> >>>>> --- /dev/null
> >>>>> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> >>>>> @@ -0,0 +1,222 @@
> >>>>> +/*
> >>>>> + * Copyright (C) 2012-2015 - ARM Ltd
> >>>>> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >>>>> + *
> >>>>> + * This program is free software; you can redistribute it and/or modify
> >>>>> + * it under the terms of the GNU General Public License version 2 as
> >>>>> + * published by the Free Software Foundation.
> >>>>> + *
> >>>>> + * This program is distributed in the hope that it will be useful,
> >>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>>>> + * GNU General Public License for more details.
> >>>>> + *
> >>>>> + * You should have received a copy of the GNU General Public License
> >>>>> + * along with this program.  If not, see 
> >>>>> <http://www.gnu.org/licenses/>.
> >>>>> + */
> >>>>> +
> >>>>> +#include 
> >>>>> +#include 
> >>>>> +#include 
> >>>>> +
> >>>>> +#include 
> >>>>> +
> >>>>> +#include "hyp.h"
> >>>>> +
> >>>>> +/*
> >>>>> + * We store LRs in reverse order to let the CPU deal with streaming
> >>>>> + * access. Use this macro to make it look saner...
> >>>>> + */
> >>>>> +#define LR_OFFSET(n)   (15 - n)
> >>>>> +
> >>>>> +#define read_gicreg(r) 
> >>>>> \
> >>>>> +   ({  
> >>>>> \
> >>>>> +   u64 reg;
> >>>>> \
> >>>>> +   asm volatile(

Re: [PATCH v2 02/21] arm64: KVM: Add a HYP-specific header file

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 11:41:08AM +, Marc Zyngier wrote:
> On 30/11/15 20:00, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:49:56PM +, Marc Zyngier wrote:
> >> In order to expose the various EL2 services that are private to
> >> the hypervisor, add a new hyp.h file.
> >>
> >> So far, it only contains mundane things such as section annotation
> >> and VA manipulation.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/hyp.h | 31 +++
> >>  1 file changed, 31 insertions(+)
> >>  create mode 100644 arch/arm64/kvm/hyp/hyp.h
> >>
> >> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> >> new file mode 100644
> >> index 000..dac843e
> >> --- /dev/null
> >> +++ b/arch/arm64/kvm/hyp/hyp.h
> >> @@ -0,0 +1,31 @@
> >> +/*
> >> + * Copyright (C) 2015 - ARM Ltd
> >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >> + */
> >> +
> >> +#ifndef __ARM64_KVM_HYP_H__
> >> +#define __ARM64_KVM_HYP_H__
> >> +
> >> +#include 
> >> +#include 
> >> +#include 
> >> +#include 
> >> +
> >> +#define __hyp_text __section(.hyp.text) notrace
> > 
> > why notrace?
> 
> Because you'd end with calls to mcount in each function prologue, and
> that doesn't really well for stuff that is not executed in the kernel
> address space.

right, makes good sense.

> 
> >> +
> >> +#define kern_hyp_va(v) (typeof(v))((unsigned long)v & 
> >> HYP_PAGE_OFFSET_MASK)
> > 
> > should you have parenthesis around 'v' ?
> 
> Yup.
> 
> Thanks,
> 
>   M.
> -- 
> Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 08/21] arm64: KVM: Implement debug save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 01:06:31PM +, Marc Zyngier wrote:
> On 01/12/15 12:56, Christoffer Dall wrote:
> > On Fri, Nov 27, 2015 at 06:50:02PM +, Marc Zyngier wrote:
> >> Implement the debug save restore as a direct translation of
> >> the assembly code version.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/Makefile   |   1 +
> >>  arch/arm64/kvm/hyp/debug-sr.c | 130 
> >> ++
> >>  arch/arm64/kvm/hyp/hyp.h  |   9 +++
> >>  3 files changed, 140 insertions(+)
> >>  create mode 100644 arch/arm64/kvm/hyp/debug-sr.c
> >>
> >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> >> index ec94200..ec14cac 100644
> >> --- a/arch/arm64/kvm/hyp/Makefile
> >> +++ b/arch/arm64/kvm/hyp/Makefile
> >> @@ -6,3 +6,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
> >>  obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
> >> +obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> >> diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> >> new file mode 100644
> >> index 000..a0b2b99
> >> --- /dev/null
> >> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> >> @@ -0,0 +1,130 @@
> >> +/*
> >> + * Copyright (C) 2015 - ARM Ltd
> >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License version 2 as
> >> + * published by the Free Software Foundation.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >> + */
> >> +
> >> +#include 
> >> +#include 
> >> +
> >> +#include 
> >> +
> >> +#include "hyp.h"
> >> +
> >> +#define read_debug(r,n)   read_sysreg(r##n##_el1)
> >> +#define write_debug(v,r,n)write_sysreg(v, r##n##_el1)
> >> +
> >> +#define save_debug(ptr,reg,nr)
> >> \
> >> +  switch (nr) {   \
> >> +  case 15:ptr[15] = read_debug(reg, 15);  \
> >> +  case 14:ptr[14] = read_debug(reg, 14);  \
> >> +  case 13:ptr[13] = read_debug(reg, 13);  \
> >> +  case 12:ptr[12] = read_debug(reg, 12);  \
> >> +  case 11:ptr[11] = read_debug(reg, 11);  \
> >> +  case 10:ptr[10] = read_debug(reg, 10);  \
> >> +  case 9: ptr[9] = read_debug(reg, 9);\
> >> +  case 8: ptr[8] = read_debug(reg, 8);\
> >> +  case 7: ptr[7] = read_debug(reg, 7);\
> >> +  case 6: ptr[6] = read_debug(reg, 6);\
> >> +  case 5: ptr[5] = read_debug(reg, 5);\
> >> +  case 4: ptr[4] = read_debug(reg, 4);\
> >> +  case 3: ptr[3] = read_debug(reg, 3);\
> >> +  case 2: ptr[2] = read_debug(reg, 2);\
> >> +  case 1: ptr[1] = read_debug(reg, 1);\
> >> +  default:ptr[0] = read_debug(reg, 0);\
> >> +  }
> >> +
> >> +#define restore_debug(ptr,reg,nr) \
> >> +  switch (nr) {   \
> >> +  case 15:write_debug(ptr[15], reg, 15);  \
> >> +  case 14:write_debug(ptr[14], reg, 14);  \
> >> +  case 13:write_debug(ptr[13], reg, 13);  \
> >> +  case 12:write_debug(ptr[12], reg, 12);  \
> >> +  case 11:write_debug(ptr[11], reg, 11);  \
> >> +

Re: [PATCH v2 08/21] arm64: KVM: Implement debug save/restore

2015-12-01 Thread Christoffer Dall
On Tue, Dec 01, 2015 at 03:47:37PM +0100, Christoffer Dall wrote:
> On Tue, Dec 01, 2015 at 01:06:31PM +, Marc Zyngier wrote:
> > On 01/12/15 12:56, Christoffer Dall wrote:
> > > On Fri, Nov 27, 2015 at 06:50:02PM +, Marc Zyngier wrote:
> > >> Implement the debug save restore as a direct translation of
> > >> the assembly code version.
> > >>
> > >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
> > >> ---
> > >>  arch/arm64/kvm/hyp/Makefile   |   1 +
> > >>  arch/arm64/kvm/hyp/debug-sr.c | 130 
> > >> ++
> > >>  arch/arm64/kvm/hyp/hyp.h  |   9 +++
> > >>  3 files changed, 140 insertions(+)
> > >>  create mode 100644 arch/arm64/kvm/hyp/debug-sr.c
> > >>
> > >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> > >> index ec94200..ec14cac 100644
> > >> --- a/arch/arm64/kvm/hyp/Makefile
> > >> +++ b/arch/arm64/kvm/hyp/Makefile
> > >> @@ -6,3 +6,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> > >>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> > >>  obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
> > >>  obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
> > >> +obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
> > >> diff --git a/arch/arm64/kvm/hyp/debug-sr.c 
> > >> b/arch/arm64/kvm/hyp/debug-sr.c
> > >> new file mode 100644
> > >> index 000..a0b2b99
> > >> --- /dev/null
> > >> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> > >> @@ -0,0 +1,130 @@
> > >> +/*
> > >> + * Copyright (C) 2015 - ARM Ltd
> > >> + * Author: Marc Zyngier <marc.zyng...@arm.com>
> > >> + *
> > >> + * This program is free software; you can redistribute it and/or modify
> > >> + * it under the terms of the GNU General Public License version 2 as
> > >> + * published by the Free Software Foundation.
> > >> + *
> > >> + * This program is distributed in the hope that it will be useful,
> > >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > >> + * GNU General Public License for more details.
> > >> + *
> > >> + * You should have received a copy of the GNU General Public License
> > >> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> > >> + */
> > >> +
> > >> +#include 
> > >> +#include 
> > >> +
> > >> +#include 
> > >> +
> > >> +#include "hyp.h"
> > >> +
> > >> +#define read_debug(r,n) read_sysreg(r##n##_el1)
> > >> +#define write_debug(v,r,n)  write_sysreg(v, r##n##_el1)
> > >> +
> > >> +#define save_debug(ptr,reg,nr)  
> > >> \
> > >> +switch (nr) {   
> > >> \
> > >> +case 15:ptr[15] = read_debug(reg, 15);  
> > >> \
> > >> +case 14:ptr[14] = read_debug(reg, 14);  
> > >> \
> > >> +case 13:ptr[13] = read_debug(reg, 13);  
> > >> \
> > >> +case 12:ptr[12] = read_debug(reg, 12);  
> > >> \
> > >> +case 11:ptr[11] = read_debug(reg, 11);  
> > >> \
> > >> +case 10:ptr[10] = read_debug(reg, 10);  
> > >> \
> > >> +case 9: ptr[9] = read_debug(reg, 9);
> > >> \
> > >> +case 8: ptr[8] = read_debug(reg, 8);
> > >> \
> > >> +case 7: ptr[7] = read_debug(reg, 7);
> > >> \
> > >> +case 6: ptr[6] = read_debug(reg, 6);
> > >> \
> > >> +case 5: ptr[5] = read_debug(reg, 5);
> > >> \
> > >> +case 4: ptr[4] = read_debug(reg, 4);
> > >> \
> > >> +case 3: ptr[3] = read_debug(reg, 3);
> > >> \
> > >> +case 2: ptr[2] = read_debug(reg, 2);
> &

Re: [PATCH v2 04/21] arm64: KVM: Implement vgic-v3 save/restore

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:58PM +, Marc Zyngier wrote:
> Implement the vgic-v3 save restore as a direct translation of
> the assembly code version.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/Makefile |   1 +
>  arch/arm64/kvm/hyp/hyp.h|   3 +
>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 222 
> 
>  3 files changed, 226 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/vgic-v3-sr.c
> 
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> index d8d5968..d1e38ce 100644
> --- a/arch/arm64/kvm/hyp/Makefile
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -3,3 +3,4 @@
>  #
>  
>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> +obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index 78f25c4..a31cb6e 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -30,5 +30,8 @@
>  void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
>  void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
>  
> +void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
> +void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
> +
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> new file mode 100644
> index 000..b490db5
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> @@ -0,0 +1,222 @@
> +/*
> + * Copyright (C) 2012-2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "hyp.h"
> +
> +/*
> + * We store LRs in reverse order to let the CPU deal with streaming
> + * access. Use this macro to make it look saner...
> + */
> +#define LR_OFFSET(n) (15 - n)
> +
> +#define read_gicreg(r)   
> \
> + ({  \
> + u64 reg;\
> + asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg)); \
> + reg;\
> + })
> +
> +#define write_gicreg(v,r)\
> + do {\
> + u64 __val = (v);\
> + asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
> + } while (0)

remind me what the msr_s and mrs_s do compared to msr and mrs?

are these the reason why we need separate macros to access the gic
registers compared to 'normal' sysregs?

> +
> +/* vcpu is already in the HYP VA space */
> +void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
> +{
> + struct vgic_v3_cpu_if *cpu_if = >arch.vgic_cpu.vgic_v3;
> + u64 val;
> + u32 nr_lr, nr_pri;
> +
> + /*
> +  * Make sure stores to the GIC via the memory mapped interface
> +  * are now visible to the system register interface.
> +  */
> + dsb(st);
> +
> + cpu_if->vgic_vmcr  = read_gicreg(ICH_VMCR_EL2);
> + cpu_if->vgic_misr  = read_gicreg(ICH_MISR_EL2);
> + cpu_if->vgic_eisr  = read_gicreg(ICH_EISR_EL2);
> + cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2);
> +
> + write_gicreg(0, ICH_HCR_EL2);
> + val = read_gicreg(ICH_VTR_EL2);
> + nr_lr = val & 0xf;

this is not technically nr_lr, it's max_lr or max_lr_idx or something
like that.

> + nr_pri = ((u32)val >> 29) + 1;

nit: nr_pri_bits

> +
> + switch (nr_lr) {
> + case 15:
> + cpu_if->vgic_lr[LR_OFFSET(15)] = read_gicreg(ICH_LR15_EL2);
> + case 14:
> + cpu_if->vgic_lr[LR_OFFSET(14)] = read_gicreg(ICH_LR14_EL2);
> + case 13:
> + cpu_if->vgic_lr[LR_OFFSET(13)] = read_gicreg(ICH_LR13_EL2);
> + case 12:
> + cpu_if->vgic_lr[LR_OFFSET(12)] = read_gicreg(ICH_LR12_EL2);
> + case 11:
> + cpu_if->vgic_lr[LR_OFFSET(11)] = read_gicreg(ICH_LR11_EL2);
> + case 10:
> + cpu_if->vgic_lr[LR_OFFSET(10)] = read_gicreg(ICH_LR10_EL2);
> + case 9:
> + cpu_if->vgic_lr[LR_OFFSET(9)] = read_gicreg(ICH_LR9_EL2);
> + case 8:
> + cpu_if->vgic_lr[LR_OFFSET(8)] = read_gicreg(ICH_LR8_EL2);
> + case 7:
> + 

Re: [PATCH v2 01/21] arm64: Add macros to read/write system registers

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:55PM +, Marc Zyngier wrote:
> From: Mark Rutland 
> 
> Rather than crafting custom macros for reading/writing each system
> register provide generics accessors, read_sysreg and write_sysreg, for
> this purpose.
> 
> Unlike read_cpuid, calls to read_exception_reg are never expected
> to be optimized away or replaced with synthetic values.

how does this comment about read_exception_reg relate to this patch?

> 
> Signed-off-by: Mark Rutland 
> Cc: Catalin Marinas 
> Cc: Marc Zyngier 
> Cc: Suzuki Poulose 
> Cc: Will Deacon 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/include/asm/sysreg.h | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index d48ab5b..c9c283a 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -20,6 +20,8 @@
>  #ifndef __ASM_SYSREG_H
>  #define __ASM_SYSREG_H
>  
> +#include 
> +
>  #include 
>  
>  /*
> @@ -208,6 +210,8 @@
>  
>  #else
>  
> +#include 
> +
>  asm(
>  ".irp
> num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n"
>  ".equ__reg_num_x\\num, \\num\n"
> @@ -232,6 +236,19 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
>   val |= set;
>   asm volatile("msr sctlr_el1, %0" : : "r" (val));
>  }
> +
> +#define read_sysreg(r) ({\
> + u64 __val;  \
> + asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
> + __val;  \
> +})
> +
> +#define write_sysreg(v, r) do {  \
> + u64 __val = (u64)v; \
> + asm volatile("msr " __stringify(r) ", %0"   \
> +  : : "r" (__val));  \
> +} while (0)
> +
>  #endif
>  
>  #endif   /* __ASM_SYSREG_H */
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 02/21] arm64: KVM: Add a HYP-specific header file

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:56PM +, Marc Zyngier wrote:
> In order to expose the various EL2 services that are private to
> the hypervisor, add a new hyp.h file.
> 
> So far, it only contains mundane things such as section annotation
> and VA manipulation.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/hyp.h | 31 +++
>  1 file changed, 31 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/hyp.h
> 
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> new file mode 100644
> index 000..dac843e
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (C) 2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#ifndef __ARM64_KVM_HYP_H__
> +#define __ARM64_KVM_HYP_H__
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define __hyp_text __section(.hyp.text) notrace

why notrace?

> +
> +#define kern_hyp_va(v) (typeof(v))((unsigned long)v & HYP_PAGE_OFFSET_MASK)

should you have parenthesis around 'v' ?

> +
> +#endif /* __ARM64_KVM_HYP_H__ */
> +
> -- 
> 2.1.4
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 03/21] arm64: KVM: Implement vgic-v2 save/restore

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:57PM +, Marc Zyngier wrote:
> Implement the vgic-v2 save restore (mostly) as a direct translation
> of the assembly code version.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/Makefile |  1 +
>  arch/arm64/kvm/hyp/Makefile |  5 +++
>  arch/arm64/kvm/hyp/hyp.h|  3 ++
>  arch/arm64/kvm/hyp/vgic-v2-sr.c | 89 
> +
>  4 files changed, 98 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/Makefile
>  create mode 100644 arch/arm64/kvm/hyp/vgic-v2-sr.c
> 
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 1949fe5..d31e4e5 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -10,6 +10,7 @@ KVM=../../../virt/kvm
>  ARM=../../../arch/arm/kvm
>  
>  obj-$(CONFIG_KVM_ARM_HOST) += kvm.o
> +obj-$(CONFIG_KVM_ARM_HOST) += hyp/
>  
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o 
> $(KVM)/eventfd.o $(KVM)/vfio.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> new file mode 100644
> index 000..d8d5968
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Makefile for Kernel-based Virtual Machine module, HYP part
> +#
> +
> +obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index dac843e..78f25c4 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -27,5 +27,8 @@
>  
>  #define kern_hyp_va(v) (typeof(v))((unsigned long)v & HYP_PAGE_OFFSET_MASK)
>  
> +void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> +void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);

should we call these flush/sync here now ?

> +
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> diff --git a/arch/arm64/kvm/hyp/vgic-v2-sr.c b/arch/arm64/kvm/hyp/vgic-v2-sr.c
> new file mode 100644
> index 000..29a5c1d
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/vgic-v2-sr.c
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright (C) 2012-2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "hyp.h"
> +
> +/* vcpu is already in the HYP VA space */

should we annotate hyp pointers similarly to __user or will that be
confusing when VHE enters the scene ?

> +void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> + struct vgic_v2_cpu_if *cpu_if = >arch.vgic_cpu.vgic_v2;
> + struct vgic_dist *vgic = >arch.vgic;
> + void __iomem *base = kern_hyp_va(vgic->vctrl_base);
> + u32 __iomem *lr_base;
> + u32 eisr0, eisr1, elrsr0, elrsr1;
> + int i = 0, nr_lr;
> +
> + if (!base)
> + return;
> +
> + nr_lr = vcpu->arch.vgic_cpu.nr_lr;
> + cpu_if->vgic_vmcr = readl_relaxed(base + GICH_VMCR);
> + cpu_if->vgic_misr = readl_relaxed(base + GICH_MISR);
> + eisr0  = readl_relaxed(base + GICH_EISR0);
> + elrsr0 = readl_relaxed(base + GICH_ELRSR0);
> + if (unlikely(nr_lr > 32)) {
> + eisr1  = readl_relaxed(base + GICH_EISR1);
> + elrsr1 = readl_relaxed(base + GICH_ELRSR1);
> + } else {
> + eisr1 = elrsr1 = 0;
> + }
> +#ifdef CONFIG_CPU_BIG_ENDIAN
> + cpu_if->vgic_eisr  = ((u64)eisr0 << 32) | eisr1;
> + cpu_if->vgic_elrsr = ((u64)elrsr0 << 32) | elrsr1;
> +#else
> + cpu_if->vgic_eisr  = ((u64)eisr1 << 32) | eisr0;
> + cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0;
> +#endif
> + cpu_if->vgic_apr= readl_relaxed(base + GICH_APR);
> +
> + writel_relaxed(0, base + GICH_HCR);
> +
> + lr_base = base + GICH_LR0;
> + do {
> + cpu_if->vgic_lr[i++] = readl_relaxed(lr_base++);
> + } while (--nr_lr);

why not a simple for-loop?

> +}
> +

copy the vcpu HYP VA comment down here.

> +void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> + struct vgic_v2_cpu_if *cpu_if = >arch.vgic_cpu.vgic_v2;
> + struct vgic_dist *vgic = >arch.vgic;
> + void __iomem *base = kern_hyp_va(vgic->vctrl_base);
> + u32 __iomem *lr_base;
> + unsigned int i = 0, nr_lr;
> +
> + if (!base)
> + return;
> +
> + 

Re: [PATCH v2 05/21] arm64: KVM: Implement timer save/restore

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:59PM +, Marc Zyngier wrote:
> Implement the timer save restore as a direct translation of
> the assembly code version.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/kvm/hyp/Makefile  |  1 +
>  arch/arm64/kvm/hyp/hyp.h |  3 ++
>  arch/arm64/kvm/hyp/timer-sr.c| 71 
> 
>  include/clocksource/arm_arch_timer.h |  6 +++
>  4 files changed, 81 insertions(+)
>  create mode 100644 arch/arm64/kvm/hyp/timer-sr.c
> 
> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
> index d1e38ce..455dc0a 100644
> --- a/arch/arm64/kvm/hyp/Makefile
> +++ b/arch/arm64/kvm/hyp/Makefile
> @@ -4,3 +4,4 @@
>  
>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
>  obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
> +obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
> index a31cb6e..86aa5a2 100644
> --- a/arch/arm64/kvm/hyp/hyp.h
> +++ b/arch/arm64/kvm/hyp/hyp.h
> @@ -33,5 +33,8 @@ void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
>  void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
>  void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
>  
> +void __timer_save_state(struct kvm_vcpu *vcpu);
> +void __timer_restore_state(struct kvm_vcpu *vcpu);
> +
>  #endif /* __ARM64_KVM_HYP_H__ */
>  
> diff --git a/arch/arm64/kvm/hyp/timer-sr.c b/arch/arm64/kvm/hyp/timer-sr.c
> new file mode 100644
> index 000..8e2209c
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/timer-sr.c
> @@ -0,0 +1,71 @@
> +/*
> + * Copyright (C) 2012-2015 - ARM Ltd
> + * Author: Marc Zyngier 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "hyp.h"
> +
> +/* vcpu is already in the HYP VA space */
> +void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> + struct arch_timer_cpu *timer = >arch.timer_cpu;
> +
> + if (kvm->arch.timer.enabled) {
> + timer->cntv_ctl = read_sysreg(cntv_ctl_el0);
> + isb();
> + timer->cntv_cval = read_sysreg(cntv_cval_el0);
> + }
> +
> + /* Disable the virtual timer */
> + write_sysreg(0, cntv_ctl_el0);
> +
> + /* Allow physical timer/counter access for the host */
> + write_sysreg((read_sysreg(cnthctl_el2) | CNTHCTL_EL1PCTEN |
> +   CNTHCTL_EL1PCEN),
> +  cnthctl_el2);

nit: again I probably prefer reading cnthctl_el2 into a variable, modify
the bits and write it back, but it's no big deal.

> +
> + /* Clear cntvoff for the host */
> + write_sysreg(0, cntvoff_el2);

why do we do this when we've just disabled the timer?

> +}
> +
> +void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> + struct arch_timer_cpu *timer = >arch.timer_cpu;
> + u64 val;
> +
> + /*
> +  * Disallow physical timer access for the guest
> +  * Physical counter access is allowed
> +  */
> + val = read_sysreg(cnthctl_el2);
> + val &= ~CNTHCTL_EL1PCEN;
> + val |= CNTHCTL_EL1PCTEN;
> + write_sysreg(val, cnthctl_el2);
> +
> + if (kvm->arch.timer.enabled) {
> + write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2);
> + write_sysreg(timer->cntv_cval, cntv_cval_el0);
> + isb();
> + write_sysreg(timer->cntv_ctl, cntv_ctl_el0);
> + }
> +}
> diff --git a/include/clocksource/arm_arch_timer.h 
> b/include/clocksource/arm_arch_timer.h
> index 9916d0e..25d0914 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -23,6 +23,12 @@
>  #define ARCH_TIMER_CTRL_IT_MASK  (1 << 1)
>  #define ARCH_TIMER_CTRL_IT_STAT  (1 << 2)
>  
> +#define CNTHCTL_EL1PCTEN (1 << 0)
> +#define CNTHCTL_EL1PCEN  (1 << 1)
> +#define CNTHCTL_EVNTEN   (1 << 2)
> +#define CNTHCTL_EVNTDIR  (1 << 3)
> +#define CNTHCTL_EVNTI(0xF << 4)
> +
>  enum arch_timer_reg {
>   ARCH_TIMER_REG_CTRL,
>   ARCH_TIMER_REG_TVAL,
> -- 
> 2.1.4
> 

Otherwise this looks good.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to 

Re: [PATCH v2 00/21] arm64: KVM: world switch in C

2015-11-30 Thread Christoffer Dall
On Fri, Nov 27, 2015 at 06:49:54PM +, Marc Zyngier wrote:
> Once upon a time, the KVM/arm64 world switch was a nice, clean, lean
> and mean piece of hand-crafted assembly code. Over time, features have
> crept in, the code has become harder to maintain, and the smallest
> change is a pain to introduce. The VHE patches are a prime example of
> why this doesn't work anymore.
> 
> This series rewrites most of the existing assembly code in C, but keeps
> the existing code structure in place (most function names will look
> familiar to the reader). The biggest change is that we don't have to
> deal with a static register allocation (the compiler does it for us),
> we can easily follow structure and pointers, and only the lowest level
> is still in assembly code. Oh, and a negative diffstat.
> 
> There is still a healthy dose of inline assembly (system register
> accessors, runtime code patching), but I've tried not to make it too
> invasive. The generated code, while not exactly brilliant, doesn't
> look too shaby. I do expect a small performance degradation, but I
> believe this is something we can improve over time (my initial
> measurements don't show any obvious regression though).

I ran this through my experimental setup on m400 and got this:

BM  v4.4-rc2v4.4-rc2-wsinc  overhead
--  --  
Apache  5297.11 5243.77 101.02%
fio rand read   4354.33 4294.50 101.39%
fio rand write  2465.33 2231.33 110.49%
hackbench   17.48   19.78   113.16%
memcached   96442.69101274.04   95.23%
TCP_MAERTS  5966.89 6029.72 98.96%
TCP_STREAM  6284.60 6351.74 98.94%
TCP_RR  15044.7114324.03105.03%
pbzip2 c18.13   17.89   98.68%
pbzip2 d11.42   11.45   100.26%
kernbench   50.13   50.28   100.30%
mysql 1 152.84  154.01  100.77%
mysql 2 98.12   98.94   100.84%
mysql 4 51.32   51.17   99.71%
mysql 8 27.31   27.70   101.42%
mysql 2016.80   17.21   102.47%
mysql 100   13.71   14.11   102.92%
mysql 200   15.20   15.20   100.00%
mysql 400   17.16   17.16   100.00%

(you want to see this with a viewer that renders clear-text and tabs
properly)

What this tells me is that we do take a noticable hit on the
world-switch path, which shows up in the TCP_RR and hackbench workloads,
which have a high precision in their output.

Note that the memcached number is well within its variability between
individual benchmark runs, where it varies to 12% of its average in over
80% of the executions.

I don't think this is a showstopper thought, but we could consider
looking more closely at a breakdown of the world-switch path and verify
if/where we are really taking a hit.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 6/8] KVM: arm/arm64: vgic: Trust the LR state for HW IRQs

2015-11-24 Thread 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: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 97e2c08..65461f8 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1417,25 +1417,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
 static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 {
struct vgic_dist *dist = >kvm->arch.vgic;
-   struct irq_phys_map *map;
-   bool phys_active;
bool level_pending;
-   int ret;
 
if (!(vlr.state & LR_HW))
return false;
 
-   map = vgic_irq_map_search(vcpu, vlr.irq);
-   BUG_ON(!map);
-
-   ret = irq_get_irqchip_state(map->irq,
-   IRQCHIP_STATE_ACTIVE,
-   _active);
-
-   WARN_ON(ret);
-
-   if (phys_active)
-   return 0;
+   if (vlr.state & LR_STATE_ACTIVE)
+   return false;
 
spin_lock(>lock);
level_pending = process_queued_irq(vcpu, lr, vlr);
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 2/8] arm64: KVM: Fix AArch32 to AArch64 register mapping

2015-11-24 Thread Christoffer Dall
From: Marc Zyngier <marc.zyng...@arm.com>

When running a 32bit guest under a 64bit hypervisor, the ARMv8
architecture defines a mapping of the 32bit registers in the 64bit
space. This includes banked registers that are being demultiplexed
over the 64bit ones.

On exceptions caused by an operation involving a 32bit register, the
HW exposes the register number in the ESR_EL2 register. It was so
far understood that SW had to distinguish between AArch32 and AArch64
accesses (based on the current AArch32 mode and register number).

It turns out that I misinterpreted the ARM ARM, and the clue is in
D1.20.1: "For some exceptions, the exception syndrome given in the
ESR_ELx identifies one or more register numbers from the issued
instruction that generated the exception. Where the exception is
taken from an Exception level using AArch32 these register numbers
give the AArch64 view of the register."

Which means that the HW is already giving us the translated version,
and that we shouldn't try to interpret it at all (for example, doing
an MMIO operation from the IRQ mode using the LR register leads to
very unexpected behaviours).

The fix is thus not to perform a call to vcpu_reg32() at all from
vcpu_reg(), and use whatever register number is supplied directly.
The only case we need to find out about the mapping is when we
actively generate a register access, which only occurs when injecting
a fault in a guest.

Cc: sta...@vger.kernel.org
Reviewed-by: Robin Murphy <robin.mur...@arm.com>
Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm64/include/asm/kvm_emulate.h | 8 +---
 arch/arm64/kvm/inject_fault.c| 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 17e92f0..3ca894e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -99,11 +99,13 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
*vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
 }
 
+/*
+ * vcpu_reg should always be passed a register number coming from a
+ * read of ESR_EL2. Otherwise, it may give the wrong result on AArch32
+ * with banked registers.
+ */
 static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num)
 {
-   if (vcpu_mode_is_32bit(vcpu))
-   return vcpu_reg32(vcpu, reg_num);
-
return (unsigned long *)_gp_regs(vcpu)->regs.regs[reg_num];
 }
 
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 85c5715..648112e 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -48,7 +48,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, 
u32 vect_offset)
 
/* Note: These now point to the banked copies */
*vcpu_spsr(vcpu) = new_spsr_value;
-   *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
+   *vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
 
/* Branch to exception vector */
if (sctlr & (1 << 13))
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 5/8] KVM: arm/arm64: arch_timer: Preserve physical dist. active state on LR.active

2015-11-24 Thread 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: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 include/kvm/arm_vgic.h|  2 +-
 virt/kvm/arm/arch_timer.c | 28 +---
 virt/kvm/arm/vgic.c   | 34 ++
 3 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 9c747cb..d2f4147 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -342,10 +342,10 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
   struct irq_phys_map *map, bool level);
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
-int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
   int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 21a0ab2..69bca18 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -221,17 +221,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
kvm_timer_update_state(vcpu);
 
/*
-* If we enter the guest with the virtual input level to the VGIC
-* asserted, then we have already told the VGIC what we need to, and
-* we don't need to exit from the guest until the guest deactivates
-* the already injected interrupt, so therefore we should set the
-* hardware active state to prevent unnecessary exits from the guest.
-*
-* Conversely, if the virtual input level is deasserted, then always
-* clear the hardware active state to ensure that hardware interrupts
-* from the timer triggers a guest exit.
-*/
-   if (timer->irq.level)
+   * If we enter the guest with the virtual input level to the VGIC
+   * asserted, then we have already told the VGIC what we need to, and
+   * we don't need to exit from the guest until the guest deactivates
+   * the already injected interrupt, so therefore we should set the
+   * hardware active state to prevent unnecessary exits from the guest.
+   *
+   * Also, if we enter the guest with the virtual timer interrupt active,
+   * then it must be active on the physical distributor, because we set
+   * the HW bit and the guest must be able to deactivate the virtual and
+   * physical interrupt at the same time.
+   *
+   * Conversely, if the virtual input level is deasserted and the virtual
+   * interrupt is not active, then always clear the hardware active state
+   * to ensure that hardware interrupts from the timer triggers a guest
+   * exit.
+   */
+   if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map))
phys_active = true;
else
phys_active = false;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 5335383..97e2c08 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1096,6 +1096,27 @@ static void vgic_retire_lr(int lr_nr, struct kvm_vcpu 
*vcpu)
vgic_set_lr(vcpu, lr_nr, vlr);
 }
 
+static bool dist_active_irq(struct kvm_vcpu *vcpu)
+{
+   struct vgic_dist *dist = >kvm->arch.vgic;
+
+   return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
+}
+
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
+{
+   int i;
+
+   for (i = 0; i < vcpu->arch.vgic_cpu.nr_lr; i++) {
+   struct vgic_lr vlr = vgic_get_lr(vcpu, i);
+
+   if (vlr.irq == map->virt_irq && vlr.state & LR_STATE_ACTIVE)
+   return true;
+   }
+
+   return dist_active_irq(vcpu);
+}
+
 /*
  * An interrupt may have been disabled after being made pending on the
  * CPU interface (the classic case is a timer running while we're
@@ -1248,7 +1269,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu 
*vcpu)
 

[PULL 3/8] arm64: KVM: Add workaround for Cortex-A57 erratum 834220

2015-11-24 Thread Christoffer Dall
From: Marc Zyngier <marc.zyng...@arm.com>

Cortex-A57 parts up to r1p2 can misreport Stage 2 translation faults
when a Stage 1 permission fault or device alignment fault should
have been reported.

This patch implements the workaround (which is to validate that the
Stage-1 translation actually succeeds) by using code patching.

Cc: sta...@vger.kernel.org
Reviewed-by: Will Deacon <will.dea...@arm.com>
Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm64/Kconfig  | 21 +
 arch/arm64/include/asm/cpufeature.h |  3 ++-
 arch/arm64/kernel/cpu_errata.c  |  9 +
 arch/arm64/kvm/hyp.S|  6 ++
 4 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9ac16a4..e55848c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -316,6 +316,27 @@ config ARM64_ERRATUM_832075
 
  If unsure, say Y.
 
+config ARM64_ERRATUM_834220
+   bool "Cortex-A57: 834220: Stage 2 translation fault might be 
incorrectly reported in presence of a Stage 1 fault"
+   depends on KVM
+   default y
+   help
+ This option adds an alternative code sequence to work around ARM
+ erratum 834220 on Cortex-A57 parts up to r1p2.
+
+ Affected Cortex-A57 parts might report a Stage 2 translation
+ fault as the result of a Stage 1 fault for load crossing a
+ page boundary when there is a permission or device memory
+ alignment fault at Stage 1 and a translation fault at Stage 2.
+
+ The workaround is to verify that the Stage 1 translation
+ doesn't generate a fault before handling the Stage 2 fault.
+ Please note that this does not necessarily enable the workaround,
+ as it depends on the alternative framework, which will only patch
+ the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+
 config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 11d5bb0f..52722ee 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -29,8 +29,9 @@
 #define ARM64_HAS_PAN  4
 #define ARM64_HAS_LSE_ATOMICS  5
 #define ARM64_WORKAROUND_CAVIUM_23154  6
+#define ARM64_WORKAROUND_8342207
 
-#define ARM64_NCAPS7
+#define ARM64_NCAPS8
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 24926f2..feb6b4e 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -75,6 +75,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
   (1 << MIDR_VARIANT_SHIFT) | 2),
},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_834220
+   {
+   /* Cortex-A57 r0p0 - r1p2 */
+   .desc = "ARM erratum 834220",
+   .capability = ARM64_WORKAROUND_834220,
+   MIDR_RANGE(MIDR_CORTEX_A57, 0x00,
+  (1 << MIDR_VARIANT_SHIFT) | 2),
+   },
+#endif
 #ifdef CONFIG_ARM64_ERRATUM_845719
{
/* Cortex-A53 r0p[01234] */
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 1599701..ff2e038 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -1015,9 +1015,15 @@ el1_trap:
b.ne1f  // Not an abort we care about
 
/* This is an abort. Check for permission fault */
+alternative_if_not ARM64_WORKAROUND_834220
and x2, x1, #ESR_ELx_FSC_TYPE
cmp x2, #FSC_PERM
b.ne1f  // Not a permission fault
+alternative_else
+   nop // Use the permission fault path to
+   nop // check for a valid S1 translation,
+   nop // regardless of the ESR value.
+alternative_endif
 
/*
 * Check for Stage-1 page table walk, which is guaranteed
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 1/8] ARM/arm64: KVM: test properly for a PTE's uncachedness

2015-11-24 Thread Christoffer Dall
From: Ard Biesheuvel <ard.biesheu...@linaro.org>

The open coded tests for checking whether a PTE maps a page as
uncached use a flawed '(pte_val(xxx) & CONST) != CONST' pattern,
which is not guaranteed to work since the type of a mapping is
not a set of mutually exclusive bits

For HYP mappings, the type is an index into the MAIR table (i.e, the
index itself does not contain any information whatsoever about the
type of the mapping), and for stage-2 mappings it is a bit field where
normal memory and device types are defined as follows:

#define MT_S2_NORMAL0xf
#define MT_S2_DEVICE_nGnRE  0x1

I.e., masking *and* comparing with the latter matches on the former,
and we have been getting lucky merely because the S2 device mappings
also have the PTE_UXN bit set, or we would misidentify memory mappings
as device mappings.

Since the unmap_range() code path (which contains one instance of the
flawed test) is used both for HYP mappings and stage-2 mappings, and
considering the difference between the two, it is non-trivial to fix
this by rewriting the tests in place, as it would involve passing
down the type of mapping through all the functions.

However, since HYP mappings and stage-2 mappings both deal with host
physical addresses, we can simply check whether the mapping is backed
by memory that is managed by the host kernel, and only perform the
D-cache maintenance if this is the case.

Cc: sta...@vger.kernel.org
Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Tested-by: Pavel Fedin <p.fe...@samsung.com>
Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/kvm/mmu.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 6984342..7dace90 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -98,6 +98,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
__kvm_flush_dcache_pud(pud);
 }
 
+static bool kvm_is_device_pfn(unsigned long pfn)
+{
+   return !pfn_valid(pfn);
+}
+
 /**
  * stage2_dissolve_pmd() - clear and flush huge PMD entry
  * @kvm:   pointer to kvm structure.
@@ -213,7 +218,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
kvm_tlb_flush_vmid_ipa(kvm, addr);
 
/* No need to invalidate the cache for device mappings 
*/
-   if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
PAGE_S2_DEVICE)
+   if (!kvm_is_device_pfn(__phys_to_pfn(addr)))
kvm_flush_dcache_pte(old_pte);
 
put_page(virt_to_page(pte));
@@ -305,8 +310,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
 
pte = pte_offset_kernel(pmd, addr);
do {
-   if (!pte_none(*pte) &&
-   (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+   if (!pte_none(*pte) && !kvm_is_device_pfn(__phys_to_pfn(addr)))
kvm_flush_dcache_pte(*pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
 }
@@ -1037,11 +1041,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
return kvm_vcpu_dabt_iswrite(vcpu);
 }
 
-static bool kvm_is_device_pfn(unsigned long pfn)
-{
-   return !pfn_valid(pfn);
-}
-
 /**
  * stage2_wp_ptes - write protect PMD range
  * @pmd:   pointer to pmd entry
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 8/8] arm64: kvm: report original PAR_EL1 upon panic

2015-11-24 Thread Christoffer Dall
From: Mark Rutland <mark.rutl...@arm.com>

If we call __kvm_hyp_panic while a guest context is active, we call
__restore_sysregs before acquiring the system register values for the
panic, in the process throwing away the PAR_EL1 value at the point of
the panic.

This patch modifies __kvm_hyp_panic to stash the PAR_EL1 value prior to
restoring host register values, enabling us to report the original
values at the point of the panic.

Acked-by: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm64/kvm/hyp.S | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index ce70817..86c2898 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -864,6 +864,10 @@ ENTRY(__kvm_flush_vm_context)
 ENDPROC(__kvm_flush_vm_context)
 
 __kvm_hyp_panic:
+   // Stash PAR_EL1 before corrupting it in __restore_sysregs
+   mrs x0, par_el1
+   pushx0, xzr
+
// Guess the context by looking at VTTBR:
// If zero, then we're already a host.
// Otherwise restore a minimal host context before panicing.
@@ -898,7 +902,7 @@ __kvm_hyp_panic:
mrs x3, esr_el2
mrs x4, far_el2
mrs x5, hpfar_el2
-   mrs x6, par_el1
+   pop x6, xzr // active context PAR_EL1
mrs x7, tpidr_el2
 
mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 0/8] KVM/ARM Fixes for v4.4-rc3

2015-11-24 Thread Christoffer Dall
Hi Paolo,

Here's a set of fixes for KVM/ARM for v4.4-rc3 based on v4.4-rc2, because the
errata fixes don't apply on v4.4-rc1.  Let me know if you can pull this anyhow.

Thanks,
-Christoffer

The following changes since commit 1ec218373b8ebda821aec00bb156a9c94fad9cd4:

  Linux 4.4-rc2 (2015-11-22 16:45:59 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git 
tags/kvm-arm-for-v4.4-rc3

for you to fetch changes up to fbb4574ce9a37e15a9872860bf202f2be5bdf6c4:

  arm64: kvm: report original PAR_EL1 upon panic (2015-11-24 18:20:58 +0100)


KVM/ARM Fixes for v4.4-rc3.

Includes some timer fixes, properly unmapping PTEs, an errata fix, and two
tweaks to the EL2 panic code.


Ard Biesheuvel (1):
  ARM/arm64: KVM: test properly for a PTE's uncachedness

Christoffer Dall (3):
  KVM: arm/arm64: Fix preemptible timer active state crazyness
  KVM: arm/arm64: arch_timer: Preserve physical dist. active state on 
LR.active
  KVM: arm/arm64: vgic: Trust the LR state for HW IRQs

Marc Zyngier (2):
  arm64: KVM: Fix AArch32 to AArch64 register mapping
  arm64: KVM: Add workaround for Cortex-A57 erratum 834220

Mark Rutland (2):
  arm64: kvm: avoid %p in __kvm_hyp_panic
  arm64: kvm: report original PAR_EL1 upon panic

 arch/arm/kvm/arm.c   |  7 +
 arch/arm/kvm/mmu.c   | 15 +--
 arch/arm64/Kconfig   | 21 +++
 arch/arm64/include/asm/cpufeature.h  |  3 ++-
 arch/arm64/include/asm/kvm_emulate.h |  8 +++---
 arch/arm64/kernel/cpu_errata.c   |  9 +++
 arch/arm64/kvm/hyp.S | 14 --
 arch/arm64/kvm/inject_fault.c|  2 +-
 include/kvm/arm_vgic.h   |  2 +-
 virt/kvm/arm/arch_timer.c| 28 
 virt/kvm/arm/vgic.c  | 50 +---
 11 files changed, 100 insertions(+), 59 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 7/8] arm64: kvm: avoid %p in __kvm_hyp_panic

2015-11-24 Thread Christoffer Dall
From: Mark Rutland <mark.rutl...@arm.com>

Currently __kvm_hyp_panic uses %p for values which are not pointers,
such as the ESR value. This can confusingly lead to "(null)" being
printed for the value.

Use %x instead, and only use %p for host pointers.

Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
Acked-by: Marc Zyngier <marc.zyng...@arm.com>
Cc: Christoffer Dall <christoffer.d...@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm64/kvm/hyp.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index ff2e038..ce70817 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -914,7 +914,7 @@ __kvm_hyp_panic:
 ENDPROC(__kvm_hyp_panic)
 
 __hyp_panic_str:
-   .ascii  "HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p 
PAR:%p\nVCPU:%p\n\0"
+   .ascii  "HYP panic:\nPS:%08x PC:%016x ESR:%08x\nFAR:%016x HPFAR:%016x 
PAR:%016x\nVCPU:%p\n\0"
 
.align  2
 
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 4/8] KVM: arm/arm64: Fix preemptible timer active state crazyness

2015-11-24 Thread Christoffer Dall
We were setting the physical active state on the GIC distributor in a
preemptible section, which could cause us to set the active state on
different physical CPU from the one we were actually going to run on,
hacoc ensues.

Since we are no longer descheduling/scheduling soft timers in the
flush/sync timer functions, simply moving the timer flush into a
non-preemptible section.

Reviewed-by: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/kvm/arm.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index eab83b2..e06fd29 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -564,17 +564,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu_sleep(vcpu);
 
/*
-* Disarming the background timer must be done in a
-* preemptible context, as this call may sleep.
-*/
-   kvm_timer_flush_hwstate(vcpu);
-
-   /*
 * Preparing the interrupts to be injected also
 * involves poking the GIC, which must be done in a
 * non-preemptible context.
 */
preempt_disable();
+   kvm_timer_flush_hwstate(vcpu);
kvm_vgic_flush_hwstate(vcpu);
 
local_irq_disable();
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/2] arm64: KVM: Fixes for 4.4-rc2

2015-11-24 Thread Christoffer Dall
On Mon, Nov 16, 2015 at 10:28:16AM +, Marc Zyngier wrote:
> Here's a couple of fixes for KVM/arm64:
> 
> - The first one addresses a misinterpretation of the architecture
>   spec, leading to the mishandling of I/O accesses generated from an
>   AArch32 guest using banked registers.
> 
> - The second one is a workaround for a Cortex-A57 erratum.
> 
Thanks, applied with cosmetic fixes and cc'ed to stable.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] KVM: arm/arm64: Fix some more timer related issues

2015-11-24 Thread Christoffer Dall
This little series addresses some problems we've been observing with the
arch timer.  First, we were fiddling with a PPI timer interrupt outside
of a preemptible section, which is bad for obvious reasons.  Second, we
were clearing the physical active state when we shouldn't.  Third, we
can simplify the vgic code by just considering the LR state instead of
the GIC physical state on guest return.

Christoffer Dall (3):
  KVM: arm/arm64: Fix preemptible timer active state crazyness
  KVM: arm/arm64: arch_timer: Preserve physical dist. active state on
LR.active
  KVM: arm/arm64: vgic: Trust the LR state for HW IRQs

 arch/arm/kvm/arm.c|  7 +--
 include/kvm/arm_vgic.h|  2 +-
 virt/kvm/arm/arch_timer.c | 28 +++--
 virt/kvm/arm/vgic.c   | 53 ---
 4 files changed, 46 insertions(+), 44 deletions(-)

-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] KVM: arm/arm64: vgic: Trust the LR state for HW IRQs

2015-11-24 Thread 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.

Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9002f0d..55cd7e3 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1420,25 +1420,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
 static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 {
struct vgic_dist *dist = >kvm->arch.vgic;
-   struct irq_phys_map *map;
-   bool phys_active;
bool level_pending;
-   int ret;
 
if (!(vlr.state & LR_HW))
return false;
 
-   map = vgic_irq_map_search(vcpu, vlr.irq);
-   BUG_ON(!map);
-
-   ret = irq_get_irqchip_state(map->irq,
-   IRQCHIP_STATE_ACTIVE,
-   _active);
-
-   WARN_ON(ret);
-
-   if (phys_active)
-   return 0;
+   if (vlr.state & LR_STATE_ACTIVE)
+   return false;
 
spin_lock(>lock);
level_pending = process_queued_irq(vcpu, lr, vlr);
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] KVM: arm/arm64: Fix preemptible timer active state crazyness

2015-11-24 Thread Christoffer Dall
We were setting the physical active state on the GIC distributor in a
preemptible section, which could cause us to set the active state on
different physical CPU from the one we were actually going to run on,
hacoc ensues.

Since we are no longer descheduling/scheduling soft timers in the
flush/sync timer functions, simply moving the timer flush into a
non-preemptible section.

Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/kvm/arm.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index eab83b2..e06fd29 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -564,17 +564,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu_sleep(vcpu);
 
/*
-* Disarming the background timer must be done in a
-* preemptible context, as this call may sleep.
-*/
-   kvm_timer_flush_hwstate(vcpu);
-
-   /*
 * Preparing the interrupts to be injected also
 * involves poking the GIC, which must be done in a
 * non-preemptible context.
 */
preempt_disable();
+   kvm_timer_flush_hwstate(vcpu);
kvm_vgic_flush_hwstate(vcpu);
 
local_irq_disable();
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] KVM: arm/arm64: arch_timer: Preserve physical dist. active state on LR.active

2015-11-24 Thread 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.

Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 include/kvm/arm_vgic.h|  2 +-
 virt/kvm/arm/arch_timer.c | 28 +---
 virt/kvm/arm/vgic.c   | 37 +
 3 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 9c747cb..d2f4147 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -342,10 +342,10 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
   struct irq_phys_map *map, bool level);
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
-int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
   int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 21a0ab2..69bca18 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -221,17 +221,23 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
kvm_timer_update_state(vcpu);
 
/*
-* If we enter the guest with the virtual input level to the VGIC
-* asserted, then we have already told the VGIC what we need to, and
-* we don't need to exit from the guest until the guest deactivates
-* the already injected interrupt, so therefore we should set the
-* hardware active state to prevent unnecessary exits from the guest.
-*
-* Conversely, if the virtual input level is deasserted, then always
-* clear the hardware active state to ensure that hardware interrupts
-* from the timer triggers a guest exit.
-*/
-   if (timer->irq.level)
+   * If we enter the guest with the virtual input level to the VGIC
+   * asserted, then we have already told the VGIC what we need to, and
+   * we don't need to exit from the guest until the guest deactivates
+   * the already injected interrupt, so therefore we should set the
+   * hardware active state to prevent unnecessary exits from the guest.
+   *
+   * Also, if we enter the guest with the virtual timer interrupt active,
+   * then it must be active on the physical distributor, because we set
+   * the HW bit and the guest must be able to deactivate the virtual and
+   * physical interrupt at the same time.
+   *
+   * Conversely, if the virtual input level is deasserted and the virtual
+   * interrupt is not active, then always clear the hardware active state
+   * to ensure that hardware interrupts from the timer triggers a guest
+   * exit.
+   */
+   if (timer->irq.level || kvm_vgic_map_is_active(vcpu, timer->map))
phys_active = true;
else
phys_active = false;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 5335383..9002f0d 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1096,6 +1096,30 @@ static void vgic_retire_lr(int lr_nr, struct kvm_vcpu 
*vcpu)
vgic_set_lr(vcpu, lr_nr, vlr);
 }
 
+static int dist_active_irq(struct kvm_vcpu *vcpu)
+{
+   struct vgic_dist *dist = >kvm->arch.vgic;
+
+   if (!irqchip_in_kernel(vcpu->kvm))
+   return 0;
+
+   return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
+}
+
+bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
+{
+   int i;
+
+   for (i = 0; i < vcpu->arch.vgic_cpu.nr_lr; i++) {
+   struct vgic_lr vlr = vgic_get_lr(vcpu, i);
+
+   if (vlr.irq == map->virt_irq && vlr.state & LR_STATE_ACTIVE)
+   return true;
+   }
+
+   return dist_active_irq(vcpu);
+}
+
 /*
  * An interrupt may have been disabled after being made pending on the
  * CPU interface (the classic case is a timer running while we're
@@ -1248,7 +1272,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vc

Re: [PATCH 3/3] KVM/arm64: enable enhanced armv8 fp/simd lazy switch

2015-11-10 Thread Christoffer Dall
On Mon, Nov 09, 2015 at 03:13:15PM -0800, Mario Smarduch wrote:
> 
> 
> On 11/5/2015 7:02 AM, Christoffer Dall wrote:
> > On Fri, Oct 30, 2015 at 02:56:33PM -0700, Mario Smarduch wrote:
> >> This patch enables arm64 lazy fp/simd switch, similar to arm described in
> >> second patch. Change from previous version - restore function is moved to
> >> host. 
> >>
> >> Signed-off-by: Mario Smarduch <m.smard...@samsung.com>
> >> ---
> >>  arch/arm64/include/asm/kvm_host.h |  2 +-
> >>  arch/arm64/kernel/asm-offsets.c   |  1 +
> >>  arch/arm64/kvm/hyp.S  | 37 
> >> +++--
> >>  3 files changed, 33 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/arch/arm64/include/asm/kvm_host.h 
> >> b/arch/arm64/include/asm/kvm_host.h
> >> index 26a2347..dcecf92 100644
> >> --- a/arch/arm64/include/asm/kvm_host.h
> >> +++ b/arch/arm64/include/asm/kvm_host.h
> >> @@ -251,11 +251,11 @@ static inline void kvm_arch_hardware_unsetup(void) {}
> >>  static inline void kvm_arch_sync_events(struct kvm *kvm) {}
> >>  static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
> >>  static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
> >> -static inline void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu) {}
> >>  
> >>  void kvm_arm_init_debug(void);
> >>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
> >>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
> >>  void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
> >> +void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu);
> >>  
> >>  #endif /* __ARM64_KVM_HOST_H__ */
> >> diff --git a/arch/arm64/kernel/asm-offsets.c 
> >> b/arch/arm64/kernel/asm-offsets.c
> >> index 8d89cf8..c9c5242 100644
> >> --- a/arch/arm64/kernel/asm-offsets.c
> >> +++ b/arch/arm64/kernel/asm-offsets.c
> >> @@ -124,6 +124,7 @@ int main(void)
> >>DEFINE(VCPU_HCR_EL2,offsetof(struct kvm_vcpu, 
> >> arch.hcr_el2));
> >>DEFINE(VCPU_MDCR_EL2,   offsetof(struct kvm_vcpu, arch.mdcr_el2));
> >>DEFINE(VCPU_IRQ_LINES,  offsetof(struct kvm_vcpu, arch.irq_lines));
> >> +  DEFINE(VCPU_VFP_DIRTY,  offsetof(struct kvm_vcpu, arch.vfp_dirty));
> >>DEFINE(VCPU_HOST_CONTEXT,   offsetof(struct kvm_vcpu, 
> >> arch.host_cpu_context));
> >>DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, 
> >> arch.host_debug_state));
> >>DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, 
> >> arch.timer_cpu.cntv_ctl));
> >> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> >> index e583613..ed2c4cf 100644
> >> --- a/arch/arm64/kvm/hyp.S
> >> +++ b/arch/arm64/kvm/hyp.S
> >> @@ -36,6 +36,28 @@
> >>  #define CPU_SYSREG_OFFSET(x)  (CPU_SYSREGS + 8*x)
> >>  
> >>.text
> >> +
> >> +/**
> >> + * void kvm_restore_host_vfp_state(struct vcpu *vcpu) - Executes lazy
> >> + *fp/simd switch, saves the guest, restores host. Called from host
> >> + *mode, placed outside of hyp section.
> > 
> > same comments on style as previous patch
> > 
> >> + */
> >> +ENTRY(kvm_restore_host_vfp_state)
> >> +  pushxzr, lr
> >> +
> >> +  add x2, x0, #VCPU_CONTEXT
> >> +  mov w3, #0
> >> +  strbw3, [x0, #VCPU_VFP_DIRTY]
> > 
> > I've been discussing with myself if it would make more sense to clear
> > the dirty flag in the C-code...
> > 
> >> +
> >> +  bl __save_fpsimd
> >> +
> >> +  ldr x2, [x0, #VCPU_HOST_CONTEXT]
> >> +  bl __restore_fpsimd
> >> +
> >> +  pop xzr, lr
> >> +  ret
> >> +ENDPROC(kvm_restore_host_vfp_state)
> >> +
> >>.pushsection.hyp.text, "ax"
> >>.align  PAGE_SHIFT
> >>  
> >> @@ -482,7 +504,11 @@
> >>  99:
> >>msr hcr_el2, x2
> >>mov x2, #CPTR_EL2_TTA
> >> +
> >> +  ldrbw3, [x0, #VCPU_VFP_DIRTY]
> >> +  tbnzw3, #0, 98f
> >>orr x2, x2, #CPTR_EL2_TFP
> >> +98:
> > 
> > mmm, don't you need to only set the fpexc32 when you're actually going
> > to trap the guest accesses?
> > 
> > also, you can consider only setting this in vcpu_load (jumping quickly
> > to EL2 to do so) if we're running a 32-bit guest.  Probably worth
> > meas

Re: [PATCH v2 resend] ARM/arm64: KVM: test properly for a PTE's uncachedness

2015-11-10 Thread Christoffer Dall
On Tue, Nov 10, 2015 at 03:11:20PM +0100, Ard Biesheuvel wrote:
> The open coded tests for checking whether a PTE maps a page as
> uncached use a flawed '(pte_val(xxx) & CONST) != CONST' pattern,
> which is not guaranteed to work since the type of a mapping is
> not a set of mutually exclusive bits
> 
> For HYP mappings, the type is an index into the MAIR table (i.e, the
> index itself does not contain any information whatsoever about the
> type of the mapping), and for stage-2 mappings it is a bit field where
> normal memory and device types are defined as follows:
> 
> #define MT_S2_NORMAL0xf
> #define MT_S2_DEVICE_nGnRE  0x1
> 
> I.e., masking *and* comparing with the latter matches on the former,
> and we have been getting lucky merely because the S2 device mappings
> also have the PTE_UXN bit set, or we would misidentify memory mappings
> as device mappings.
> 
> Since the unmap_range() code path (which contains one instance of the
> flawed test) is used both for HYP mappings and stage-2 mappings, and
> considering the difference between the two, it is non-trivial to fix
> this by rewriting the tests in place, as it would involve passing
> down the type of mapping through all the functions.
> 
> However, since HYP mappings and stage-2 mappings both deal with host
> physical addresses, we can simply check whether the mapping is backed
> by memory that is managed by the host kernel, and only perform the
> D-cache maintenance if this is the case.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
> Tested-by: Pavel Fedin <p.fe...@samsung.com>
> Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>

Thanks, applied.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] ARM/arm64: KVM: test properly for a PTE's uncachedness

2015-11-10 Thread Christoffer Dall
On Tue, Nov 10, 2015 at 02:15:45PM +0100, Ard Biesheuvel wrote:
> On 10 November 2015 at 13:22, Christoffer Dall
> <christoffer.d...@linaro.org> wrote:
> > On Tue, Nov 10, 2015 at 10:45:37AM +0100, Ard Biesheuvel wrote:
> >> Hi all,
> >>
> >> I wonder if this is a better way to address the problem. It looks at
> >> the nature of the memory rather than the nature of the mapping, which
> >> is probably a more reliable indicator of whether cache maintenance is
> >> required when performing the unmap.
> >>
> >>
> >> ---8<
> >> The open coded tests for checking whether a PTE maps a page as
> >> uncached use a flawed 'pte_val(xxx) & CONST != CONST' pattern,
> >> which is not guaranteed to work since the type of a mapping is
> >> not a set of mutually exclusive bits
> >>
> >> For HYP mappings, the type is an index into the MAIR table (i.e, the
> >> index itself does not contain any information whatsoever about the
> >> type of the mapping), and for stage-2 mappings it is a bit field where
> >> normal memory and device types are defined as follows:
> >>
> >> #define MT_S2_NORMAL0xf
> >> #define MT_S2_DEVICE_nGnRE  0x1
> >>
> >> I.e., masking *and* comparing with the latter matches on the former,
> >> and we have been getting lucky merely because the S2 device mappings
> >> also have the PTE_UXN bit set, or we would misidentify memory mappings
> >> as device mappings.
> >>
> >> Since the unmap_range() code path (which contains one instance of the
> >> flawed test) is used both for HYP mappings and stage-2 mappings, and
> >> considering the difference between the two, it is non-trivial to fix
> >> this by rewriting the tests in place, as it would involve passing
> >> down the type of mapping through all the functions.
> >>
> >> However, since HYP mappings and stage-2 mappings both deal with host
> >> physical addresses, we can simply check whether the mapping is backed
> >> by memory that is managed by the host kernel, and only perform the
> >> D-cache maintenance if this is the case.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
> >> ---
> >>  arch/arm/kvm/mmu.c | 15 +++
> >>  1 file changed, 7 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> >> index 6984342da13d..7dace909d5cf 100644
> >> --- a/arch/arm/kvm/mmu.c
> >> +++ b/arch/arm/kvm/mmu.c
> >> @@ -98,6 +98,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
> >>   __kvm_flush_dcache_pud(pud);
> >>  }
> >>
> >> +static bool kvm_is_device_pfn(unsigned long pfn)
> >> +{
> >> + return !pfn_valid(pfn);
> >> +}
> >> +
> >>  /**
> >>   * stage2_dissolve_pmd() - clear and flush huge PMD entry
> >>   * @kvm: pointer to kvm structure.
> >> @@ -213,7 +218,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
> >>   kvm_tlb_flush_vmid_ipa(kvm, addr);
> >>
> >>   /* No need to invalidate the cache for device 
> >> mappings */
> >> - if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
> >> PAGE_S2_DEVICE)
> >> + if (!kvm_is_device_pfn(__phys_to_pfn(addr)))
> >>   kvm_flush_dcache_pte(old_pte);
> >>
> >>   put_page(virt_to_page(pte));
> >> @@ -305,8 +310,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t 
> >> *pmd,
> >>
> >>   pte = pte_offset_kernel(pmd, addr);
> >>   do {
> >> - if (!pte_none(*pte) &&
> >> - (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
> >> + if (!pte_none(*pte) && 
> >> !kvm_is_device_pfn(__phys_to_pfn(addr)))
> >>   kvm_flush_dcache_pte(*pte);
> >>   } while (pte++, addr += PAGE_SIZE, addr != end);
> >>  }
> >> @@ -1037,11 +1041,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu 
> >> *vcpu)
> >>   return kvm_vcpu_dabt_iswrite(vcpu);
> >>  }
> >>
> >> -static bool kvm_is_device_pfn(unsigned long pfn)
> >> -{
> >> - return !pfn_valid(pfn);
> >> -}
> >> -
> >>  /**
> >>   * stage2_wp_ptes - write protect PMD range
&g

Re: [PATCH v3 2/3] KVM/arm/arm64: enable enhanced armv7 fp/simd lazy switch

2015-11-06 Thread Christoffer Dall
On Thu, Nov 05, 2015 at 04:23:41PM -0800, Mario Smarduch wrote:
> 
> 
> On 11/5/2015 6:48 AM, Christoffer Dall wrote:
> > On Fri, Oct 30, 2015 at 02:56:32PM -0700, Mario Smarduch wrote:
> >> This patch tracks vfp/simd hardware state with a vcpu lazy flag. vCPU lazy 
> >> flag is set on guest access and traps to vfp/simd hardware switch handler. 
> >> On 
> >> vm-enter if lazy flag is set skip trap enable and save host fpexc. On 
> >> vm-exit if flag is set skip hardware context switch and return to host 
> >> with 
> >> guest context. In vcpu_put check if vcpu lazy flag is set, and execute a 
> >> hardware context switch to restore host.
> >>
> >> Also some arm64 field and empty function are added to compile for arm64.
> >>
> >> Signed-off-by: Mario Smarduch <m.smard...@samsung.com>
> >> ---
> >>  arch/arm/include/asm/kvm_host.h   |  1 +
> >>  arch/arm/kvm/arm.c|  6 
> >>  arch/arm/kvm/interrupts.S | 60 
> >> ---
> >>  arch/arm/kvm/interrupts_head.S| 14 +
> >>  arch/arm64/include/asm/kvm_host.h |  4 +++
> >>  5 files changed, 63 insertions(+), 22 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/kvm_host.h 
> >> b/arch/arm/include/asm/kvm_host.h
> >> index f1bf551..a9e86e0 100644
> >> --- a/arch/arm/include/asm/kvm_host.h
> >> +++ b/arch/arm/include/asm/kvm_host.h
> >> @@ -227,6 +227,7 @@ int kvm_perf_teardown(void);
> >>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> >>  
> >>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
> >> +void kvm_restore_host_vfp_state(struct kvm_vcpu *);
> >>  
> >>  static inline void kvm_arch_hardware_disable(void) {}
> >>  static inline void kvm_arch_hardware_unsetup(void) {}
> >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >> index dc017ad..11a56fe 100644
> >> --- a/arch/arm/kvm/arm.c
> >> +++ b/arch/arm/kvm/arm.c
> >> @@ -296,6 +296,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
> >> cpu)
> >>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >>  {
> >>/*
> >> +   * If fp/simd registers are dirty save guest, restore host before
> > 
> > If the fp/simd registers are dirty, then restore the host state before
> I'd drop 'releasing the cpu', the vcpu thread may be returning to
> user mode.
> > 
> >> +   * releasing the cpu.
> >> +   */
> >> +  if (vcpu->arch.vfp_dirty)
> >> +  kvm_restore_host_vfp_state(vcpu);
> >> +  /*
> >> * The arch-generic KVM code expects the cpu field of a vcpu to be -1
> >> * if the vcpu is no longer assigned to a cpu.  This is used for the
> >> * optimized make_all_cpus_request path.
> >> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
> >> index 900ef6d..ca25314 100644
> >> --- a/arch/arm/kvm/interrupts.S
> >> +++ b/arch/arm/kvm/interrupts.S
> >> @@ -28,6 +28,32 @@
> >>  #include "interrupts_head.S"
> >>  
> >>.text
> >> +/**
> >> + * void kvm_restore_host_vfp_state(struct vcpu *vcpu) - Executes lazy
> > 
> > nit: Can you move the multi-line description of the function into a
> > separate paragraph?
> Sure.
> > 
> >> + *fp/simd switch, saves the guest, restores host. Called from host
> >> + *mode, placed outside of hyp region start/end.
> > 
> > Put the description in a separate paragraph and get rid of the "executes
> > lazy fp/simd swithch" part, that doesn't help understanding.  Just say
> > that this funciton restores the host state.
> Sure.
> > 
> >> + */
> >> +ENTRY(kvm_restore_host_vfp_state)
> >> +#ifdef CONFIG_VFPv3
> >> +  push{r4-r7}
> >> +
> >> +  add r7, vcpu, #VCPU_VFP_GUEST
> >> +  store_vfp_state r7
> >> +
> >> +  add r7, vcpu, #VCPU_VFP_HOST
> >> +  ldr r7, [r7]
> >> +  restore_vfp_state r7
> >> +
> >> +  ldr r3, [vcpu, #VCPU_VFP_HOST_FPEXC]
> >> +  VFPFMXR FPEXC, r3
> >> +
> >> +  mov r3, #0
> >> +  strbr3, [vcpu, #VCPU_VFP_DIRTY]
> >> +
> >> +  pop {r4-r7}
> >> +#endif
> >> +  bx  lr
> >> +ENDPROC(kvm_restore_host_vfp_state)
> >>  
> >>  __kvm_hyp_code_start:
> >>.globl __

Re: [PATCH 3/3] KVM/arm64: enable enhanced armv8 fp/simd lazy switch

2015-11-06 Thread Christoffer Dall
On Thu, Nov 05, 2015 at 04:57:12PM -0800, Mario Smarduch wrote:
> 
> 
> On 11/5/2015 7:02 AM, Christoffer Dall wrote:
> > On Fri, Oct 30, 2015 at 02:56:33PM -0700, Mario Smarduch wrote:
> >> This patch enables arm64 lazy fp/simd switch, similar to arm described in
> >> second patch. Change from previous version - restore function is moved to
> >> host. 
> >>
> >> Signed-off-by: Mario Smarduch <m.smard...@samsung.com>
> >> ---
> >>  arch/arm64/include/asm/kvm_host.h |  2 +-
> >>  arch/arm64/kernel/asm-offsets.c   |  1 +
> >>  arch/arm64/kvm/hyp.S  | 37 
> >> +++--
> >>  3 files changed, 33 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/arch/arm64/include/asm/kvm_host.h 
> >> b/arch/arm64/include/asm/kvm_host.h
> >> index 26a2347..dcecf92 100644
> >> --- a/arch/arm64/include/asm/kvm_host.h
> >> +++ b/arch/arm64/include/asm/kvm_host.h
> >> @@ -251,11 +251,11 @@ static inline void kvm_arch_hardware_unsetup(void) {}
> >>  static inline void kvm_arch_sync_events(struct kvm *kvm) {}
> >>  static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
> >>  static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
> >> -static inline void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu) {}
> >>  
> >>  void kvm_arm_init_debug(void);
> >>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
> >>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
> >>  void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
> >> +void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu);
> >>  
> >>  #endif /* __ARM64_KVM_HOST_H__ */
> >> diff --git a/arch/arm64/kernel/asm-offsets.c 
> >> b/arch/arm64/kernel/asm-offsets.c
> >> index 8d89cf8..c9c5242 100644
> >> --- a/arch/arm64/kernel/asm-offsets.c
> >> +++ b/arch/arm64/kernel/asm-offsets.c
> >> @@ -124,6 +124,7 @@ int main(void)
> >>DEFINE(VCPU_HCR_EL2,offsetof(struct kvm_vcpu, 
> >> arch.hcr_el2));
> >>DEFINE(VCPU_MDCR_EL2,   offsetof(struct kvm_vcpu, arch.mdcr_el2));
> >>DEFINE(VCPU_IRQ_LINES,  offsetof(struct kvm_vcpu, arch.irq_lines));
> >> +  DEFINE(VCPU_VFP_DIRTY,  offsetof(struct kvm_vcpu, arch.vfp_dirty));
> >>DEFINE(VCPU_HOST_CONTEXT,   offsetof(struct kvm_vcpu, 
> >> arch.host_cpu_context));
> >>DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, 
> >> arch.host_debug_state));
> >>DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, 
> >> arch.timer_cpu.cntv_ctl));
> >> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> >> index e583613..ed2c4cf 100644
> >> --- a/arch/arm64/kvm/hyp.S
> >> +++ b/arch/arm64/kvm/hyp.S
> >> @@ -36,6 +36,28 @@
> >>  #define CPU_SYSREG_OFFSET(x)  (CPU_SYSREGS + 8*x)
> >>  
> >>.text
> >> +
> >> +/**
> >> + * void kvm_restore_host_vfp_state(struct vcpu *vcpu) - Executes lazy
> >> + *fp/simd switch, saves the guest, restores host. Called from host
> >> + *mode, placed outside of hyp section.
> > 
> > same comments on style as previous patch
> Got it.
> > 
> >> + */
> >> +ENTRY(kvm_restore_host_vfp_state)
> >> +  pushxzr, lr
> >> +
> >> +  add x2, x0, #VCPU_CONTEXT
> >> +  mov w3, #0
> >> +  strbw3, [x0, #VCPU_VFP_DIRTY]
> > 
> > I've been discussing with myself if it would make more sense to clear
> > the dirty flag in the C-code...
> Since all the work is done here I placed it here.

yeah, that's what I thought first, but then I thought it's typically
easier to understand the logic in the C-code and this is technically a
side-effect from the name of the function "kvm_restore_host_vfp_state"
which should then be "kvm_restore_host_vfp_state_and_clear_dirty_flag"
:)

> > 
> >> +
> >> +  bl __save_fpsimd
> >> +
> >> +  ldr x2, [x0, #VCPU_HOST_CONTEXT]
> >> +  bl __restore_fpsimd
> >> +
> >> +  pop xzr, lr
> >> +  ret
> >> +ENDPROC(kvm_restore_host_vfp_state)
> >> +
> >>.pushsection.hyp.text, "ax"
> >>.align  PAGE_SHIFT
> >>  
> >> @@ -482,7 +504,11 @@
> >>  99:
> >>msr hcr_el2, x2
> >>mov x2, #CPTR_EL2_TTA
> >> +
> >> +  ldrbw3, [x0, #VCPU_VFP_DIRTY]
> >> +  tbnzw3, #0, 98f
> >

Re: [PATCH] KVM: arm: Fix crash in free_hyp_pgds() if timer initialization fails

2015-11-06 Thread Christoffer Dall
On Fri, Nov 06, 2015 at 12:32:51PM +0300, Pavel Fedin wrote:
>  Hello!
> 
> > > diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> > > index 7b42012..839dd970 100644
> > > --- a/arch/arm/kvm/mmu.c
> > > +++ b/arch/arm/kvm/mmu.c
> > > @@ -213,7 +213,10 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
> > >   kvm_tlb_flush_vmid_ipa(kvm, addr);
> > >
> > >   /* No need to invalidate the cache for device mappings 
> > > */
> > > - if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
> > > PAGE_S2_DEVICE)
> > > + if (((pte_val(old_pte) & PAGE_S2_DEVICE)
> > > +  != PAGE_S2_DEVICE) &&
> > > + ((pte_val(old_pte) & PAGE_HYP_DEVICE)
> > > +  != PAGE_HYP_DEVICE))
> > >   kvm_flush_dcache_pte(old_pte);
> > >
> > >   put_page(virt_to_page(pte));
> > > --
> > > 2.4.4
> > >
> > 
> > Did you check if PAGE_HYP_DEVICE can mean something sane on a stage-2
> > page table entry and vice verse?
> 
>  I tried to, the chain of macros and variables is complicated enough not to
> get 200% sure, but anyway PAGE_HYP_DEVICE (as well as PAGE_S2_DEVICE)
> includes PROT_PTE_DEVICE, so this is definitely device.
>  I even tried to construct some mask in order to make a single check for only
> DEVICE flags, but, to make things even less understandable and predictable,
> the same code with different bitfields is reused by ARM64. So, i thought that
> it will be more reliable just to add a second test.

The thing I want to avoid is PAGE_HYP_DEVICE covering some normal S2
mapping, which we *should* flush but that we now end up ignoring?  That
doesn't sound like it can be the case because the device bit is the same
bit for both types of page tables, correct?

> 
> > 
> > Also, the commit message and formatting here is horrible, see this
> > reworked version:
> 
> [skip]
> 
>  It's OK, to tell the truth the commit message is not that much important
> for me, but i know that sometimes these changes require good elaboration,
> so i included as much information as possible, together with crash
> backtrace. I've seen something like this in "git log" before.

The problem with your commit message was that it focused on the symptom
of the bug and how you saw it, instead of describing what the commit
does and why the patch is correct from a general point of view.

Think about your commit subject if you do "git log --oneline", then with
your version I would think, "that commit addresses some weird bug that
happens only in certain circumstances" as opposed to "this commit
modifies the unmapping logic".

>  Could you give me some directions on how to write better messages? And
> about formatting, IIRC i adhere to "75 chars per line" rule, and always
> (well, almost, unless forget to do so ;) ) run checkpatch.

For mail text, I think the convention is to use 72 chars per line.

For code, it's advisable to stick to 80 chars per line, unless it makes
the code absolutely imposible to read (in your original patch, you
should just have let the lines be 82 chars or whatever it came to if you
wanted to do it that way).

> 
> > diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> > index 6984342..f0c3aef 100644
> > --- a/arch/arm/kvm/mmu.c
> > +++ b/arch/arm/kvm/mmu.c
> > @@ -206,18 +206,20 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
> > 
> > start_pte = pte = pte_offset_kernel(pmd, addr);
> > do {
> > -   if (!pte_none(*pte)) {
> > -   pte_t old_pte = *pte;
> > +   if (pte_none(*pte))
> > +   continue;
> > 
> > -   kvm_set_pte(pte, __pte(0));
> > -   kvm_tlb_flush_vmid_ipa(kvm, addr);
> > +   pte_t old_pte = *pte;
> > 
> > -   /* No need to invalidate the cache for device mappings 
> > */
> > -   if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
> > PAGE_S2_DEVICE)
> > -   kvm_flush_dcache_pte(old_pte);
> > +   kvm_set_pte(pte, __pte(0));
> > +   kvm_tlb_flush_vmid_ipa(kvm, addr);
> > 
> > -   put_page(virt_to_page(pte));
> > -   }
> > +   /* No need to invalidate the cache for device mappings */
> > +   if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE &&
> > +   (pte_val(old_pte) & PAGE_HYP_DEVICE) != PAGE_HYP_DEVICE)
> > +   kvm_flush_dcache_pte(old_pte);
> > +
> > +   put_page(virt_to_page(pte));
> > } while (pte++, addr += PAGE_SIZE, addr != end);
> > 
> > if (kvm_pte_table_empty(kvm, start_pte))
> > --
> 
>  I see you inverted pte_none() check, and now kbuild bot complains about
> "mixed declarations and code".
> 
Yeah, that can be easily fixed though.  I just did it quickly to
illustrate my point.  I'll fix that up if we can agree on the
PAGE_HYP_DEVICE and PAGE_S2_DEVICE stuff above.

-Christoffer
--
To unsubscribe from this list: 

Re: [PATCH] KVM: arm: Fix crash in free_hyp_pgds() if timer initialization fails

2015-11-05 Thread Christoffer Dall
Hi Pavel,

On Tue, Oct 27, 2015 at 10:40:08AM +0300, Pavel Fedin wrote:
> After vGIC initialization succeeded, and timer initialization failed,
> the following crash can be observed on ARM32:
> 
> kvm [1]: interrupt-controller@10484000 IRQ57
> kvm [1]: kvm_arch_timer: can't find DT node
> Unable to handle kernel paging request at virtual address 90484000
> pgd = c0003000
> [90484000] *pgd=8040006003, *pmd=
> Internal error: Oops: 2a06 [#1] PREEMPT SMP ARM
> ...
> [] (v7_flush_kern_dcache_area) from [] 
> (kvm_flush_dcache_pte+0x48/0x5c)
> [] (kvm_flush_dcache_pte) from [] 
> (unmap_range+0x24c/0x460)
> [] (unmap_range) from [] (free_hyp_pgds+0x84/0x160)
> [] (free_hyp_pgds) from [] (kvm_arch_init+0x254/0x41c)
> [] (kvm_arch_init) from [] (kvm_init+0x28/0x2b4)
> [] (kvm_init) from [] (do_one_initcall+0x9c/0x200)
> 
> This happens when unmapping reaches mapped vGIC control registers. The
> problem root seems to be combination of two facts:
> 1. vGIC control region is defined in device trees as having size of
>0x2000. But the specification defines only registers up to 0x1FC,
>therefore it is only one page, not two.
> 2. unmap_ptes() is expected to recognize device memory and omit cache
>flushing. However, it tests only for PAGE_S2_DEVICE, while devices
>mapped for HYP mode have PAGE_HYP_DEVICE, which is different.
>Therefore, cache flush is attempted, and it dies when hitting the
>nonexistent second page.
> 
> This patch fixes the problem by adding missing recognition of
> PAGE_HYP_DEVICE protection value.
> 
> The crash can be observed on Exynos 5410 (and probably on all Exynos5
> family) with stock device trees (using MCT) and CONFIG_KVM enabled.
> 
> Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
> ---
>  arch/arm/kvm/mmu.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
> index 7b42012..839dd970 100644
> --- a/arch/arm/kvm/mmu.c
> +++ b/arch/arm/kvm/mmu.c
> @@ -213,7 +213,10 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
>   kvm_tlb_flush_vmid_ipa(kvm, addr);
>  
>   /* No need to invalidate the cache for device mappings 
> */
> - if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
> PAGE_S2_DEVICE)
> + if (((pte_val(old_pte) & PAGE_S2_DEVICE)
> +  != PAGE_S2_DEVICE) &&
> + ((pte_val(old_pte) & PAGE_HYP_DEVICE)
> +  != PAGE_HYP_DEVICE))
>   kvm_flush_dcache_pte(old_pte);
>  
>   put_page(virt_to_page(pte));
> -- 
> 2.4.4
> 

Did you check if PAGE_HYP_DEVICE can mean something sane on a stage-2
page table entry and vice verse?

Also, the commit message and formatting here is horrible, see this
reworked version:

>From e15700dd24419bb0e7ddc79feaa4efdf20304f2c Mon Sep 17 00:00:00 2001
From: Pavel Fedin <p.fe...@samsung.com>
Date: Tue, 27 Oct 2015 10:40:08 +0300
Subject: [PATCH] KVM: arm: Don't try to flush hyp-mode device mappings

The unmap_ptes function is currently called to unmap both Stage-2 and
Hyp mode page table entries.  Since calling clean and invalidate on
device memory may raise exceptions, we currently test against
PAGE_S2_DEVICE and do not flush for such mappings.  However, we should
also be testing against PAGE_HYP_DEVICE.

This fixes an issue observed on some 32-bit platforms, for example the
Exynos 5410.

Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/kvm/mmu.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 6984342..f0c3aef 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -206,18 +206,20 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
 
start_pte = pte = pte_offset_kernel(pmd, addr);
do {
-   if (!pte_none(*pte)) {
-   pte_t old_pte = *pte;
+   if (pte_none(*pte))
+   continue;
 
-   kvm_set_pte(pte, __pte(0));
-   kvm_tlb_flush_vmid_ipa(kvm, addr);
+   pte_t old_pte = *pte;
 
-   /* No need to invalidate the cache for device mappings 
*/
-   if ((pte_val(old_pte) & PAGE_S2_DEVICE) != 
PAGE_S2_DEVICE)
-   kvm_flush_dcache_pte(old_pte);
+   kvm_set_pte(pte, __pte(0));
+   kvm_tlb_flush_vmid_ipa(kvm, addr);
 
-   put_page(virt_to_page(pte));
-   }
+   /* No need to invalidate the cache for device mappings *

Re: [PATCH v3 2/3] KVM/arm/arm64: enable enhanced armv7 fp/simd lazy switch

2015-11-05 Thread Christoffer Dall
On Fri, Oct 30, 2015 at 02:56:32PM -0700, Mario Smarduch wrote:
> This patch tracks vfp/simd hardware state with a vcpu lazy flag. vCPU lazy 
> flag is set on guest access and traps to vfp/simd hardware switch handler. On 
> vm-enter if lazy flag is set skip trap enable and save host fpexc. On 
> vm-exit if flag is set skip hardware context switch and return to host with 
> guest context. In vcpu_put check if vcpu lazy flag is set, and execute a 
> hardware context switch to restore host.
> 
> Also some arm64 field and empty function are added to compile for arm64.
> 
> Signed-off-by: Mario Smarduch 
> ---
>  arch/arm/include/asm/kvm_host.h   |  1 +
>  arch/arm/kvm/arm.c|  6 
>  arch/arm/kvm/interrupts.S | 60 
> ---
>  arch/arm/kvm/interrupts_head.S| 14 +
>  arch/arm64/include/asm/kvm_host.h |  4 +++
>  5 files changed, 63 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index f1bf551..a9e86e0 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -227,6 +227,7 @@ int kvm_perf_teardown(void);
>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
>  
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
> +void kvm_restore_host_vfp_state(struct kvm_vcpu *);
>  
>  static inline void kvm_arch_hardware_disable(void) {}
>  static inline void kvm_arch_hardware_unsetup(void) {}
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index dc017ad..11a56fe 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -296,6 +296,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  {
>   /*
> +  * If fp/simd registers are dirty save guest, restore host before

If the fp/simd registers are dirty, then restore the host state before

> +  * releasing the cpu.
> +  */
> + if (vcpu->arch.vfp_dirty)
> + kvm_restore_host_vfp_state(vcpu);
> + /*
>* The arch-generic KVM code expects the cpu field of a vcpu to be -1
>* if the vcpu is no longer assigned to a cpu.  This is used for the
>* optimized make_all_cpus_request path.
> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
> index 900ef6d..ca25314 100644
> --- a/arch/arm/kvm/interrupts.S
> +++ b/arch/arm/kvm/interrupts.S
> @@ -28,6 +28,32 @@
>  #include "interrupts_head.S"
>  
>   .text
> +/**
> + * void kvm_restore_host_vfp_state(struct vcpu *vcpu) - Executes lazy

nit: Can you move the multi-line description of the function into a
separate paragraph?

> + *   fp/simd switch, saves the guest, restores host. Called from host
> + *   mode, placed outside of hyp region start/end.

Put the description in a separate paragraph and get rid of the "executes
lazy fp/simd swithch" part, that doesn't help understanding.  Just say
that this funciton restores the host state.

> + */
> +ENTRY(kvm_restore_host_vfp_state)
> +#ifdef CONFIG_VFPv3
> + push{r4-r7}
> +
> + add r7, vcpu, #VCPU_VFP_GUEST
> + store_vfp_state r7
> +
> + add r7, vcpu, #VCPU_VFP_HOST
> + ldr r7, [r7]
> + restore_vfp_state r7
> +
> + ldr r3, [vcpu, #VCPU_VFP_HOST_FPEXC]
> + VFPFMXR FPEXC, r3
> +
> + mov r3, #0
> + strbr3, [vcpu, #VCPU_VFP_DIRTY]
> +
> + pop {r4-r7}
> +#endif
> + bx  lr
> +ENDPROC(kvm_restore_host_vfp_state)
>  
>  __kvm_hyp_code_start:
>   .globl __kvm_hyp_code_start
> @@ -119,11 +145,16 @@ ENTRY(__kvm_vcpu_run)
>   @ If the host kernel has not been configured with VFPv3 support,
>   @ then it is safer if we deny guests from using it as well.
>  #ifdef CONFIG_VFPv3
> - @ Set FPEXC_EN so the guest doesn't trap floating point instructions
> + @ fp/simd register file has already been accessed, so skip host fpexc
> + @ save and access trap enable.
> + vfp_inlazy_mode r7, skip_guest_vfp_trap

So, why do we need to touch this register at all on every CPU exit?

Is it not true that we can only be in one of two state:
 1) The register file is not dirty (not touched by the guest) and we
should trap
 2) The register file is dirty, and we should not trap to EL2?

Only in the first case do we need to set the FPEXC, and couldn't we just
do that on vcpu_load and git rid of all this?  (except HCPTR_TCP which
we still need to adjust).

> +
>   VFPFMRX r2, FPEXC   @ VMRS
> - push{r2}
> + str r2, [vcpu, #VCPU_VFP_HOST_FPEXC]
>   orr r2, r2, #FPEXC_EN
>   VFPFMXR FPEXC, r2   @ VMSR
> + set_hcptr vmentry, (HCPTR_TCP(10) | HCPTR_TCP(11))
> +skip_guest_vfp_trap:
>  #endif
>  
>   @ Configure Hyp-role
> @@ -131,7 +162,7 @@ ENTRY(__kvm_vcpu_run)
>  
>   @ Trap coprocessor CRx accesses
>   set_hstr vmentry
> - set_hcptr vmentry, (HCPTR_TTA | HCPTR_TCP(10) | 

Re: [PATCH 3/3] KVM/arm64: enable enhanced armv8 fp/simd lazy switch

2015-11-05 Thread Christoffer Dall
On Fri, Oct 30, 2015 at 02:56:33PM -0700, Mario Smarduch wrote:
> This patch enables arm64 lazy fp/simd switch, similar to arm described in
> second patch. Change from previous version - restore function is moved to
> host. 
> 
> Signed-off-by: Mario Smarduch 
> ---
>  arch/arm64/include/asm/kvm_host.h |  2 +-
>  arch/arm64/kernel/asm-offsets.c   |  1 +
>  arch/arm64/kvm/hyp.S  | 37 +++--
>  3 files changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h 
> b/arch/arm64/include/asm/kvm_host.h
> index 26a2347..dcecf92 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -251,11 +251,11 @@ static inline void kvm_arch_hardware_unsetup(void) {}
>  static inline void kvm_arch_sync_events(struct kvm *kvm) {}
>  static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
>  static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
> -static inline void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu) {}
>  
>  void kvm_arm_init_debug(void);
>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
>  void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
> +void kvm_restore_host_vfp_state(struct kvm_vcpu *vcpu);
>  
>  #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 8d89cf8..c9c5242 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -124,6 +124,7 @@ int main(void)
>DEFINE(VCPU_HCR_EL2,   offsetof(struct kvm_vcpu, 
> arch.hcr_el2));
>DEFINE(VCPU_MDCR_EL2,  offsetof(struct kvm_vcpu, arch.mdcr_el2));
>DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
> +  DEFINE(VCPU_VFP_DIRTY, offsetof(struct kvm_vcpu, arch.vfp_dirty));
>DEFINE(VCPU_HOST_CONTEXT,  offsetof(struct kvm_vcpu, 
> arch.host_cpu_context));
>DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, 
> arch.host_debug_state));
>DEFINE(VCPU_TIMER_CNTV_CTL,offsetof(struct kvm_vcpu, 
> arch.timer_cpu.cntv_ctl));
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index e583613..ed2c4cf 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -36,6 +36,28 @@
>  #define CPU_SYSREG_OFFSET(x) (CPU_SYSREGS + 8*x)
>  
>   .text
> +
> +/**
> + * void kvm_restore_host_vfp_state(struct vcpu *vcpu) - Executes lazy
> + *   fp/simd switch, saves the guest, restores host. Called from host
> + *   mode, placed outside of hyp section.

same comments on style as previous patch

> + */
> +ENTRY(kvm_restore_host_vfp_state)
> + pushxzr, lr
> +
> + add x2, x0, #VCPU_CONTEXT
> + mov w3, #0
> + strbw3, [x0, #VCPU_VFP_DIRTY]

I've been discussing with myself if it would make more sense to clear
the dirty flag in the C-code...

> +
> + bl __save_fpsimd
> +
> + ldr x2, [x0, #VCPU_HOST_CONTEXT]
> + bl __restore_fpsimd
> +
> + pop xzr, lr
> + ret
> +ENDPROC(kvm_restore_host_vfp_state)
> +
>   .pushsection.hyp.text, "ax"
>   .align  PAGE_SHIFT
>  
> @@ -482,7 +504,11 @@
>  99:
>   msr hcr_el2, x2
>   mov x2, #CPTR_EL2_TTA
> +
> + ldrbw3, [x0, #VCPU_VFP_DIRTY]
> + tbnzw3, #0, 98f
>   orr x2, x2, #CPTR_EL2_TFP
> +98:

mmm, don't you need to only set the fpexc32 when you're actually going
to trap the guest accesses?

also, you can consider only setting this in vcpu_load (jumping quickly
to EL2 to do so) if we're running a 32-bit guest.  Probably worth
measuring the difference between the extra EL2 jump on vcpu_load
compared to hitting this register on every entry/exit.

Code-wise, it will be nicer to do it on vcpu_load.

>   msr cptr_el2, x2
>  
>   mov x2, #(1 << 15)  // Trap CP15 Cr=15
> @@ -669,14 +695,12 @@ __restore_debug:
>   ret
>  
>  __save_fpsimd:
> - skip_fpsimd_state x3, 1f
>   save_fpsimd
> -1:   ret
> + ret
>  
>  __restore_fpsimd:
> - skip_fpsimd_state x3, 1f
>   restore_fpsimd
> -1:   ret
> + ret
>  
>  switch_to_guest_fpsimd:
>   pushx4, lr
> @@ -688,6 +712,9 @@ switch_to_guest_fpsimd:
>  
>   mrs x0, tpidr_el2
>  
> + mov w2, #1
> + strbw2, [x0, #VCPU_VFP_DIRTY]

hmm, just noticing this.  Are you not writing a 32-bit value to a
potentially 8-bit field (ignoring padding in the struct), as the dirty
flag is declared a bool.

Are you also doing this on the 32-bit side?

> +
>   ldr x2, [x0, #VCPU_HOST_CONTEXT]
>   kern_hyp_va x2
>   bl __save_fpsimd
> @@ -763,7 +790,6 @@ __kvm_vcpu_return:
>   add x2, x0, #VCPU_CONTEXT
>  
>   save_guest_regs
> - bl __save_fpsimd
>   bl __save_sysregs
>  
>   skip_debug_state x3, 1f
> @@ -784,7 +810,6 @@ __kvm_vcpu_return:
>   kern_hyp_va x2
>  
>   bl __restore_sysregs
> - bl 

Re: [PATCH] KVM/arm: kernel low level debug support for ARM32 virtual platforms

2015-11-05 Thread Christoffer Dall
On Wed, Nov 04, 2015 at 07:51:58PM +0100, Ard Biesheuvel wrote:
> On 4 November 2015 at 19:49, Christopher Covington <c...@codeaurora.org> 
> wrote:
> > On 11/04/2015 08:31 AM, Christoffer Dall wrote:
> >> On Tue, Nov 03, 2015 at 01:39:44PM -0600, Rob Herring wrote:
> >>> On Tue, Nov 3, 2015 at 1:17 PM, Mario Smarduch <m.smard...@samsung.com> 
> >>> wrote:
> >>>> On 11/3/2015 9:55 AM, Will Deacon wrote:
> >>>>> On Tue, Nov 03, 2015 at 09:44:52AM -0800, Mario Smarduch wrote:
> >>>>>> On 11/3/2015 8:33 AM, Christopher Covington wrote:
> >>>>>>> On 11/02/2015 06:51 PM, Mario Smarduch wrote:
> >>>>>>>>this is a re-post from couple weeks ago, please take time to 
> >>>>>>>> review this
> >>>>>>>> simple patch which simplifies DEBUG_LL and prevents kernel crash on 
> >>>>>>>> virtual
> >>>>>>>> platforms.
> >>>>>>>>
> >>>>>>>> Before this patch DEBUG_LL for 'dummy virtual machine':
> >>>>>>>>
> >>>>>>>> ( ) Kernel low-level debugging via EmbeddedICE DCC channel
> >>>>>>>> ( ) Kernel low-level debug output via semihosting I/O
> >>>>>>>> ( ) Kernel low-level debugging via 8250 UART
> >>>>>>>> ( ) Kernel low-level debugging via ARM Ltd PL01x Primecell
> >>>>>>>>
> >>>>>>>> In summary if debug uart is not emulated kernel crashes.
> >>>>>>>> And once you pass that hurdle, uart physical/virtual addresses are 
> >>>>>>>> unknown.
> >>>>>>>> DEBUG_LL comes in handy on many occasions and should be somewhat
> >>>>>>>> intuitive to use like it is for physical platforms. For virtual 
> >>>>>>>> platforms
> >>>>>>>> user may start daubting the host and get into a bigger mess.
> >>>>>>>>
> >>>>>>>> After this patch is applied user gets:
> >>>>>>>>
> >>>>>>>> (X) Kernel low-level debugging on QEMU Virtual Platform
> >>>>>>>> ( ) Kernel low-level debugging on Kvmtool Virtual Platform
> >>>>>>>>. above repeated 
> >>>>>>>>
> >>>>>>>> The virtual addresses selected follow arm reference models, high in 
> >>>>>>>> vmalloc
> >>>>>>>> section with high mem enabled and guest running with >= 1GB of 
> >>>>>>>> memory. The
> >>>>>>>> offset is leftover from arm reference models.
> >>>>>>>
> >>>>>>> Which model? It doesn't appear to match the vexpress 
> >>>>>>> AEM/RTSM/FVP/whatever
> >>>>>>> which used 0x1c09 for UART0.
> >>>>>>
> >>>>>> I recall QEMU virt model had it's own physical address map, for sure I 
> >>>>>> saw the
> >>>>>> virtio-mmio regions assigned in some ARM document. Peter would you 
> >>>>>> know?
> >>>>>>
> >>>>>> As far as kvmtool I'm not sure, currently PC1 COM1 port is used? Andre 
> >>>>>> will that
> >>>>>> stay fixed?
> >>>>>
> >>>>> We make absolutely no guarantees about the memory map provided by 
> >>>>> kvmtool.
> >>>>
> >>>> If that's also the case for qemu, then I guess the best you can do is 
> >>>> find a way
> >>>> to dump the device tree. Find the uart, physical address and try figure 
> >>>> out the
> >>>> virtual address.
> >>>>
> >>>> Pretty involved, hoped for something more automated since that's a handy 
> >>>> feature.
> >>>
> >>> You really only need LL_DEBUG now if you are debugging very early code
> >>> before memory is setup and/or bad memory. Use earlycon instead which
> >>> should already be supported both via the pl011 or semihosting. I used
> >>> it with QEMU semihosting support.
> >>>
> >> Then we should really document how to use that with qemu's virt platform
> >> and kvmtool's platform on both 32-bit and 64-bit so that users can
> >> easily figure out what they're doing wrong when they get no output.
> >>
> >> In practice, the address for the pl011 is quite unlikely to change, I
> >> dare speculate, so that documentation shouldn't need frequent updating.
> >
> > Is it not on by default since the following change?
> >
> > http://git.qemu.org/?p=qemu.git;a=commitdiff;h=f022b8e95379b0433d13509706b66f38fc15dde8
> >
> 
> Yes, but it still requires the plain 'earlycon' argument (i.e, without
> '=pl011,...') to be passed on the kernel command line if you want
> early output.
> 
I didn't notice this. Cool!

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 08/21] arm/arm64: KVM: Support edge-triggered forwarded interrupts

2015-11-04 Thread 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: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 40 ++--
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 3c2909c..84abc6f 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1313,13 +1313,10 @@ epilog:
}
 }
 
-static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
+static int process_queued_irq(struct kvm_vcpu *vcpu,
+  int lr, struct vgic_lr vlr)
 {
-   int level_pending = 0;
-
-   vlr.state = 0;
-   vlr.hwirq = 0;
-   vgic_set_lr(vcpu, lr, vlr);
+   int pending = 0;
 
/*
 * If the IRQ was EOIed (called from vgic_process_maintenance) or it
@@ -1335,26 +1332,35 @@ static int process_level_irq(struct kvm_vcpu *vcpu, int 
lr, struct vgic_lr vlr)
vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
 
/*
-* Tell the gic to start sampling the line of this interrupt again.
+* Tell the gic to start sampling this interrupt again.
 */
vgic_irq_clear_queued(vcpu, vlr.irq);
 
/* Any additional pending interrupt? */
-   if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
-   vgic_cpu_irq_set(vcpu, vlr.irq);
-   level_pending = 1;
+   if (vgic_irq_is_edge(vcpu, vlr.irq)) {
+   BUG_ON(!(vlr.state & LR_HW));
+   pending = vgic_dist_irq_is_pending(vcpu, vlr.irq);
} else {
-   vgic_dist_irq_clear_pending(vcpu, vlr.irq);
-   vgic_cpu_irq_clear(vcpu, vlr.irq);
+   if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
+   vgic_cpu_irq_set(vcpu, vlr.irq);
+   pending = 1;
+   } else {
+   vgic_dist_irq_clear_pending(vcpu, vlr.irq);
+   vgic_cpu_irq_clear(vcpu, vlr.irq);
+   }
}
 
/*
 * Despite being EOIed, the LR may not have
 * been marked as empty.
 */
+   vlr.state = 0;
+   vlr.hwirq = 0;
+   vgic_set_lr(vcpu, lr, vlr);
+
vgic_sync_lr_elrsr(vcpu, lr, vlr);
 
-   return level_pending;
+   return pending;
 }
 
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
@@ -1391,7 +1397,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
 vlr.irq - VGIC_NR_PRIVATE_IRQS);
 
spin_lock(>lock);
-   level_pending |= process_level_irq(vcpu, lr, vlr);
+   level_pending |= process_queued_irq(vcpu, lr, vlr);
spin_unlock(>lock);
}
}
@@ -1413,7 +1419,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
 /*
  * Save the physical active state, and reset it to inactive.
  *
- * Return true if there's a pending level triggered interrupt line to queue.
+ * Return true if there's a pending forwarded interrupt to queue.
  */
 static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 {
@@ -1438,10 +1444,8 @@ static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int 
lr, struct vgic_lr vlr)
if (phys_active)
return 0;
 
-   /* Mapped edge-triggered interrupts not yet supported. */
-   WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
spin_lock(>lock);
-   level_pending = process_level_irq(vcpu, lr, vlr);
+   level_pending = process_queued_irq(vcpu, lr, vlr);
spin_unlock(>lock);
return level_pending;
 }
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 02/21] arm/arm64: KVM: arch_timer: Only schedule soft timer on vcpu_block

2015-11-04 Thread 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: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/include/asm/kvm_host.h   |  3 --
 arch/arm/kvm/arm.c| 10 +
 arch/arm64/include/asm/kvm_host.h |  3 --
 include/kvm/arm_arch_timer.h  |  2 +
 virt/kvm/arm/arch_timer.c | 94 +--
 5 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 84da979..c4072d9 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -234,7 +234,4 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu 
*vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
-static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
-
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 78b2869..7ed4d47 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -271,6 +271,16 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
return kvm_timer_should_fire(vcpu);
 }
 
+void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
+{
+   kvm_timer_schedule(vcpu);
+}
+
+void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
+{
+   kvm_timer_unschedule(vcpu);
+}
+
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 {
/* Force users to call KVM_ARM_VCPU_INIT */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e4f4d65..ed03968 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -255,7 +255,4 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
-static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
-
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index e1e4d7c..ef14cc1 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -71,5 +71,7 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid);
 int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value);
 
 bool kvm_timer_should_fire(struct kvm_vcpu *vcpu);
+void kvm_timer_schedule(struct kvm_vcpu *vcpu);
+void kvm_timer_unschedule(struct kvm_vcpu *vcpu);
 
 #endif
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index b9d3a32..32095fb 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -111,14 +111,21 @@ static enum hrtimer_restart kvm_timer_expire(struct 
hrtimer *hrt)
return HRTIMER_NORESTART;
 }
 
+static bool kvm_timer_irq_can_fire(struct kvm_vcpu *vcpu)
+{
+   struct arch_timer_cpu *timer = >arch.timer_cpu;
+
+   return !(timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) &&
+   (timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) &&
+   !kvm_vgic_get_phys_irq_active(timer->map);
+}
+
 bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 {
struct arch_timer_cpu *timer = >arch.timer_cpu;
cycle_t cval, now;
 
-   if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
-   !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
-   kvm_vgic_get_phys_irq_active(timer->map))
+   if (!kvm_timer_irq_can_fire(vcpu))
return false;
 
cval = timer->cntv_cval;
@@ -127,12 +134,57 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
return cval 

[PULL 00/21] KVM/ARM Changes for v4.4-rc1

2015-11-04 Thread Christoffer Dall
Hi Paolo,

Here is the set of changes for v4.4.  Some of the commits listed here were
already merged as fixes for v4.3, but since they are not in kvm/next yet, they
show up here.  Let me know if you want me to handle this differently somehow.

As usual, there's a lot of churn in the vgic and timer code, and then there are
number of smaller tweaks and adjustments.  Nothing major this time around.  For
a detailed description, see below.

The following changes since commit 920552b213e3dc832a874b4e7ba29ecddbab31bc:

  KVM: disable halt_poll_ns as default for s390x (2015-09-25 10:31:30 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git 
tags/kvm-arm-for-4.4

for you to fetch changes up to 26caea7693cb99833fe4ecc544c842289d6b3f69:

  KVM: arm/arm64: Merge vgic_set_lr() and vgic_sync_lr_elrsr() (2015-11-04 
15:29:49 +0100)


Thanks,
-Christoffer


KVM/ARM Changes for v4.4-rc1

Includes a number of fixes for the arch-timer, introducing proper
level-triggered semantics for the arch-timers, a series of patches to
synchronously halt a guest (prerequisite for IRQ forwarding), some tracepoint
improvements, a tweak for the EL2 panic handlers, some more VGIC cleanups
getting rid of redundant state, and finally a stylistic change that gets rid of
some ctags warnings.

Christoffer Dall (10):
  KVM: Add kvm_arch_vcpu_{un}blocking callbacks
  arm/arm64: KVM: arch_timer: Only schedule soft timer on vcpu_block
  arm/arm64: KVM: vgic: Factor out level irq processing on guest exit
  arm/arm64: KVM: Implement GICD_ICFGR as RO for PPIs
  arm/arm64: KVM: Use appropriate define in VGIC reset code
  arm/arm64: KVM: Add forwarded physical interrupts documentation
  arm/arm64: KVM: Rework the arch timer to use level-triggered semantics
  arm/arm64: KVM: Support edge-triggered forwarded interrupts
  arm/arm64: KVM: Improve kvm_exit tracepoint
  arm/arm64: KVM: Add tracepoints for vgic and timer

Eric Auger (4):
  KVM: arm/arm64: rename pause into power_off
  KVM: arm/arm64: check power_off in kvm_arch_vcpu_runnable
  KVM: arm/arm64: check power_off in critical section before VCPU run
  KVM: arm/arm64: implement kvm_arm_[halt,resume]_guest

Mark Rutland (1):
  arm64: kvm: restore EL1N SP for panic

Michal Marek (1):
  KVM: arm: Do not indent the arguments of DECLARE_BITMAP

Pavel Fedin (4):
  KVM: arm/arm64: Fix vGIC documentation
  KVM: arm/arm64: Optimize away redundant LR tracking
  KVM: arm/arm64: Clean up vgic_retire_lr() and surroundings
  KVM: arm/arm64: Merge vgic_set_lr() and vgic_sync_lr_elrsr()

Wei Huang (1):
  arm/arm64: KVM : Enable vhost device selection under KVM config menu

 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt | 187 +
 Documentation/virtual/kvm/devices/arm-vgic.txt |  18 +-
 arch/arm/include/asm/kvm_arm.h |  20 ++
 arch/arm/include/asm/kvm_host.h|   5 +-
 arch/arm/kvm/Kconfig   |   2 +
 arch/arm/kvm/arm.c |  76 +++--
 arch/arm/kvm/psci.c|  10 +-
 arch/arm/kvm/trace.h   |  10 +-
 arch/arm64/include/asm/kvm_arm.h   |  16 ++
 arch/arm64/include/asm/kvm_host.h  |   5 +-
 arch/arm64/kvm/Kconfig |   2 +
 arch/arm64/kvm/hyp.S   |   8 +
 arch/mips/include/asm/kvm_host.h   |   2 +
 arch/powerpc/include/asm/kvm_host.h|   2 +
 arch/s390/include/asm/kvm_host.h   |   2 +
 arch/x86/include/asm/kvm_host.h|   3 +
 include/kvm/arm_arch_timer.h   |   4 +-
 include/kvm/arm_vgic.h |  16 +-
 include/linux/kvm_host.h   |   2 +
 virt/kvm/arm/arch_timer.c  | 173 
 virt/kvm/arm/trace.h   |  63 +
 virt/kvm/arm/vgic-v2.c |   6 +-
 virt/kvm/arm/vgic-v3.c |   6 +-
 virt/kvm/arm/vgic.c| 308 -
 virt/kvm/kvm_main.c|   3 +
 25 files changed, 646 insertions(+), 303 deletions(-)
 create mode 100644 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
 create mode 100644 virt/kvm/arm/trace.h

-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/3] KVM: arm/arm64: Clean up some obsolete code

2015-11-04 Thread Christoffer Dall
On Tue, Nov 03, 2015 at 12:44:54PM +0300, Pavel Fedin wrote:
>  Hello!
> 
> >  By this time i'll make a very minimal version of patch 0001, for you to 
> > test it. If we have
> > problems with current 0001, which we
> > cannot solve quickly, we could stick to that version then, which will 
> > provide the necessary
> > changes to plug in LPIs, yet with
> > minimal changes (it will only remove vgic_irq_lr_map).
> >  I guess i should have done it before. Or, i could even respin v5, with 
> > current 0001 split up.
> > This should make it easier to bisect
> > the problem.
> 
>  So, i have just sent v5, conditions are the same as before. It is OK to stop 
> at any point, and actually you should be able to
> easily throw away 0003 and apply just 1, 2, 4. The minimum needed thing for 
> LPIs introduction is 0001.
>  You can also stick to v4 if the problem does not get triggered by its first 
> patch, if you prefer reduced commit log.
> 
Actually, I seem to have been just incredibly unlucky with my test
cycles, because I eventually reproduced the bug without your patches.

I'm going to take this version of the series because that's what I
reviewed and tested.

Sorry for the noise.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 04/21] arm/arm64: KVM: Implement GICD_ICFGR as RO for PPIs

2015-11-04 Thread 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: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 367a180..f8ca2e9 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -690,10 +690,9 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio 
*mmio,
vgic_reg_access(mmio, , offset,
ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
if (mmio->is_write) {
-   if (offset < 8) {
-   *reg = ~0U; /* Force PPIs/SGIs to 1 */
+   /* Ignore writes to read-only SGI and PPI bits */
+   if (offset < 8)
return false;
-   }
 
val = vgic_cfg_compress(val);
if (offset & 4) {
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 03/21] arm/arm64: KVM: vgic: Factor out level irq processing on guest exit

2015-11-04 Thread 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: Eric Auger <eric.au...@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 94 +++--
 1 file changed, 56 insertions(+), 38 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 66c6616..367a180 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -107,6 +107,7 @@ static struct vgic_lr vgic_get_lr(const struct kvm_vcpu 
*vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
 static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
int virt_irq);
+static int compute_pending_for_cpu(struct kvm_vcpu *vcpu);
 
 static const struct vgic_ops *vgic_ops;
 static const struct vgic_params *vgic;
@@ -357,6 +358,11 @@ static void vgic_dist_irq_clear_soft_pend(struct kvm_vcpu 
*vcpu, int irq)
struct vgic_dist *dist = >kvm->arch.vgic;
 
vgic_bitmap_set_irq_val(>irq_soft_pend, vcpu->vcpu_id, irq, 0);
+   if (!vgic_dist_irq_get_level(vcpu, irq)) {
+   vgic_dist_irq_clear_pending(vcpu, irq);
+   if (!compute_pending_for_cpu(vcpu))
+   clear_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
+   }
 }
 
 static int vgic_dist_irq_is_pending(struct kvm_vcpu *vcpu, int irq)
@@ -1338,12 +1344,56 @@ epilog:
}
 }
 
+static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
+{
+   int level_pending = 0;
+
+   vlr.state = 0;
+   vlr.hwirq = 0;
+   vgic_set_lr(vcpu, lr, vlr);
+
+   /*
+* If the IRQ was EOIed (called from vgic_process_maintenance) or it
+* went from active to non-active (called from vgic_sync_hwirq) it was
+* also ACKed and we we therefore assume we can clear the soft pending
+* state (should it had been set) for this interrupt.
+*
+* Note: if the IRQ soft pending state was set after the IRQ was
+* acked, it actually shouldn't be cleared, but we have no way of
+* knowing that unless we start trapping ACKs when the soft-pending
+* state is set.
+*/
+   vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
+
+   /*
+* Tell the gic to start sampling the line of this interrupt again.
+*/
+   vgic_irq_clear_queued(vcpu, vlr.irq);
+
+   /* Any additional pending interrupt? */
+   if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
+   vgic_cpu_irq_set(vcpu, vlr.irq);
+   level_pending = 1;
+   } else {
+   vgic_dist_irq_clear_pending(vcpu, vlr.irq);
+   vgic_cpu_irq_clear(vcpu, vlr.irq);
+   }
+
+   /*
+* Despite being EOIed, the LR may not have
+* been marked as empty.
+*/
+   vgic_sync_lr_elrsr(vcpu, lr, vlr);
+
+   return level_pending;
+}
+
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 {
u32 status = vgic_get_interrupt_status(vcpu);
struct vgic_dist *dist = >kvm->arch.vgic;
-   bool level_pending = false;
struct kvm *kvm = vcpu->kvm;
+   int level_pending = 0;
 
kvm_debug("STATUS = %08x\n", status);
 
@@ -1358,54 +1408,22 @@ static bool vgic_process_maintenance(struct kvm_vcpu 
*vcpu)
 
for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) {
struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
-   WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
 
-   spin_

[PULL 17/21] arm64: kvm: restore EL1N SP for panic

2015-11-04 Thread Christoffer Dall
From: Mark Rutland <mark.rutl...@arm.com>

If we panic in hyp mode, we inject a call to panic() into the EL1N host
kernel. If a guest context is active, we first attempt to restore the
minimal amount of state necessary to execute the host kernel with
restore_sysregs.

However, the SP is restored as part of restore_common_regs, and so we
may return to the host's panic() function with the SP of the guest. Any
calculations based on the SP will be bogus, and any attempt to access
the stack will result in recursive data aborts.

When running Linux as a guest, the guest's EL1N SP is like to be some
valid kernel address. In this case, the host kernel may use that region
as a stack for panic(), corrupting it in the process.

Avoid the problem by restoring the host SP prior to returning to the
host. To prevent misleading backtraces in the host, the FP is zeroed at
the same time. We don't need any of the other "common" registers in
order to panic successfully.

Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
Acked-by: Marc Zyngier <marc.zyng...@arm.com>
Cc: Christoffer Dall <christoffer.d...@linaro.org>
Cc: <kvm...@lists.cs.columbia.edu>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm64/kvm/hyp.S | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index e583613..1599701 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -880,6 +880,14 @@ __kvm_hyp_panic:
 
bl __restore_sysregs
 
+   /*
+* Make sure we have a valid host stack, and don't leave junk in the
+* frame pointer that will give us a misleading host stack unwinding.
+*/
+   ldr x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
+   msr sp_el1, x22
+   mov x29, xzr
+
 1: adr x0, __hyp_panic_str
adr x1, 2f
ldp x2, x3, [x1]
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 01/21] KVM: Add kvm_arch_vcpu_{un}blocking callbacks

2015-11-04 Thread 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: Marc Zyngier <marc.zyng...@arm.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/include/asm/kvm_host.h | 3 +++
 arch/arm64/include/asm/kvm_host.h   | 3 +++
 arch/mips/include/asm/kvm_host.h| 2 ++
 arch/powerpc/include/asm/kvm_host.h | 2 ++
 arch/s390/include/asm/kvm_host.h| 2 ++
 arch/x86/include/asm/kvm_host.h | 3 +++
 include/linux/kvm_host.h| 2 ++
 virt/kvm/kvm_main.c | 3 +++
 8 files changed, 20 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c4072d9..84da979 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -234,4 +234,7 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu 
*vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index ed03968..e4f4d65 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -255,4 +255,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 5a1a882..6ded8d3 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -847,5 +847,7 @@ static inline void kvm_arch_flush_shadow_memslot(struct kvm 
*kvm,
struct kvm_memory_slot *slot) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif /* __MIPS_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 827a38d..c9f122d 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -718,5 +718,7 @@ static inline void kvm_arch_memslots_updated(struct kvm 
*kvm, struct kvm_memslot
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_exit(void) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 8ced426..72a614c 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -644,5 +644,7 @@ static inline void kvm_arch_memslots_updated(struct kvm 
*kvm, struct kvm_memslot
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2beee03..b28f0f1 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1233,4 +1233,7 @@ int x86_set_memory_region(struct kvm *kvm,
 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
 bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 1bef9e2..4a86f5f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -625,6 +625,8 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, 
const void *data,
 void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
 
 void kvm_vcpu_block(struct kvm_vcpu *vcpu);
+void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu);
+void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu);
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
 int kvm_vcpu_yie

[PULL 14/21] KVM: arm/arm64: Fix vGIC documentation

2015-11-04 Thread Christoffer Dall
From: Pavel Fedin <p.fe...@samsung.com>

Correct some old mistakes in the API documentation:

1. VCPU is identified by index (using kvm_get_vcpu() function), but
   "cpu id" can be mistaken for affinity ID.
2. Some error codes are wrong.

  [ Slightly tweaked some grammer and did some s/CPU index/vcpu_index/
in the descriptions.  -Christoffer ]

Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 Documentation/virtual/kvm/devices/arm-vgic.txt | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt 
b/Documentation/virtual/kvm/devices/arm-vgic.txt
index 3fb9054..59541d4 100644
--- a/Documentation/virtual/kvm/devices/arm-vgic.txt
+++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
@@ -44,28 +44,29 @@ Groups:
   Attributes:
 The attr field of kvm_device_attr encodes two values:
 bits: | 63     40 | 39 ..  32  |  31   0 |
-values:   |reserved   |   cpu id   |  offset |
+values:   |reserved   | vcpu_index |  offset |
 
 All distributor regs are (rw, 32-bit)
 
 The offset is relative to the "Distributor base address" as defined in the
 GICv2 specs.  Getting or setting such a register has the same effect as
-reading or writing the register on the actual hardware from the cpu
-specified with cpu id field.  Note that most distributor fields are not
-banked, but return the same value regardless of the cpu id used to access
-the register.
+reading or writing the register on the actual hardware from the cpu whose
+index is specified with the vcpu_index field.  Note that most distributor
+fields are not banked, but return the same value regardless of the
+vcpu_index used to access the register.
   Limitations:
 - Priorities are not implemented, and registers are RAZ/WI
 - Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
   Errors:
--ENODEV: Getting or setting this register is not yet supported
+-ENXIO: Getting or setting this register is not yet supported
 -EBUSY: One or more VCPUs are running
+-EINVAL: Invalid vcpu_index supplied
 
   KVM_DEV_ARM_VGIC_GRP_CPU_REGS
   Attributes:
 The attr field of kvm_device_attr encodes two values:
 bits: | 63     40 | 39 ..  32  |  31   0 |
-values:   |reserved   |   cpu id   |  offset |
+values:   |reserved   | vcpu_index |  offset |
 
 All CPU interface regs are (rw, 32-bit)
 
@@ -91,8 +92,9 @@ Groups:
 - Priorities are not implemented, and registers are RAZ/WI
 - Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
   Errors:
--ENODEV: Getting or setting this register is not yet supported
+-ENXIO: Getting or setting this register is not yet supported
 -EBUSY: One or more VCPUs are running
+-EINVAL: Invalid vcpu_index supplied
 
   KVM_DEV_ARM_VGIC_GRP_NR_IRQS
   Attributes:
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 12/21] KVM: arm/arm64: check power_off in critical section before VCPU run

2015-11-04 Thread Christoffer Dall
From: Eric Auger <eric.au...@linaro.org>

In case a vcpu off PSCI call is called just after we executed the
vcpu_sleep check, we can enter the guest although power_off
is set. Let's check the power_off state in the critical section,
just before entering the guest.

Signed-off-by: Eric Auger <eric.au...@linaro.org>
Reported-by: Christoffer Dall <christoffer.d...@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.d...@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 arch/arm/kvm/arm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d04deeb..3b3384c 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -560,7 +560,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
run->exit_reason = KVM_EXIT_INTR;
}
 
-   if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
+   if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
+   vcpu->arch.power_off) {
local_irq_enable();
kvm_timer_sync_hwstate(vcpu);
kvm_vgic_sync_hwstate(vcpu);
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 19/21] KVM: arm/arm64: Optimize away redundant LR tracking

2015-11-04 Thread Christoffer Dall
From: Pavel Fedin <p.fe...@samsung.com>

Currently we use vgic_irq_lr_map in order to track which LRs hold which
IRQs, and lr_used bitmap in order to track which LRs are used or free.

vgic_irq_lr_map is actually used only for piggy-back optimization, and
can be easily replaced by iteration over lr_used. This is good because in
future, when LPI support is introduced, number of IRQs will grow up to at
least 16384, while numbers from 1024 to 8192 are never going to be used.
This would be a huge memory waste.

In its turn, lr_used is also completely redundant since
ae705930fca6322600690df9dc1c7d0516145a93 ("arm/arm64: KVM: Keep elrsr/aisr
in sync with software model"), because together with lr_used we also update
elrsr. This allows to easily replace lr_used with elrsr, inverting all
conditions (because in elrsr '1' means 'free').

Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 include/kvm/arm_vgic.h |  6 --
 virt/kvm/arm/vgic-v2.c |  1 +
 virt/kvm/arm/vgic-v3.c |  1 +
 virt/kvm/arm/vgic.c| 53 ++
 4 files changed, 17 insertions(+), 44 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 8065801..3936bf8 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -295,9 +295,6 @@ struct vgic_v3_cpu_if {
 };
 
 struct vgic_cpu {
-   /* per IRQ to LR mapping */
-   u8  *vgic_irq_lr_map;
-
/* Pending/active/both interrupts on this VCPU */
DECLARE_BITMAP(pending_percpu, VGIC_NR_PRIVATE_IRQS);
DECLARE_BITMAP(active_percpu, VGIC_NR_PRIVATE_IRQS);
@@ -308,9 +305,6 @@ struct vgic_cpu {
unsigned long   *active_shared;
unsigned long   *pend_act_shared;
 
-   /* Bitmap of used/free list registers */
-   DECLARE_BITMAP(lr_used, VGIC_V2_MAX_LRS);
-
/* Number of list registers on this CPU */
int nr_lr;
 
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index 8d7b04d..c0f5d7f 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -158,6 +158,7 @@ static void vgic_v2_enable(struct kvm_vcpu *vcpu)
 * anyway.
 */
vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
+   vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0;
 
/* Get the show on the road... */
vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index 7dd5d62..92003cb 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -193,6 +193,7 @@ static void vgic_v3_enable(struct kvm_vcpu *vcpu)
 * anyway.
 */
vgic_v3->vgic_vmcr = 0;
+   vgic_v3->vgic_elrsr = ~0;
 
/*
 * If we are emulating a GICv3, we do it in an non-GICv2-compatible
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index d4669eb..265a410 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -108,6 +108,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu 
*vcpu);
 static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
+static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu);
 static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
int virt_irq);
 static int compute_pending_for_cpu(struct kvm_vcpu *vcpu);
@@ -691,9 +692,11 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio 
*mmio,
 void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 {
struct vgic_cpu *vgic_cpu = >arch.vgic_cpu;
+   u64 elrsr = vgic_get_elrsr(vcpu);
+   unsigned long *elrsr_ptr = u64_to_bitmask();
int i;
 
-   for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
+   for_each_clear_bit(i, elrsr_ptr, vgic_cpu->nr_lr) {
struct vgic_lr lr = vgic_get_lr(vcpu, i);
 
/*
@@ -1098,7 +1101,6 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
 
 static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
 {
-   struct vgic_cpu *vgic_cpu = >arch.vgic_cpu;
struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
 
/*
@@ -1112,8 +1114,6 @@ static void vgic_retire_lr(int lr_nr, int irq, struct 
kvm_vcpu *vcpu)
 
vlr.state = 0;
vgic_set_lr(vcpu, lr_nr, vlr);
-   clear_bit(lr_nr, vgic_cpu->lr_used);
-   vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
 }
 
@@ -1128,10 +1128,11 @@ static void vgic_retire_lr(int lr_nr, int irq, struct 
kvm_vcpu *vcpu)
  */
 static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
 {
-   struct vgic_cpu *vgic_cpu = >arch.vgic_cpu;
+   u64 elrsr = vgic_get_elrsr(vcpu);
+   unsigned long *elrsr_ptr = u64_to_bitmask();
in

[PULL 18/21] KVM: arm: Do not indent the arguments of DECLARE_BITMAP

2015-11-04 Thread Christoffer Dall
From: Michal Marek <mma...@suse.com>

Besides being a coding style issue, it confuses make tags:

ctags: Warning: include/kvm/arm_vgic.h:307: null expansion of name pattern "\1"
ctags: Warning: include/kvm/arm_vgic.h:308: null expansion of name pattern "\1"
ctags: Warning: include/kvm/arm_vgic.h:309: null expansion of name pattern "\1"
ctags: Warning: include/kvm/arm_vgic.h:317: null expansion of name pattern "\1"

Cc: kvm...@lists.cs.columbia.edu
Signed-off-by: Michal Marek <mma...@suse.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 include/kvm/arm_vgic.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 7bc5d02..8065801 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -299,9 +299,9 @@ struct vgic_cpu {
u8  *vgic_irq_lr_map;
 
/* Pending/active/both interrupts on this VCPU */
-   DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
-   DECLARE_BITMAP( active_percpu, VGIC_NR_PRIVATE_IRQS);
-   DECLARE_BITMAP( pend_act_percpu, VGIC_NR_PRIVATE_IRQS);
+   DECLARE_BITMAP(pending_percpu, VGIC_NR_PRIVATE_IRQS);
+   DECLARE_BITMAP(active_percpu, VGIC_NR_PRIVATE_IRQS);
+   DECLARE_BITMAP(pend_act_percpu, VGIC_NR_PRIVATE_IRQS);
 
/* Pending/active/both shared interrupts, dynamically sized */
unsigned long   *pending_shared;
@@ -309,7 +309,7 @@ struct vgic_cpu {
unsigned long   *pend_act_shared;
 
/* Bitmap of used/free list registers */
-   DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
+   DECLARE_BITMAP(lr_used, VGIC_V2_MAX_LRS);
 
/* Number of list registers on this CPU */
int nr_lr;
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PULL 06/21] arm/arm64: KVM: Add forwarded physical interrupts documentation

2015-11-04 Thread Christoffer Dall
Forwarded physical interrupts on arm/arm64 is a tricky concept and the
way we deal with them is not apparently easy to understand by reading
various specs.

Therefore, add a proper documentation file explaining the flow and
rationale of the behavior of the vgic.

Some of this text was contributed by Marc Zyngier and edited by me.
Omissions and errors are all mine.

Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt | 187 +
 1 file changed, 187 insertions(+)
 create mode 100644 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt

diff --git a/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt 
b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
new file mode 100644
index 000..38bca28
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
@@ -0,0 +1,187 @@
+KVM/ARM VGIC Forwarded Physical Interrupts
+==
+
+The KVM/ARM code implements software support for the ARM Generic
+Interrupt Controller's (GIC's) hardware support for virtualization by
+allowing software to inject virtual interrupts to a VM, which the guest
+OS sees as regular interrupts.  The code is famously known as the VGIC.
+
+Some of these virtual interrupts, however, correspond to physical
+interrupts from real physical devices.  One example could be the
+architected timer, which itself supports virtualization, and therefore
+lets a guest OS program the hardware device directly to raise an
+interrupt at some point in time.  When such an interrupt is raised, the
+host OS initially handles the interrupt and must somehow signal this
+event as a virtual interrupt to the guest.  Another example could be a
+passthrough device, where the physical interrupts are initially handled
+by the host, but the device driver for the device lives in the guest OS
+and KVM must therefore somehow inject a virtual interrupt on behalf of
+the physical one to the guest OS.
+
+These virtual interrupts corresponding to a physical interrupt on the
+host are called forwarded physical interrupts, but are also sometimes
+referred to as 'virtualized physical interrupts' and 'mapped interrupts'.
+
+Forwarded physical interrupts are handled slightly differently compared
+to virtual interrupts generated purely by a software emulated device.
+
+
+The HW bit
+--
+Virtual interrupts are signalled to the guest by programming the List
+Registers (LRs) on the GIC before running a VCPU.  The LR is programmed
+with the virtual IRQ number and the state of the interrupt (Pending,
+Active, or Pending+Active).  When the guest ACKs and EOIs a virtual
+interrupt, the LR state moves from Pending to Active, and finally to
+inactive.
+
+The LRs include an extra bit, called the HW bit.  When this bit is set,
+KVM must also program an additional field in the LR, the physical IRQ
+number, to link the virtual with the physical IRQ.
+
+When the HW bit is set, KVM must EITHER set the Pending OR the Active
+bit, never both at the same time.
+
+Setting the HW bit causes the hardware to deactivate the physical
+interrupt on the physical distributor when the guest deactivates the
+corresponding virtual interrupt.
+
+
+Forwarded Physical Interrupts Life Cycle
+
+
+The state of forwarded physical interrupts is managed in the following way:
+
+  - The physical interrupt is acked by the host, and becomes active on
+the physical distributor (*).
+  - KVM sets the LR.Pending bit, because this is the only way the GICV
+interface is going to present it to the guest.
+  - LR.Pending will stay set as long as the guest has not acked the interrupt.
+  - LR.Pending transitions to LR.Active on the guest read of the IAR, as
+expected.
+  - On guest EOI, the *physical distributor* active bit gets cleared,
+but the LR.Active is left untouched (set).
+  - KVM clears the LR on VM exits when the physical distributor
+active state has been cleared.
+
+(*): The host handling is slightly more complicated.  For some forwarded
+interrupts (shared), KVM directly sets the active state on the physical
+distributor before entering the guest, because the interrupt is never actually
+handled on the host (see details on the timer as an example below).  For other
+forwarded interrupts (non-shared) the host does not deactivate the interrupt
+when the host ISR completes, but leaves the interrupt active until the guest
+deactivates it.  Leaving the interrupt active is allowed, because Linux
+configures the physical GIC with EOIMode=1, which causes EOI operations to
+perform a priority drop allowing the GIC to receive other interrupts of the
+default priority.
+
+
+Forwarded Edge and Level Triggered PPIs and SPIs
+
+Forwarded physical interrupts injected should always be active on the
+physical distributor when injected to a guest.
+
+Level-triggered interrupts will keep the int

[PULL 20/21] KVM: arm/arm64: Clean up vgic_retire_lr() and surroundings

2015-11-04 Thread Christoffer Dall
From: Pavel Fedin <p.fe...@samsung.com>

1. Remove unnecessary 'irq' argument, because irq number can be retrieved
   from the LR.
2. Since cff9211eb1a1f58ce7f5a2d596b617928fd4be0e
   ("arm/arm64: KVM: Fix arch timer behavior for disabled interrupts ")
   LR_STATE_PENDING is queued back by vgic_retire_lr() itself. Also, it
   clears vlr.state itself. Therefore, we remove the same, now duplicated,
   check with all accompanying bit manipulations from vgic_unqueue_irqs().
3. vgic_retire_lr() is always accompanied by vgic_irq_clear_queued(). Since
   it already does more than just clearing the LR, move
   vgic_irq_clear_queued() inside of it.

Signed-off-by: Pavel Fedin <p.fe...@samsung.com>
Signed-off-by: Christoffer Dall <christoffer.d...@linaro.org>
---
 virt/kvm/arm/vgic.c | 37 ++---
 1 file changed, 10 insertions(+), 27 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 265a410..96e45f3 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -105,7 +105,7 @@
 #include "vgic.h"
 
 static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
 static u64 vgic_get_elrsr(struct kvm_vcpu *vcpu);
@@ -717,30 +717,14 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 * interrupt then move the active state to the
 * distributor tracking bit.
 */
-   if (lr.state & LR_STATE_ACTIVE) {
+   if (lr.state & LR_STATE_ACTIVE)
vgic_irq_set_active(vcpu, lr.irq);
-   lr.state &= ~LR_STATE_ACTIVE;
-   }
 
/*
 * Reestablish the pending state on the distributor and the
-* CPU interface.  It may have already been pending, but that
-* is fine, then we are only setting a few bits that were
-* already set.
+* CPU interface and mark the LR as free for other use.
 */
-   if (lr.state & LR_STATE_PENDING) {
-   vgic_dist_irq_set_pending(vcpu, lr.irq);
-   lr.state &= ~LR_STATE_PENDING;
-   }
-
-   vgic_set_lr(vcpu, i, lr);
-
-   /*
-* Mark the LR as free for other use.
-*/
-   BUG_ON(lr.state & LR_STATE_MASK);
-   vgic_retire_lr(i, lr.irq, vcpu);
-   vgic_irq_clear_queued(vcpu, lr.irq);
+   vgic_retire_lr(i, vcpu);
 
/* Finally update the VGIC state. */
vgic_update_state(vcpu->kvm);
@@ -1099,16 +1083,18 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
vgic_ops->enable(vcpu);
 }
 
-static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
+static void vgic_retire_lr(int lr_nr, struct kvm_vcpu *vcpu)
 {
struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
 
+   vgic_irq_clear_queued(vcpu, vlr.irq);
+
/*
 * We must transfer the pending state back to the distributor before
 * retiring the LR, otherwise we may loose edge-triggered interrupts.
 */
if (vlr.state & LR_STATE_PENDING) {
-   vgic_dist_irq_set_pending(vcpu, irq);
+   vgic_dist_irq_set_pending(vcpu, vlr.irq);
vlr.hwirq = 0;
}
 
@@ -1135,11 +1121,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu 
*vcpu)
for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
 
-   if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
-   vgic_retire_lr(lr, vlr.irq, vcpu);
-   if (vgic_irq_is_queued(vcpu, vlr.irq))
-   vgic_irq_clear_queued(vcpu, vlr.irq);
-   }
+   if (!vgic_irq_is_enabled(vcpu, vlr.irq))
+   vgic_retire_lr(lr, vcpu);
}
 }
 
-- 
2.1.2.330.g565301e.dirty

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   7   8   9   10   >