linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 05/22] arm64: KVM: Implement vgic-v3 save/restore
Date: Mon, 07 Dec 2015 18:20:15 +0000	[thread overview]
Message-ID: <5665CDDF.3090201@arm.com> (raw)
In-Reply-To: <5665CA68.2000401@samsung.com>

On 07/12/15 18:05, Mario Smarduch wrote:
> 
> 
> On 12/7/2015 9:37 AM, Marc Zyngier wrote:
>> On 07/12/15 17:18, Mario Smarduch wrote:
>>>
>>>
>>> On 12/7/2015 8:52 AM, Marc Zyngier wrote:
>>>> Hi Mario,
>>>>
>>>> On 07/12/15 16:40, Mario Smarduch wrote:
>>>>> Hi Marc,
>>>>>
>>>>> On 12/7/2015 2:53 AM, Marc Zyngier wrote:
>>>>>> Implement the vgic-v3 save restore as a direct translation of
>>>>>> the assembly code version.
>>>>>>
>>>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>>>> ---
>>>>>>  arch/arm64/kvm/hyp/Makefile     |   1 +
>>>>>>  arch/arm64/kvm/hyp/hyp.h        |   3 +
>>>>>>  arch/arm64/kvm/hyp/vgic-v3-sr.c | 226 ++++++++++++++++++++++++++++++++++++++++
>>>>>>  3 files changed, 230 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 ac63553..5759f9f 100644
>>>>>> --- a/arch/arm64/kvm/hyp/hyp.h
>>>>>> +++ b/arch/arm64/kvm/hyp/hyp.h
>>>>>> @@ -32,5 +32,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 0000000..78d05f3
>>>>>> --- /dev/null
>>>>>> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
>>>>>> @@ -0,0 +1,226 @@
>>>>>> +/*
>>>>>> + * Copyright (C) 2012-2015 - ARM Ltd
>>>>>> + * Author: Marc Zyngier <marc.zyngier@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 <linux/compiler.h>
>>>>>> +#include <linux/irqchip/arm-gic-v3.h>
>>>>>> +#include <linux/kvm_host.h>
>>>>>> +
>>>>>> +#include <asm/kvm_mmu.h>
>>>>>> +
>>>>>> +#include "hyp.h"
>>>>>> +
>>>>>> +#define vtr_to_max_lr_idx(v)		((v) & 0xf)
>>>>>> +#define vtr_to_nr_pri_bits(v)		(((u32)(v) >> 29) + 1)
>>>>>> +
>>>>>> +#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)
>>>>>> +
>>>>>> +/* 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 = &vcpu->arch.vgic_cpu.vgic_v3;
>>>>>> +	u64 val;
>>>>>> +	u32 max_lr_idx, nr_pri_bits;
>>>>>> +
>>>>>> +	/*
>>>>>> +	 * 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);
>>>>>> +	max_lr_idx = vtr_to_max_lr_idx(val);
>>>>>> +	nr_pri_bits = vtr_to_nr_pri_bits(val);
>>>>>> +
>>>>> Can you setup a base pointer to cpu_if->vgic_lr and use an offset?
>>>>
>>>> I could, but I fail to see what we'd gain by using this (aside from
>>>> slightly shorter lines). Or am I completely missing the point?
>>>
>>> Skip adding the offset of vgic_lr to cpu_if pointer.
>>
>> But if we do that, we also change the layout that EL1 expect. Assume we
>> do something like this:
>>
>> u64 *current_lr = cpu_if->vgic_lr;
>>
>> switch (max_lr_idx) {
>> 	case 15:
>> 		current_lr++ = read_gicreg(ICH_LR15_EL2);
>> 	case 14:
>> 		current_lr++ = read_gicreg(ICH_LR14_EL2);
>> 	[...]
>> }
>>
> 
> I was thinking something like 'current_lr[VGIC_V3_LR_INDEX(...)]'.

That doesn't change anything, the compiler is perfectly able to 
optimize something like this:

[...]
ffffffc0007f31ac:       38624862        ldrb    w2, [x3,w2,uxtw]
ffffffc0007f31b0:       10000063        adr     x3, ffffffc0007f31bc <__vgic_v3_save_state+0x64>
ffffffc0007f31b4:       8b228862        add     x2, x3, w2, sxtb #2
ffffffc0007f31b8:       d61f0040        br      x2
ffffffc0007f31bc:       d53ccde2        mrs     x2, s3_4_c12_c13_7
ffffffc0007f31c0:       f9001c02        str     x2, [x0,#56]
ffffffc0007f31c4:       d53ccdc2        mrs     x2, s3_4_c12_c13_6
ffffffc0007f31c8:       f9002002        str     x2, [x0,#64]
ffffffc0007f31cc:       d53ccda2        mrs     x2, s3_4_c12_c13_5
ffffffc0007f31d0:       f9002402        str     x2, [x0,#72]
ffffffc0007f31d4:       d53ccd82        mrs     x2, s3_4_c12_c13_4
ffffffc0007f31d8:       f9002802        str     x2, [x0,#80]
ffffffc0007f31dc:       d53ccd62        mrs     x2, s3_4_c12_c13_3
ffffffc0007f31e0:       f9002c02        str     x2, [x0,#88]
ffffffc0007f31e4:       d53ccd42        mrs     x2, s3_4_c12_c13_2
ffffffc0007f31e8:       f9003002        str     x2, [x0,#96]
ffffffc0007f31ec:       d53ccd22        mrs     x2, s3_4_c12_c13_1
ffffffc0007f31f0:       f9003402        str     x2, [x0,#104]
ffffffc0007f31f4:       d53ccd02        mrs     x2, s3_4_c12_c13_0
ffffffc0007f31f8:       f9003802        str     x2, [x0,#112]
ffffffc0007f31fc:       d53ccce2        mrs     x2, s3_4_c12_c12_7
ffffffc0007f3200:       f9003c02        str     x2, [x0,#120]
ffffffc0007f3204:       d53cccc2        mrs     x2, s3_4_c12_c12_6
ffffffc0007f3208:       f9004002        str     x2, [x0,#128]
ffffffc0007f320c:       d53ccca2        mrs     x2, s3_4_c12_c12_5
ffffffc0007f3210:       f9004402        str     x2, [x0,#136]
ffffffc0007f3214:       d53ccc82        mrs     x2, s3_4_c12_c12_4
ffffffc0007f3218:       f9004802        str     x2, [x0,#144]
ffffffc0007f321c:       d53ccc62        mrs     x2, s3_4_c12_c12_3
ffffffc0007f3220:       f9004c02        str     x2, [x0,#152]
ffffffc0007f3224:       d53ccc42        mrs     x2, s3_4_c12_c12_2
ffffffc0007f3228:       f9005002        str     x2, [x0,#160]
ffffffc0007f322c:       d53ccc22        mrs     x2, s3_4_c12_c12_1
ffffffc0007f3230:       f9005402        str     x2, [x0,#168]
ffffffc0007f3234:       d53ccc02        mrs     x2, s3_4_c12_c12_0
ffffffc0007f3238:       7100183f        cmp     w1, #0x6
ffffffc0007f323c:       f9005802        str     x2, [x0,#176]

As you can see, this is as optimal as it gets, short of being able
to find a nice way to use more than one register...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2015-12-07 18:20 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-07 10:53 [PATCH v3 00/22] arm64: KVM: Rewriting the world switch in C Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 01/22] arm64: Add macros to read/write system registers Marc Zyngier
2015-12-07 17:35   ` Catalin Marinas
2015-12-07 17:45     ` Mark Rutland
2015-12-07 17:51       ` Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 02/22] arm64: KVM: Add a HYP-specific header file Marc Zyngier
2015-12-11 21:19   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 03/22] arm64: KVM: Implement vgic-v2 save/restore Marc Zyngier
2015-12-11 20:55   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 04/22] KVM: arm/arm64: vgic-v3: Make the LR indexing macro public Marc Zyngier
2015-12-11 20:57   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 05/22] arm64: KVM: Implement vgic-v3 save/restore Marc Zyngier
2015-12-07 16:40   ` Mario Smarduch
2015-12-07 16:52     ` Marc Zyngier
2015-12-07 17:18       ` Mario Smarduch
2015-12-07 17:37         ` Marc Zyngier
2015-12-07 18:05           ` Mario Smarduch
2015-12-07 18:20             ` Marc Zyngier [this message]
2015-12-08  2:14               ` Mario Smarduch
2015-12-08  8:19                 ` Marc Zyngier
2015-12-11 21:04   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 06/22] arm64: KVM: Implement timer save/restore Marc Zyngier
2015-12-08  2:18   ` Mario Smarduch
2015-12-08 10:02     ` Marc Zyngier
2015-12-11 21:20   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 07/22] arm64: KVM: Implement system register save/restore Marc Zyngier
2015-12-11  3:24   ` Mario Smarduch
2015-12-11 18:29     ` Marc Zyngier
2015-12-13  4:56       ` Mario Smarduch
2015-12-07 10:53 ` [PATCH v3 08/22] arm64: KVM: Implement 32bit " Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 09/22] arm64: KVM: Implement debug save/restore Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 10/22] arm64: KVM: Implement guest entry Marc Zyngier
2015-12-14 11:06   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 11/22] arm64: KVM: Add patchable function selector Marc Zyngier
2015-12-11 21:21   ` Christoffer Dall
2015-12-07 10:53 ` [PATCH v3 12/22] arm64: KVM: Implement the core world switch Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 13/22] arm64: KVM: Implement fpsimd save/restore Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 14/22] arm64: KVM: Implement TLB handling Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 15/22] arm64: KVM: HYP mode entry points Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 16/22] arm64: KVM: Add panic handling Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 17/22] arm64: KVM: Add compatibility aliases Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 18/22] arm64: KVM: Map the kernel RO section into HYP Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 19/22] arm64: KVM: Move away from the assembly version of the world switch Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 20/22] arm64: KVM: Turn system register numbers to an enum Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 21/22] arm64: KVM: Cleanup asm-offset.c Marc Zyngier
2015-12-07 10:53 ` [PATCH v3 22/22] arm64: KVM: Remove weak attributes Marc Zyngier
2015-12-14 11:07   ` Christoffer Dall

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=5665CDDF.3090201@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

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

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