Re: [PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-29 Thread Christoffer Dall
On Tue, Jan 27, 2015 at 01:44:05PM +, Marc Zyngier wrote:
> On 27/01/15 13:17, Christoffer Dall wrote:
> > On Tue, Jan 27, 2015 at 11:21:38AM +, Marc Zyngier wrote:
> >> On 26/01/15 22:58, Christoffer Dall wrote:
> >>> On Wed, Jan 21, 2015 at 06:39:46PM +, Marc Zyngier wrote:
>  Trying to emulate the behaviour of set/way cache ops is fairly
>  pointless, as there are too many ways we can end-up missing stuff.
>  Also, there is some system caches out there that simply ignore
>  set/way operations.
> 
>  So instead of trying to implement them, let's convert it to VA ops,
>  and use them as a way to re-enable the trapping of VM ops. That way,
>  we can detect the point when the MMU/caches are turned off, and do
>  a full VM flush (which is what the guest was trying to do anyway).
> 
>  This allows a 32bit zImage to boot on the APM thingy, and will
>  probably help bootloaders in general.
> 
>  Signed-off-by: Marc Zyngier 
> >>>
> >>> This had some conflicts with dirty page logging.  I fixed it up here,
> >>> and also removed some trailing white space and mixed spaces/tabs that
> >>> patch complained about:
> >>>
> >>> http://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git mm-fixes
> >>
> >> Thanks for doing so.
> >>
>  ---
>   arch/arm/include/asm/kvm_emulate.h   | 10 +
>   arch/arm/include/asm/kvm_host.h  |  3 --
>   arch/arm/include/asm/kvm_mmu.h   |  3 +-
>   arch/arm/kvm/arm.c   | 10 -
>   arch/arm/kvm/coproc.c| 64 ++
>   arch/arm/kvm/coproc_a15.c|  2 +-
>   arch/arm/kvm/coproc_a7.c |  2 +-
>   arch/arm/kvm/mmu.c   | 70 
>  -
>   arch/arm/kvm/trace.h | 39 +++
>   arch/arm64/include/asm/kvm_emulate.h | 10 +
>   arch/arm64/include/asm/kvm_host.h|  3 --
>   arch/arm64/include/asm/kvm_mmu.h |  3 +-
>   arch/arm64/kvm/sys_regs.c| 75 
>  +---
>   13 files changed, 155 insertions(+), 139 deletions(-)
> 
>  diff --git a/arch/arm/include/asm/kvm_emulate.h 
>  b/arch/arm/include/asm/kvm_emulate.h
>  index 66ce176..7b01523 100644
>  --- a/arch/arm/include/asm/kvm_emulate.h
>  +++ b/arch/arm/include/asm/kvm_emulate.h
>  @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu 
>  *vcpu)
>    vcpu->arch.hcr = HCR_GUEST_MASK;
>   }
> 
>  +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
>  +{
>  + return vcpu->arch.hcr;
>  +}
>  +
>  +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long 
>  hcr)
>  +{
>  + vcpu->arch.hcr = hcr;
>  +}
>  +
>   static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
>   {
>    return 1;
>  diff --git a/arch/arm/include/asm/kvm_host.h 
>  b/arch/arm/include/asm/kvm_host.h
>  index 254e065..04b4ea0 100644
>  --- a/arch/arm/include/asm/kvm_host.h
>  +++ b/arch/arm/include/asm/kvm_host.h
>  @@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
> * Anything that is not used directly from assembly code goes
> * here.
> */
>  - /* dcache set/way operation pending */
>  - int last_pcpu;
>  - cpumask_t require_dcache_flush;
> 
>    /* Don't run the guest on this vcpu */
>    bool pause;
>  diff --git a/arch/arm/include/asm/kvm_mmu.h 
>  b/arch/arm/include/asm/kvm_mmu.h
>  index 63e0ecc..286644c 100644
>  --- a/arch/arm/include/asm/kvm_mmu.h
>  +++ b/arch/arm/include/asm/kvm_mmu.h
>  @@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
>  kvm_vcpu *vcpu, hva_t hva,
> 
>   #define kvm_virt_to_phys(x)  virt_to_idmap((unsigned long)(x))
> 
>  -void stage2_flush_vm(struct kvm *kvm);
>  +void kvm_set_way_flush(struct kvm_vcpu *vcpu);
>  +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
> 
>   #endif   /* !__ASSEMBLY__ */
> 
>  diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>  index 2d6d910..0b0d58a 100644
>  --- a/arch/arm/kvm/arm.c
>  +++ b/arch/arm/kvm/arm.c
>  @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
>  cpu)
>    vcpu->cpu = cpu;
>    vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
> 
>  - /*
>  -  * Check whether this vcpu requires the cache to be flushed on
>  -  * this physical CPU. This is a consequence of doing dcache
>  -  * operations by set/way on this vcpu. We do it here to be in
>  -  * a non-preemptible section.
>  -  */
>  - if (cpumask_test_and_clear_cpu(cpu, 
>  &vcpu->arch.require_dcache_flush))

