* [PATCH v9 1/5] arm64: arm_pmu: remove unnecessary isb instruction
2019-01-07 14:41 [PATCH v9 0/5] arm64: Support perf event modifiers :G and :H Andrew Murray
@ 2019-01-07 14:41 ` Andrew Murray
2019-01-07 14:41 ` [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data Andrew Murray
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Andrew Murray @ 2019-01-07 14:41 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Julien Thierry, kvmarm, linux-arm-kernel, Suzuki K Poulose
The armv8pmu_enable_event_counter function issues an isb instruction
after enabling a pair of counters - this doesn't provide any value
and is inconsistent with the armv8pmu_disable_event_counter.
In any case armv8pmu_enable_event_counter is always called with the
PMU stopped. Starting the PMU with armv8pmu_start results in an isb
instruction being issued prior to writing to PMCR_EL0.
Let's remove the unnecessary isb instruction.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
arch/arm64/kernel/perf_event.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 8e38d52..de564ae 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -652,7 +652,6 @@ static inline void armv8pmu_enable_event_counter(struct perf_event *event)
armv8pmu_enable_counter(idx);
if (armv8pmu_event_is_chained(event))
armv8pmu_enable_counter(idx - 1);
- isb();
}
static inline int armv8pmu_disable_counter(int idx)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data
2019-01-07 14:41 [PATCH v9 0/5] arm64: Support perf event modifiers :G and :H Andrew Murray
2019-01-07 14:41 ` [PATCH v9 1/5] arm64: arm_pmu: remove unnecessary isb instruction Andrew Murray
@ 2019-01-07 14:41 ` Andrew Murray
2019-01-10 11:36 ` Suzuki K Poulose
2019-01-07 14:41 ` [PATCH v9 3/5] arm64: KVM: add accessors to track guest/host only counters Andrew Murray
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Andrew Murray @ 2019-01-07 14:41 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Julien Thierry, kvmarm, linux-arm-kernel, Suzuki K Poulose
The virt/arm core allocates a kvm_cpu_context_t percpu, at present this is
a typedef to kvm_cpu_context and is used to store host cpu context. The
kvm_cpu_context structure is also used elsewhere to hold vcpu context.
In order to use the percpu to hold additional future host information we
encapsulate kvm_cpu_context in a new structure and rename the typedef and
percpu to match.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
arch/arm/include/asm/kvm_host.h | 8 ++++++--
arch/arm64/include/asm/kvm_asm.h | 4 ++--
arch/arm64/include/asm/kvm_host.h | 14 +++++++++-----
arch/arm64/kernel/asm-offsets.c | 2 +-
virt/kvm/arm/arm.c | 12 +++++++-----
5 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 79906ce..71645ba 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -145,7 +145,11 @@ struct kvm_cpu_context {
u32 cp15[NR_CP15_REGS];
};
-typedef struct kvm_cpu_context kvm_cpu_context_t;
+struct kvm_host_data {
+ struct kvm_cpu_context host_ctxt;
+};
+
+typedef struct kvm_host_data kvm_host_data_t;
struct kvm_vcpu_arch {
struct kvm_cpu_context ctxt;
@@ -163,7 +167,7 @@ struct kvm_vcpu_arch {
struct kvm_vcpu_fault_info fault;
/* Host FP context */
- kvm_cpu_context_t *host_cpu_context;
+ struct kvm_cpu_context *host_cpu_context;
/* VGIC state */
struct vgic_cpu vgic_cpu;
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 102b5a5..6a9bfd4 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -102,12 +102,12 @@ extern u32 __init_stage2_translation(void);
.endm
.macro get_host_ctxt reg, tmp
- hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
+ hyp_adr_this_cpu \reg, kvm_host_data, \tmp
.endm
.macro get_vcpu_ptr vcpu, ctxt
get_host_ctxt \ctxt, \vcpu
- ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU]
+ ldr \vcpu, [\ctxt, #HOST_DATA_VCPU]
kern_hyp_va \vcpu
.endm
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1550192..9ab4b13 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -205,7 +205,11 @@ struct kvm_cpu_context {
struct kvm_vcpu *__hyp_running_vcpu;
};
-typedef struct kvm_cpu_context kvm_cpu_context_t;
+struct kvm_host_data {
+ struct kvm_cpu_context host_ctxt;
+};
+
+typedef struct kvm_host_data kvm_host_data_t;
struct kvm_vcpu_arch {
struct kvm_cpu_context ctxt;
@@ -241,7 +245,7 @@ struct kvm_vcpu_arch {
struct kvm_guest_debug_arch external_debug_state;
/* Pointer to host CPU context */
- kvm_cpu_context_t *host_cpu_context;
+ struct kvm_cpu_context *host_cpu_context;
struct thread_info *host_thread_info; /* hyp VA */
struct user_fpsimd_state *host_fpsimd_state; /* hyp VA */
@@ -387,7 +391,7 @@ void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
-DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
+DECLARE_PER_CPU(kvm_host_data_t, kvm_host_data);
void __kvm_enable_ssbs(void);
@@ -400,8 +404,8 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
* kernel's mapping to the linear mapping, and store it in tpidr_el2
* so that we can use adr_l to access per-cpu variables in EL2.
*/
- u64 tpidr_el2 = ((u64)this_cpu_ptr(&kvm_host_cpu_state) -
- (u64)kvm_ksym_ref(kvm_host_cpu_state));
+ u64 tpidr_el2 = ((u64)this_cpu_ptr(&kvm_host_data) -
+ (u64)kvm_ksym_ref(kvm_host_data));
/*
* Call initialization code, and switch to the full blown HYP code.
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 323aeb5..cb968ff 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -142,7 +142,7 @@ int main(void)
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2]));
DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
- DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu));
+ DEFINE(HOST_DATA_VCPU, offsetof(struct kvm_host_data, host_ctxt.__hyp_running_vcpu));
#endif
#ifdef CONFIG_CPU_PM
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 150c8a6..160ab30 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -56,7 +56,7 @@
__asm__(".arch_extension virt");
#endif
-DEFINE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
+DEFINE_PER_CPU(kvm_host_data_t, kvm_host_data);
static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
/* Per-CPU variable containing the currently running vcpu. */
@@ -361,8 +361,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
int *last_ran;
+ kvm_host_data_t *cpu_data;
last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran);
+ cpu_data = this_cpu_ptr(&kvm_host_data);
/*
* We might get preempted before the vCPU actually runs, but
@@ -374,7 +376,7 @@ 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);
+ vcpu->arch.host_cpu_context = &cpu_data->host_ctxt;
kvm_arm_set_running_vcpu(vcpu);
kvm_vgic_load(vcpu);
@@ -1547,10 +1549,10 @@ static int init_hyp_mode(void)
}
for_each_possible_cpu(cpu) {
- kvm_cpu_context_t *cpu_ctxt;
+ kvm_host_data_t *cpu_data;
- cpu_ctxt = per_cpu_ptr(&kvm_host_cpu_state, cpu);
- err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1, PAGE_HYP);
+ cpu_data = per_cpu_ptr(&kvm_host_data, cpu);
+ err = create_hyp_mappings(cpu_data, cpu_data + 1, PAGE_HYP);
if (err) {
kvm_err("Cannot map host CPU state: %d\n", err);
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data
2019-01-07 14:41 ` [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data Andrew Murray
@ 2019-01-10 11:36 ` Suzuki K Poulose
2019-01-10 15:16 ` Andrew Murray
0 siblings, 1 reply; 9+ messages in thread
From: Suzuki K Poulose @ 2019-01-10 11:36 UTC (permalink / raw)
To: andrew.murray, christoffer.dall, marc.zyngier, catalin.marinas,
will.deacon, mark.rutland
Cc: kvmarm, linux-arm-kernel, julien.thierry
Hi Andrew,
On 07/01/2019 14:41, Andrew Murray wrote:
> The virt/arm core allocates a kvm_cpu_context_t percpu, at present this is
> a typedef to kvm_cpu_context and is used to store host cpu context. The
> kvm_cpu_context structure is also used elsewhere to hold vcpu context.
> In order to use the percpu to hold additional future host information we
> encapsulate kvm_cpu_context in a new structure and rename the typedef and
> percpu to match.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/arm/include/asm/kvm_host.h | 8 ++++++--
> arch/arm64/include/asm/kvm_asm.h | 4 ++--
> arch/arm64/include/asm/kvm_host.h | 14 +++++++++-----
> arch/arm64/kernel/asm-offsets.c | 2 +-
> virt/kvm/arm/arm.c | 12 +++++++-----
> 5 files changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 79906ce..71645ba 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -145,7 +145,11 @@ struct kvm_cpu_context {
> u32 cp15[NR_CP15_REGS];
> };
>
> -typedef struct kvm_cpu_context kvm_cpu_context_t;
> +struct kvm_host_data {
> + struct kvm_cpu_context host_ctxt;
> +};
> +
> +typedef struct kvm_host_data kvm_host_data_t;
>
> struct kvm_vcpu_arch {
> struct kvm_cpu_context ctxt;
> @@ -163,7 +167,7 @@ struct kvm_vcpu_arch {
> struct kvm_vcpu_fault_info fault;
>
> /* Host FP context */
> - kvm_cpu_context_t *host_cpu_context;
> + struct kvm_cpu_context *host_cpu_context;
>
> /* VGIC state */
> struct vgic_cpu vgic_cpu;
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 102b5a5..6a9bfd4 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -102,12 +102,12 @@ extern u32 __init_stage2_translation(void);
> .endm
>
> .macro get_host_ctxt reg, tmp
> - hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
> + hyp_adr_this_cpu \reg, kvm_host_data, \tmp
> .endm
minor nit: We now load "kvm_host_data" instead of the host_ctxt here,
even though they both are same. Do we need to make this explicitly load
the address of the host_ctxt member to make sure this doesn't break
with future changes to the structure ?
i.e,
add \reg, \reg, #HOST_DATA_CONTEXT
Otherwise,
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data
2019-01-10 11:36 ` Suzuki K Poulose
@ 2019-01-10 15:16 ` Andrew Murray
2019-01-14 12:07 ` Suzuki K Poulose
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Murray @ 2019-01-10 15:16 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: mark.rutland, julien.thierry, marc.zyngier, catalin.marinas,
will.deacon, christoffer.dall, kvmarm, linux-arm-kernel
On Thu, Jan 10, 2019 at 11:36:01AM +0000, Suzuki K Poulose wrote:
> Hi Andrew,
>
> On 07/01/2019 14:41, Andrew Murray wrote:
> > The virt/arm core allocates a kvm_cpu_context_t percpu, at present this is
> > a typedef to kvm_cpu_context and is used to store host cpu context. The
> > kvm_cpu_context structure is also used elsewhere to hold vcpu context.
> > In order to use the percpu to hold additional future host information we
> > encapsulate kvm_cpu_context in a new structure and rename the typedef and
> > percpu to match.
> >
> > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > ---
> > arch/arm/include/asm/kvm_host.h | 8 ++++++--
> > arch/arm64/include/asm/kvm_asm.h | 4 ++--
> > arch/arm64/include/asm/kvm_host.h | 14 +++++++++-----
> > arch/arm64/kernel/asm-offsets.c | 2 +-
> > virt/kvm/arm/arm.c | 12 +++++++-----
> > 5 files changed, 25 insertions(+), 15 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> > index 79906ce..71645ba 100644
> > --- a/arch/arm/include/asm/kvm_host.h
> > +++ b/arch/arm/include/asm/kvm_host.h
> > @@ -145,7 +145,11 @@ struct kvm_cpu_context {
> > u32 cp15[NR_CP15_REGS];
> > };
> > -typedef struct kvm_cpu_context kvm_cpu_context_t;
> > +struct kvm_host_data {
> > + struct kvm_cpu_context host_ctxt;
> > +};
> > +
> > +typedef struct kvm_host_data kvm_host_data_t;
> > struct kvm_vcpu_arch {
> > struct kvm_cpu_context ctxt;
> > @@ -163,7 +167,7 @@ struct kvm_vcpu_arch {
> > struct kvm_vcpu_fault_info fault;
> > /* Host FP context */
> > - kvm_cpu_context_t *host_cpu_context;
> > + struct kvm_cpu_context *host_cpu_context;
> > /* VGIC state */
> > struct vgic_cpu vgic_cpu;
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 102b5a5..6a9bfd4 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -102,12 +102,12 @@ extern u32 __init_stage2_translation(void);
> > .endm
> > .macro get_host_ctxt reg, tmp
> > - hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
> > + hyp_adr_this_cpu \reg, kvm_host_data, \tmp
> > .endm
>
> minor nit: We now load "kvm_host_data" instead of the host_ctxt here,
> even though they both are same. Do we need to make this explicitly load
> the address of the host_ctxt member to make sure this doesn't break
> with future changes to the structure ?
> i.e,
> add \reg, \reg, #HOST_DATA_CONTEXT
>
> Otherwise,
>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Thanks for spotting this.
Are you happy for me to add the Reviewed-by tag if I squash in the following?
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 6a9bfd4..f182d13 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -103,11 +103,12 @@ extern u32 __init_stage2_translation(void);
.macro get_host_ctxt reg, tmp
hyp_adr_this_cpu \reg, kvm_host_data, \tmp
+ add \reg, \reg, #HOST_DATA_CONTEXT
.endm
.macro get_vcpu_ptr vcpu, ctxt
get_host_ctxt \ctxt, \vcpu
- ldr \vcpu, [\ctxt, #HOST_DATA_VCPU]
+ ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU]
kern_hyp_va \vcpu
.endm
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index cb968ff..0deddfb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -142,7 +142,8 @@ int main(void)
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2]));
DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
- DEFINE(HOST_DATA_VCPU, offsetof(struct kvm_host_data, host_ctxt.__hyp_running_vcpu));
+ DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu));
+ DEFINE(HOST_DATA_CONTEXT, offsetof(struct kvm_host_data, host_ctxt));
#endif
#ifdef CONFIG_CPU_PM
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
Thanks,
Andrew Murray
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data
2019-01-10 15:16 ` Andrew Murray
@ 2019-01-14 12:07 ` Suzuki K Poulose
0 siblings, 0 replies; 9+ messages in thread
From: Suzuki K Poulose @ 2019-01-14 12:07 UTC (permalink / raw)
To: andrew.murray
Cc: mark.rutland, julien.thierry, marc.zyngier, catalin.marinas,
will.deacon, christoffer.dall, kvmarm, linux-arm-kernel
On 10/01/2019 15:16, Andrew Murray wrote:
> On Thu, Jan 10, 2019 at 11:36:01AM +0000, Suzuki K Poulose wrote:
>> Hi Andrew,
>>
>> On 07/01/2019 14:41, Andrew Murray wrote:
>>> The virt/arm core allocates a kvm_cpu_context_t percpu, at present this is
>>> a typedef to kvm_cpu_context and is used to store host cpu context. The
>>> kvm_cpu_context structure is also used elsewhere to hold vcpu context.
>>> In order to use the percpu to hold additional future host information we
>>> encapsulate kvm_cpu_context in a new structure and rename the typedef and
>>> percpu to match.
>>>
>>> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
>>> ---
>>> arch/arm/include/asm/kvm_host.h | 8 ++++++--
>>> arch/arm64/include/asm/kvm_asm.h | 4 ++--
>>> arch/arm64/include/asm/kvm_host.h | 14 +++++++++-----
>>> arch/arm64/kernel/asm-offsets.c | 2 +-
>>> virt/kvm/arm/arm.c | 12 +++++++-----
>>> 5 files changed, 25 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>>> index 79906ce..71645ba 100644
>>> --- a/arch/arm/include/asm/kvm_host.h
>>> +++ b/arch/arm/include/asm/kvm_host.h
>>> @@ -145,7 +145,11 @@ struct kvm_cpu_context {
>>> u32 cp15[NR_CP15_REGS];
>>> };
>>> -typedef struct kvm_cpu_context kvm_cpu_context_t;
>>> +struct kvm_host_data {
>>> + struct kvm_cpu_context host_ctxt;
>>> +};
>>> +
>>> +typedef struct kvm_host_data kvm_host_data_t;
>>> struct kvm_vcpu_arch {
>>> struct kvm_cpu_context ctxt;
>>> @@ -163,7 +167,7 @@ struct kvm_vcpu_arch {
>>> struct kvm_vcpu_fault_info fault;
>>> /* Host FP context */
>>> - kvm_cpu_context_t *host_cpu_context;
>>> + struct kvm_cpu_context *host_cpu_context;
>>> /* VGIC state */
>>> struct vgic_cpu vgic_cpu;
>>> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
>>> index 102b5a5..6a9bfd4 100644
>>> --- a/arch/arm64/include/asm/kvm_asm.h
>>> +++ b/arch/arm64/include/asm/kvm_asm.h
>>> @@ -102,12 +102,12 @@ extern u32 __init_stage2_translation(void);
>>> .endm
>>> .macro get_host_ctxt reg, tmp
>>> - hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
>>> + hyp_adr_this_cpu \reg, kvm_host_data, \tmp
>>> .endm
>>
>> minor nit: We now load "kvm_host_data" instead of the host_ctxt here,
>> even though they both are same. Do we need to make this explicitly load
>> the address of the host_ctxt member to make sure this doesn't break
>> with future changes to the structure ?
>> i.e,
>> add \reg, \reg, #HOST_DATA_CONTEXT
>>
>> Otherwise,
>>
>> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>
> Thanks for spotting this.
>
> Are you happy for me to add the Reviewed-by tag if I squash in the following?
Yes, that looks fine to me.
Cheers
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v9 3/5] arm64: KVM: add accessors to track guest/host only counters
2019-01-07 14:41 [PATCH v9 0/5] arm64: Support perf event modifiers :G and :H Andrew Murray
2019-01-07 14:41 ` [PATCH v9 1/5] arm64: arm_pmu: remove unnecessary isb instruction Andrew Murray
2019-01-07 14:41 ` [PATCH v9 2/5] arm64: KVM: encapsulate kvm_cpu_context in kvm_host_data Andrew Murray
@ 2019-01-07 14:41 ` Andrew Murray
2019-01-07 14:41 ` [PATCH v9 4/5] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes Andrew Murray
2019-01-07 14:41 ` [PATCH v9 5/5] arm64: KVM: Enable support for :G/:H perf event modifiers Andrew Murray
4 siblings, 0 replies; 9+ messages in thread
From: Andrew Murray @ 2019-01-07 14:41 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Julien Thierry, kvmarm, linux-arm-kernel, Suzuki K Poulose
In order to effeciently enable/disable guest/host only perf counters
at guest entry/exit we add bitfields to kvm_cpu_context for guest and
host events as well as accessors for updating them.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/kvm_host.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 9ab4b13..50f9d4c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -205,8 +205,14 @@ struct kvm_cpu_context {
struct kvm_vcpu *__hyp_running_vcpu;
};
+struct kvm_pmu_events {
+ u32 events_host;
+ u32 events_guest;
+};
+
struct kvm_host_data {
struct kvm_cpu_context host_ctxt;
+ struct kvm_pmu_events pmu_events;
};
typedef struct kvm_host_data kvm_host_data_t;
@@ -471,11 +477,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
+#define KVM_PMU_EVENTS_HOST 1
+#define KVM_PMU_EVENTS_GUEST 2
+
#ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
{
return kvm_arch_vcpu_run_map_fp(vcpu);
}
+static inline void kvm_set_pmu_events(u32 set, int flags)
+{
+ struct kvm_host_data *ctx = this_cpu_ptr(&kvm_host_data);
+
+ if (flags & KVM_PMU_EVENTS_HOST)
+ ctx->pmu_events.events_host |= set;
+ if (flags & KVM_PMU_EVENTS_GUEST)
+ ctx->pmu_events.events_guest |= set;
+}
+static inline void kvm_clr_pmu_events(u32 clr)
+{
+ struct kvm_host_data *ctx = this_cpu_ptr(&kvm_host_data);
+
+ ctx->pmu_events.events_host &= ~clr;
+ ctx->pmu_events.events_guest &= ~clr;
+}
+#else
+static inline void kvm_set_pmu_events(u32 set, int flags) {}
+static inline void kvm_clr_pmu_events(u32 clr) {}
#endif
static inline void kvm_arm_vhe_guest_enter(void)
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v9 4/5] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes
2019-01-07 14:41 [PATCH v9 0/5] arm64: Support perf event modifiers :G and :H Andrew Murray
` (2 preceding siblings ...)
2019-01-07 14:41 ` [PATCH v9 3/5] arm64: KVM: add accessors to track guest/host only counters Andrew Murray
@ 2019-01-07 14:41 ` Andrew Murray
2019-01-07 14:41 ` [PATCH v9 5/5] arm64: KVM: Enable support for :G/:H perf event modifiers Andrew Murray
4 siblings, 0 replies; 9+ messages in thread
From: Andrew Murray @ 2019-01-07 14:41 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Julien Thierry, kvmarm, linux-arm-kernel, Suzuki K Poulose
Add support for the :G and :H attributes in perf by handling the
exclude_host/exclude_guest event attributes.
We notify KVM of counters that we wish to be enabled or disabled on
guest entry/exit and thus defer from starting or stopping :G events
as per the events exclude_host attribute.
With both VHE and non-VHE we switch the counters between host/guest
at EL2. We are able to eliminate counters counting host events on
the boundaries of guest entry/exit when using :G by filtering out
EL2 for exclude_host. However when using :H unless exclude_hv is set
on non-VHE then there is a small blackout window at the guest
entry/exit where host events are not captured.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kernel/perf_event.c | 53 ++++++++++++++++++++++++++++++++++++------
1 file changed, 46 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index de564ae..64dde86 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -26,6 +26,7 @@
#include <linux/acpi.h>
#include <linux/clocksource.h>
+#include <linux/kvm_host.h>
#include <linux/of.h>
#include <linux/perf/arm_pmu.h>
#include <linux/platform_device.h>
@@ -647,11 +648,27 @@ static inline int armv8pmu_enable_counter(int idx)
static inline void armv8pmu_enable_event_counter(struct perf_event *event)
{
+ struct perf_event_attr *attr = &event->attr;
int idx = event->hw.idx;
+ int flags = 0;
+ u32 counter_bits = BIT(ARMV8_IDX_TO_COUNTER(idx));
- armv8pmu_enable_counter(idx);
if (armv8pmu_event_is_chained(event))
- armv8pmu_enable_counter(idx - 1);
+ counter_bits |= BIT(ARMV8_IDX_TO_COUNTER(idx - 1));
+
+ if (!attr->exclude_host)
+ flags |= KVM_PMU_EVENTS_HOST;
+ if (!attr->exclude_guest)
+ flags |= KVM_PMU_EVENTS_GUEST;
+
+ kvm_set_pmu_events(counter_bits, flags);
+
+ /* We rely on the hypervisor switch code to enable guest counters */
+ if (!attr->exclude_host) {
+ armv8pmu_enable_counter(idx);
+ if (armv8pmu_event_is_chained(event))
+ armv8pmu_enable_counter(idx - 1);
+ }
}
static inline int armv8pmu_disable_counter(int idx)
@@ -664,11 +681,21 @@ static inline int armv8pmu_disable_counter(int idx)
static inline void armv8pmu_disable_event_counter(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
+ struct perf_event_attr *attr = &event->attr;
int idx = hwc->idx;
+ u32 counter_bits = BIT(ARMV8_IDX_TO_COUNTER(idx));
if (armv8pmu_event_is_chained(event))
- armv8pmu_disable_counter(idx - 1);
- armv8pmu_disable_counter(idx);
+ counter_bits |= BIT(ARMV8_IDX_TO_COUNTER(idx - 1));
+
+ kvm_clr_pmu_events(counter_bits);
+
+ /* We rely on the hypervisor switch code to disable guest counters */
+ if (!attr->exclude_host) {
+ if (armv8pmu_event_is_chained(event))
+ armv8pmu_disable_counter(idx - 1);
+ armv8pmu_disable_counter(idx);
+ }
}
static inline int armv8pmu_enable_intens(int idx)
@@ -943,16 +970,25 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event,
* Therefore we ignore exclude_hv in this configuration, since
* there's no hypervisor to sample anyway. This is consistent
* with other architectures (x86 and Power).
+ *
+ * To eliminate counting host events on the boundaries of
+ * guest entry/exit we ensure EL2 is not included in hyp mode
+ * with !exclude_host.
*/
if (is_kernel_in_hyp_mode()) {
- if (!attr->exclude_kernel)
+ if (!attr->exclude_kernel && !attr->exclude_host)
config_base |= ARMV8_PMU_INCLUDE_EL2;
} else {
- if (attr->exclude_kernel)
- config_base |= ARMV8_PMU_EXCLUDE_EL1;
if (!attr->exclude_hv)
config_base |= ARMV8_PMU_INCLUDE_EL2;
}
+
+ /*
+ * Filter out !VHE kernels and guest kernels
+ */
+ if (attr->exclude_kernel)
+ config_base |= ARMV8_PMU_EXCLUDE_EL1;
+
if (attr->exclude_user)
config_base |= ARMV8_PMU_EXCLUDE_EL0;
@@ -976,6 +1012,9 @@ static void armv8pmu_reset(void *info)
armv8pmu_disable_intens(idx);
}
+ /* Clear the counters we flip at guest entry/exit */
+ kvm_clr_pmu_events(U32_MAX);
+
/*
* Initialize & Reset PMNC. Request overflow interrupt for
* 64 bit cycle counter but cheat in armv8pmu_write_counter().
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v9 5/5] arm64: KVM: Enable support for :G/:H perf event modifiers
2019-01-07 14:41 [PATCH v9 0/5] arm64: Support perf event modifiers :G and :H Andrew Murray
` (3 preceding siblings ...)
2019-01-07 14:41 ` [PATCH v9 4/5] arm64: arm_pmu: Add support for exclude_host/exclude_guest attributes Andrew Murray
@ 2019-01-07 14:41 ` Andrew Murray
4 siblings, 0 replies; 9+ messages in thread
From: Andrew Murray @ 2019-01-07 14:41 UTC (permalink / raw)
To: Christoffer Dall, Marc Zyngier, Catalin Marinas, Will Deacon,
Mark Rutland
Cc: Julien Thierry, kvmarm, linux-arm-kernel, Suzuki K Poulose
Enable/disable event counters as appropriate when entering and exiting
the guest to enable support for guest or host only event counting.
For both VHE and non-VHE we switch the counters between host/guest at
EL2. EL2 is filtered out by the PMU when we are using the :G modifier.
The PMU may be on when we change which counters are enabled however
we avoid adding an isb as we instead rely on existing context
synchronisation events: the isb in kvm_arm_vhe_guest_exit for VHE and
the eret from the hvc in kvm_call_hyp.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arch/arm64/kvm/hyp/switch.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index d496ef5..bec6521 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -373,6 +373,54 @@ static bool __hyp_text __hyp_switch_fpsimd(struct kvm_vcpu *vcpu)
return true;
}
+static bool __hyp_text __pmu_switch_to_guest(struct kvm_cpu_context *host_ctxt)
+{
+ struct kvm_host_data *host;
+ struct kvm_pmu_events *pmu;
+ u32 clr, set;
+
+ host = container_of(host_ctxt, struct kvm_host_data, host_ctxt);
+ pmu = &host->pmu_events;
+
+ /* We can potentially avoid a sysreg write by only changing bits that
+ * differ between the guest/host. E.g. where events are enabled in
+ * both guest and host
+ */
+ clr = pmu->events_host & ~pmu->events_guest;
+ set = pmu->events_guest & ~pmu->events_host;
+
+ if (clr)
+ write_sysreg(clr, pmcntenclr_el0);
+
+ if (set)
+ write_sysreg(set, pmcntenset_el0);
+
+ return (clr || set);
+}
+
+static void __hyp_text __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
+{
+ struct kvm_host_data *host;
+ struct kvm_pmu_events *pmu;
+ u32 clr, set;
+
+ host = container_of(host_ctxt, struct kvm_host_data, host_ctxt);
+ pmu = &host->pmu_events;
+
+ /* We can potentially avoid a sysreg write by only changing bits that
+ * differ between the guest/host. E.g. where events are enabled in
+ * both guest and host
+ */
+ clr = pmu->events_guest & ~pmu->events_host;
+ set = pmu->events_host & ~pmu->events_guest;
+
+ if (clr)
+ write_sysreg(clr, pmcntenclr_el0);
+
+ if (set)
+ write_sysreg(set, pmcntenset_el0);
+}
+
/*
* Return true when we were able to fixup the guest exit and should return to
* the guest, false when we should restore the host state and return to the
@@ -488,12 +536,15 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_cpu_context *guest_ctxt;
+ bool pmu_switch_needed;
u64 exit_code;
host_ctxt = vcpu->arch.host_cpu_context;
host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
+ pmu_switch_needed = __pmu_switch_to_guest(host_ctxt);
+
sysreg_save_host_state_vhe(host_ctxt);
__activate_traps(vcpu);
@@ -524,6 +575,9 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
__debug_switch_to_host(vcpu);
+ if (pmu_switch_needed)
+ __pmu_switch_to_host(host_ctxt);
+
return exit_code;
}
@@ -532,6 +586,7 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *host_ctxt;
struct kvm_cpu_context *guest_ctxt;
+ bool pmu_switch_needed;
u64 exit_code;
vcpu = kern_hyp_va(vcpu);
@@ -540,6 +595,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
host_ctxt->__hyp_running_vcpu = vcpu;
guest_ctxt = &vcpu->arch.ctxt;
+ pmu_switch_needed = __pmu_switch_to_guest(host_ctxt);
+
__sysreg_save_state_nvhe(host_ctxt);
__activate_traps(vcpu);
@@ -586,6 +643,9 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
*/
__debug_switch_to_host(vcpu);
+ if (pmu_switch_needed)
+ __pmu_switch_to_host(host_ctxt);
+
return exit_code;
}
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 9+ messages in thread