Re: [PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-27 Thread Marc Zyngier
On 27/01/15 13:17, Christoffer Dall wrote:
> On Tue, Jan 27, 2015 at 11:21:38AM +, Marc Zyngier wrote:
>> On 26/01/15 22:58, Christoffer Dall wrote:
>>> On Wed, Jan 21, 2015 at 06:39:46PM +, Marc Zyngier wrote:
 Trying to emulate the behaviour of set/way cache ops is fairly
 pointless, as there are too many ways we can end-up missing stuff.
 Also, there is some system caches out there that simply ignore
 set/way operations.

 So instead of trying to implement them, let's convert it to VA ops,
 and use them as a way to re-enable the trapping of VM ops. That way,
 we can detect the point when the MMU/caches are turned off, and do
 a full VM flush (which is what the guest was trying to do anyway).

 This allows a 32bit zImage to boot on the APM thingy, and will
 probably help bootloaders in general.

 Signed-off-by: Marc Zyngier 
>>>
>>> This had some conflicts with dirty page logging.  I fixed it up here,
>>> and also removed some trailing white space and mixed spaces/tabs that
>>> patch complained about:
>>>
>>> http://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git mm-fixes
>>
>> Thanks for doing so.
>>
 ---
  arch/arm/include/asm/kvm_emulate.h   | 10 +
  arch/arm/include/asm/kvm_host.h  |  3 --
  arch/arm/include/asm/kvm_mmu.h   |  3 +-
  arch/arm/kvm/arm.c   | 10 -
  arch/arm/kvm/coproc.c| 64 ++
  arch/arm/kvm/coproc_a15.c|  2 +-
  arch/arm/kvm/coproc_a7.c |  2 +-
  arch/arm/kvm/mmu.c   | 70 
 -
  arch/arm/kvm/trace.h | 39 +++
  arch/arm64/include/asm/kvm_emulate.h | 10 +
  arch/arm64/include/asm/kvm_host.h|  3 --
  arch/arm64/include/asm/kvm_mmu.h |  3 +-
  arch/arm64/kvm/sys_regs.c| 75 
 +---
  13 files changed, 155 insertions(+), 139 deletions(-)

 diff --git a/arch/arm/include/asm/kvm_emulate.h 
 b/arch/arm/include/asm/kvm_emulate.h
 index 66ce176..7b01523 100644
 --- a/arch/arm/include/asm/kvm_emulate.h
 +++ b/arch/arm/include/asm/kvm_emulate.h
 @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
   vcpu->arch.hcr = HCR_GUEST_MASK;
  }

 +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
 +{
 + return vcpu->arch.hcr;
 +}
 +
 +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
 +{
 + vcpu->arch.hcr = hcr;
 +}
 +
  static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
  {
   return 1;
 diff --git a/arch/arm/include/asm/kvm_host.h 
 b/arch/arm/include/asm/kvm_host.h
 index 254e065..04b4ea0 100644
 --- a/arch/arm/include/asm/kvm_host.h
 +++ b/arch/arm/include/asm/kvm_host.h
 @@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
* Anything that is not used directly from assembly code goes
* here.
*/
 - /* dcache set/way operation pending */
 - int last_pcpu;
 - cpumask_t require_dcache_flush;

   /* Don't run the guest on this vcpu */
   bool pause;
 diff --git a/arch/arm/include/asm/kvm_mmu.h 
 b/arch/arm/include/asm/kvm_mmu.h
 index 63e0ecc..286644c 100644
 --- a/arch/arm/include/asm/kvm_mmu.h
 +++ b/arch/arm/include/asm/kvm_mmu.h
 @@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
 kvm_vcpu *vcpu, hva_t hva,

  #define kvm_virt_to_phys(x)  virt_to_idmap((unsigned long)(x))

 -void stage2_flush_vm(struct kvm *kvm);
 +void kvm_set_way_flush(struct kvm_vcpu *vcpu);
 +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);

  #endif   /* !__ASSEMBLY__ */

 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index 2d6d910..0b0d58a 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
 cpu)
   vcpu->cpu = cpu;
   vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);

 - /*
 -  * Check whether this vcpu requires the cache to be flushed on
 -  * this physical CPU. This is a consequence of doing dcache
 -  * operations by set/way on this vcpu. We do it here to be in
 -  * a non-preemptible section.
 -  */
 - if (cpumask_test_and_clear_cpu(cpu, 
 &vcpu->arch.require_dcache_flush))
 - flush_cache_all(); /* We'd really want v7_flush_dcache_all() 
 */
 -
   kvm_arm_set_running_vcpu(vcpu);
  }

 @@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
 struct kvm_run *run)
   ret = kvm_call_hyp(__kvm_vcpu_run

Re: [PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-27 Thread Christoffer Dall
On Tue, Jan 27, 2015 at 11:21:38AM +, Marc Zyngier wrote:
> On 26/01/15 22:58, Christoffer Dall wrote:
> > On Wed, Jan 21, 2015 at 06:39:46PM +, Marc Zyngier wrote:
> >> Trying to emulate the behaviour of set/way cache ops is fairly
> >> pointless, as there are too many ways we can end-up missing stuff.
> >> Also, there is some system caches out there that simply ignore
> >> set/way operations.
> >>
> >> So instead of trying to implement them, let's convert it to VA ops,
> >> and use them as a way to re-enable the trapping of VM ops. That way,
> >> we can detect the point when the MMU/caches are turned off, and do
> >> a full VM flush (which is what the guest was trying to do anyway).
> >>
> >> This allows a 32bit zImage to boot on the APM thingy, and will
> >> probably help bootloaders in general.
> >>
> >> Signed-off-by: Marc Zyngier 
> > 
> > This had some conflicts with dirty page logging.  I fixed it up here,
> > and also removed some trailing white space and mixed spaces/tabs that
> > patch complained about:
> > 
> > http://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git mm-fixes
> 
> Thanks for doing so.
> 
> >> ---
> >>  arch/arm/include/asm/kvm_emulate.h   | 10 +
> >>  arch/arm/include/asm/kvm_host.h  |  3 --
> >>  arch/arm/include/asm/kvm_mmu.h   |  3 +-
> >>  arch/arm/kvm/arm.c   | 10 -
> >>  arch/arm/kvm/coproc.c| 64 ++
> >>  arch/arm/kvm/coproc_a15.c|  2 +-
> >>  arch/arm/kvm/coproc_a7.c |  2 +-
> >>  arch/arm/kvm/mmu.c   | 70 
> >> -
> >>  arch/arm/kvm/trace.h | 39 +++
> >>  arch/arm64/include/asm/kvm_emulate.h | 10 +
> >>  arch/arm64/include/asm/kvm_host.h|  3 --
> >>  arch/arm64/include/asm/kvm_mmu.h |  3 +-
> >>  arch/arm64/kvm/sys_regs.c| 75 
> >> +---
> >>  13 files changed, 155 insertions(+), 139 deletions(-)
> >>
> >> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> >> b/arch/arm/include/asm/kvm_emulate.h
> >> index 66ce176..7b01523 100644
> >> --- a/arch/arm/include/asm/kvm_emulate.h
> >> +++ b/arch/arm/include/asm/kvm_emulate.h
> >> @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
> >>   vcpu->arch.hcr = HCR_GUEST_MASK;
> >>  }
> >>
> >> +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
> >> +{
> >> + return vcpu->arch.hcr;
> >> +}
> >> +
> >> +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
> >> +{
> >> + vcpu->arch.hcr = hcr;
> >> +}
> >> +
> >>  static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
> >>  {
> >>   return 1;
> >> diff --git a/arch/arm/include/asm/kvm_host.h 
> >> b/arch/arm/include/asm/kvm_host.h
> >> index 254e065..04b4ea0 100644
> >> --- a/arch/arm/include/asm/kvm_host.h
> >> +++ b/arch/arm/include/asm/kvm_host.h
> >> @@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
> >>* Anything that is not used directly from assembly code goes
> >>* here.
> >>*/
> >> - /* dcache set/way operation pending */
> >> - int last_pcpu;
> >> - cpumask_t require_dcache_flush;
> >>
> >>   /* Don't run the guest on this vcpu */
> >>   bool pause;
> >> diff --git a/arch/arm/include/asm/kvm_mmu.h 
> >> b/arch/arm/include/asm/kvm_mmu.h
> >> index 63e0ecc..286644c 100644
> >> --- a/arch/arm/include/asm/kvm_mmu.h
> >> +++ b/arch/arm/include/asm/kvm_mmu.h
> >> @@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
> >> kvm_vcpu *vcpu, hva_t hva,
> >>
> >>  #define kvm_virt_to_phys(x)  virt_to_idmap((unsigned long)(x))
> >>
> >> -void stage2_flush_vm(struct kvm *kvm);
> >> +void kvm_set_way_flush(struct kvm_vcpu *vcpu);
> >> +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
> >>
> >>  #endif   /* !__ASSEMBLY__ */
> >>
> >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >> index 2d6d910..0b0d58a 100644
> >> --- a/arch/arm/kvm/arm.c
> >> +++ b/arch/arm/kvm/arm.c
> >> @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int 
> >> cpu)
> >>   vcpu->cpu = cpu;
> >>   vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
> >>
> >> - /*
> >> -  * Check whether this vcpu requires the cache to be flushed on
> >> -  * this physical CPU. This is a consequence of doing dcache
> >> -  * operations by set/way on this vcpu. We do it here to be in
> >> -  * a non-preemptible section.
> >> -  */
> >> - if (cpumask_test_and_clear_cpu(cpu, 
> >> &vcpu->arch.require_dcache_flush))
> >> - flush_cache_all(); /* We'd really want v7_flush_dcache_all() 
> >> */
> >> -
> >>   kvm_arm_set_running_vcpu(vcpu);
> >>  }
> >>
> >> @@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
> >> struct kvm_run *run)
> >>   ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
> >>
> >>   vcpu->mode =

Re: [PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-27 Thread Marc Zyngier
On 26/01/15 22:58, Christoffer Dall wrote:
> On Wed, Jan 21, 2015 at 06:39:46PM +, Marc Zyngier wrote:
>> Trying to emulate the behaviour of set/way cache ops is fairly
>> pointless, as there are too many ways we can end-up missing stuff.
>> Also, there is some system caches out there that simply ignore
>> set/way operations.
>>
>> So instead of trying to implement them, let's convert it to VA ops,
>> and use them as a way to re-enable the trapping of VM ops. That way,
>> we can detect the point when the MMU/caches are turned off, and do
>> a full VM flush (which is what the guest was trying to do anyway).
>>
>> This allows a 32bit zImage to boot on the APM thingy, and will
>> probably help bootloaders in general.
>>
>> Signed-off-by: Marc Zyngier 
> 
> This had some conflicts with dirty page logging.  I fixed it up here,
> and also removed some trailing white space and mixed spaces/tabs that
> patch complained about:
> 
> http://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git mm-fixes

Thanks for doing so.

>> ---
>>  arch/arm/include/asm/kvm_emulate.h   | 10 +
>>  arch/arm/include/asm/kvm_host.h  |  3 --
>>  arch/arm/include/asm/kvm_mmu.h   |  3 +-
>>  arch/arm/kvm/arm.c   | 10 -
>>  arch/arm/kvm/coproc.c| 64 ++
>>  arch/arm/kvm/coproc_a15.c|  2 +-
>>  arch/arm/kvm/coproc_a7.c |  2 +-
>>  arch/arm/kvm/mmu.c   | 70 -
>>  arch/arm/kvm/trace.h | 39 +++
>>  arch/arm64/include/asm/kvm_emulate.h | 10 +
>>  arch/arm64/include/asm/kvm_host.h|  3 --
>>  arch/arm64/include/asm/kvm_mmu.h |  3 +-
>>  arch/arm64/kvm/sys_regs.c| 75 
>> +---
>>  13 files changed, 155 insertions(+), 139 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_emulate.h 
>> b/arch/arm/include/asm/kvm_emulate.h
>> index 66ce176..7b01523 100644
>> --- a/arch/arm/include/asm/kvm_emulate.h
>> +++ b/arch/arm/include/asm/kvm_emulate.h
>> @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
>>   vcpu->arch.hcr = HCR_GUEST_MASK;
>>  }
>>
>> +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
>> +{
>> + return vcpu->arch.hcr;
>> +}
>> +
>> +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
>> +{
>> + vcpu->arch.hcr = hcr;
>> +}
>> +
>>  static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
>>  {
>>   return 1;
>> diff --git a/arch/arm/include/asm/kvm_host.h 
>> b/arch/arm/include/asm/kvm_host.h
>> index 254e065..04b4ea0 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
>>* Anything that is not used directly from assembly code goes
>>* here.
>>*/
>> - /* dcache set/way operation pending */
>> - int last_pcpu;
>> - cpumask_t require_dcache_flush;
>>
>>   /* Don't run the guest on this vcpu */
>>   bool pause;
>> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
>> index 63e0ecc..286644c 100644
>> --- a/arch/arm/include/asm/kvm_mmu.h
>> +++ b/arch/arm/include/asm/kvm_mmu.h
>> @@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
>> kvm_vcpu *vcpu, hva_t hva,
>>
>>  #define kvm_virt_to_phys(x)  virt_to_idmap((unsigned long)(x))
>>
>> -void stage2_flush_vm(struct kvm *kvm);
>> +void kvm_set_way_flush(struct kvm_vcpu *vcpu);
>> +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
>>
>>  #endif   /* !__ASSEMBLY__ */
>>
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 2d6d910..0b0d58a 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>>   vcpu->cpu = cpu;
>>   vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
>>
>> - /*
>> -  * Check whether this vcpu requires the cache to be flushed on
>> -  * this physical CPU. This is a consequence of doing dcache
>> -  * operations by set/way on this vcpu. We do it here to be in
>> -  * a non-preemptible section.
>> -  */
>> - if (cpumask_test_and_clear_cpu(cpu, &vcpu->arch.require_dcache_flush))
>> - flush_cache_all(); /* We'd really want v7_flush_dcache_all() */
>> -
>>   kvm_arm_set_running_vcpu(vcpu);
>>  }
>>
>> @@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
>> struct kvm_run *run)
>>   ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
>>
>>   vcpu->mode = OUTSIDE_GUEST_MODE;
>> - vcpu->arch.last_pcpu = smp_processor_id();
>>   kvm_guest_exit();
>>   trace_kvm_exit(*vcpu_pc(vcpu));
>>   /*
>> diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
>> index 7928dbd..0afcc00 100644
>> --- a/arch/arm/kvm/coproc.c
>> +++ b/arch/arm/k

Re: [PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-26 Thread Christoffer Dall
On Wed, Jan 21, 2015 at 06:39:46PM +, Marc Zyngier wrote:
> Trying to emulate the behaviour of set/way cache ops is fairly
> pointless, as there are too many ways we can end-up missing stuff.
> Also, there is some system caches out there that simply ignore
> set/way operations.
> 
> So instead of trying to implement them, let's convert it to VA ops,
> and use them as a way to re-enable the trapping of VM ops. That way,
> we can detect the point when the MMU/caches are turned off, and do
> a full VM flush (which is what the guest was trying to do anyway).
> 
> This allows a 32bit zImage to boot on the APM thingy, and will
> probably help bootloaders in general.
> 
> Signed-off-by: Marc Zyngier 

This had some conflicts with dirty page logging.  I fixed it up here,
and also removed some trailing white space and mixed spaces/tabs that
patch complained about:

http://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git mm-fixes

> ---
>  arch/arm/include/asm/kvm_emulate.h   | 10 +
>  arch/arm/include/asm/kvm_host.h  |  3 --
>  arch/arm/include/asm/kvm_mmu.h   |  3 +-
>  arch/arm/kvm/arm.c   | 10 -
>  arch/arm/kvm/coproc.c| 64 ++
>  arch/arm/kvm/coproc_a15.c|  2 +-
>  arch/arm/kvm/coproc_a7.c |  2 +-
>  arch/arm/kvm/mmu.c   | 70 -
>  arch/arm/kvm/trace.h | 39 +++
>  arch/arm64/include/asm/kvm_emulate.h | 10 +
>  arch/arm64/include/asm/kvm_host.h|  3 --
>  arch/arm64/include/asm/kvm_mmu.h |  3 +-
>  arch/arm64/kvm/sys_regs.c| 75 
> +---
>  13 files changed, 155 insertions(+), 139 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_emulate.h 
> b/arch/arm/include/asm/kvm_emulate.h
> index 66ce176..7b01523 100644
> --- a/arch/arm/include/asm/kvm_emulate.h
> +++ b/arch/arm/include/asm/kvm_emulate.h
> @@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
>   vcpu->arch.hcr = HCR_GUEST_MASK;
>  }
>  
> +static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
> +{
> + return vcpu->arch.hcr;
> +}
> +
> +static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
> +{
> + vcpu->arch.hcr = hcr;
> +}
> +
>  static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
>  {
>   return 1;
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 254e065..04b4ea0 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
>* Anything that is not used directly from assembly code goes
>* here.
>*/
> - /* dcache set/way operation pending */
> - int last_pcpu;
> - cpumask_t require_dcache_flush;
>  
>   /* Don't run the guest on this vcpu */
>   bool pause;
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 63e0ecc..286644c 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
> kvm_vcpu *vcpu, hva_t hva,
>  
>  #define kvm_virt_to_phys(x)  virt_to_idmap((unsigned long)(x))
>  
> -void stage2_flush_vm(struct kvm *kvm);
> +void kvm_set_way_flush(struct kvm_vcpu *vcpu);
> +void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
>  
>  #endif   /* !__ASSEMBLY__ */
>  
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 2d6d910..0b0d58a 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>   vcpu->cpu = cpu;
>   vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
>  
> - /*
> -  * Check whether this vcpu requires the cache to be flushed on
> -  * this physical CPU. This is a consequence of doing dcache
> -  * operations by set/way on this vcpu. We do it here to be in
> -  * a non-preemptible section.
> -  */
> - if (cpumask_test_and_clear_cpu(cpu, &vcpu->arch.require_dcache_flush))
> - flush_cache_all(); /* We'd really want v7_flush_dcache_all() */
> -
>   kvm_arm_set_running_vcpu(vcpu);
>  }
>  
> @@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
> kvm_run *run)
>   ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
>  
>   vcpu->mode = OUTSIDE_GUEST_MODE;
> - vcpu->arch.last_pcpu = smp_processor_id();
>   kvm_guest_exit();
>   trace_kvm_exit(*vcpu_pc(vcpu));
>   /*
> diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
> index 7928dbd..0afcc00 100644
> --- a/arch/arm/kvm/coproc.c
> +++ b/arch/arm/kvm/coproc.c
> @@ -189,82 +189,40 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
>   return true;
>  }
>  
> -/* See note at ARM ARM B1.14.4 */
> +/*
> + * See note at

[PATCH v3 1/3] arm/arm64: KVM: Use set/way op trapping to track the state of the caches

2015-01-21 Thread Marc Zyngier
Trying to emulate the behaviour of set/way cache ops is fairly
pointless, as there are too many ways we can end-up missing stuff.
Also, there is some system caches out there that simply ignore
set/way operations.

So instead of trying to implement them, let's convert it to VA ops,
and use them as a way to re-enable the trapping of VM ops. That way,
we can detect the point when the MMU/caches are turned off, and do
a full VM flush (which is what the guest was trying to do anyway).

This allows a 32bit zImage to boot on the APM thingy, and will
probably help bootloaders in general.

Signed-off-by: Marc Zyngier 
---
 arch/arm/include/asm/kvm_emulate.h   | 10 +
 arch/arm/include/asm/kvm_host.h  |  3 --
 arch/arm/include/asm/kvm_mmu.h   |  3 +-
 arch/arm/kvm/arm.c   | 10 -
 arch/arm/kvm/coproc.c| 64 ++
 arch/arm/kvm/coproc_a15.c|  2 +-
 arch/arm/kvm/coproc_a7.c |  2 +-
 arch/arm/kvm/mmu.c   | 70 -
 arch/arm/kvm/trace.h | 39 +++
 arch/arm64/include/asm/kvm_emulate.h | 10 +
 arch/arm64/include/asm/kvm_host.h|  3 --
 arch/arm64/include/asm/kvm_mmu.h |  3 +-
 arch/arm64/kvm/sys_regs.c| 75 +---
 13 files changed, 155 insertions(+), 139 deletions(-)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 66ce176..7b01523 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -38,6 +38,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
vcpu->arch.hcr = HCR_GUEST_MASK;
 }
 
+static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
+{
+   return vcpu->arch.hcr;
+}
+
+static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
+{
+   vcpu->arch.hcr = hcr;
+}
+
 static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
 {
return 1;
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 254e065..04b4ea0 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -125,9 +125,6 @@ struct kvm_vcpu_arch {
 * Anything that is not used directly from assembly code goes
 * here.
 */
-   /* dcache set/way operation pending */
-   int last_pcpu;
-   cpumask_t require_dcache_flush;
 
/* Don't run the guest on this vcpu */
bool pause;
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 63e0ecc..286644c 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -190,7 +190,8 @@ static inline void coherent_cache_guest_page(struct 
kvm_vcpu *vcpu, hva_t hva,
 
 #define kvm_virt_to_phys(x)virt_to_idmap((unsigned long)(x))
 
-void stage2_flush_vm(struct kvm *kvm);
+void kvm_set_way_flush(struct kvm_vcpu *vcpu);
+void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 2d6d910..0b0d58a 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -281,15 +281,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
vcpu->cpu = cpu;
vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
 
-   /*
-* Check whether this vcpu requires the cache to be flushed on
-* this physical CPU. This is a consequence of doing dcache
-* operations by set/way on this vcpu. We do it here to be in
-* a non-preemptible section.
-*/
-   if (cpumask_test_and_clear_cpu(cpu, &vcpu->arch.require_dcache_flush))
-   flush_cache_all(); /* We'd really want v7_flush_dcache_all() */
-
kvm_arm_set_running_vcpu(vcpu);
 }
 
@@ -541,7 +532,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
 
vcpu->mode = OUTSIDE_GUEST_MODE;
-   vcpu->arch.last_pcpu = smp_processor_id();
kvm_guest_exit();
trace_kvm_exit(*vcpu_pc(vcpu));
/*
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 7928dbd..0afcc00 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -189,82 +189,40 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
return true;
 }
 
-/* See note at ARM ARM B1.14.4 */
+/*
+ * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
+ */
 static bool access_dcsw(struct kvm_vcpu *vcpu,
const struct coproc_params *p,
const struct coproc_reg *r)
 {
-   unsigned long val;
-   int cpu;
-
if (!p->is_write)
return read_from_write_only(vcpu, p);
 
-   cpu = get_cpu();
-
-   cpumask_setall(&vcpu->arch.require_dcache_flush);
-   cpumask_clear_cpu(cpu, &vcpu->arch.require_