All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 1/2] perf ignore LBR and extra_regs.
@ 2014-07-08 16:49 kan.liang
  2014-07-08 16:49 ` [PATCH V4 2/2] kvm: " kan.liang
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: kan.liang @ 2014-07-08 16:49 UTC (permalink / raw)
  To: peterz; +Cc: andi, linux-kernel, kvm, Kan Liang

From: Kan Liang <kan.liang@intel.com>

x86, perf: Protect LBR and extra_regs against KVM lying

With -cpu host, KVM reports LBR and extra_regs support, if the host has support.
When the guest perf driver tries to access LBR or extra_regs MSR,
it #GPs all MSR accesses,since KVM doesn't handle LBR and extra_regs support.
So check the related MSRs access right once at initialization time to avoid the error access at runtime.

For reproducing the issue, please build the kernel with CONFIG_KVM_INTEL = y (for host kernel).
And CONFIG_PARAVIRT = n and CONFIG_KVM_GUEST = n (for guest kernel).
Start the guest with -cpu host.
Run perf record with --branch-any or --branch-filter in guest to trigger LBR #GP.
Run perf stat offcore events (E.g. LLC-loads/LLC-load-misses ...) in guest to trigger offcore_rsp #GP

Signed-off-by: Kan Liang <kan.liang@intel.com>

V2: Move the check code to initialization time.
V3: Add flag for each extra register.
    Check all LBR MSRs at initialization time.
V4: Remove lbr_msr_access. For LBR msr, simply set lbr_nr to 0 if check_msr failed.
    Disable all extra msrs in creation places if check_msr failed.
---
 arch/x86/kernel/cpu/perf_event.c       |  3 +++
 arch/x86/kernel/cpu/perf_event.h       | 21 +++++++++++++++++
 arch/x86/kernel/cpu/perf_event_intel.c | 43 +++++++++++++++++++++++++++++++---
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 2bdfbff..f0e8022 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -118,6 +118,9 @@ static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
 			continue;
 		if (event->attr.config1 & ~er->valid_mask)
 			return -EINVAL;
+		/* Check if the extra msrs can be safely accessed*/
+		if (!x86_pmu.extra_msr_access[er->idx])
+			continue;
 
 		reg->idx = er->idx;
 		reg->config = event->attr.config1;
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 3b2f9bd..85725c5 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -464,6 +464,12 @@ struct x86_pmu {
 	 */
 	struct extra_reg *extra_regs;
 	unsigned int er_flags;
+	/*
+	 * EXTRA REG MSR can be accessed
+	 * The extra registers are completely unrelated to each other.
+	 * So it needs a flag for each extra register.
+	 */
+	bool		extra_msr_access[EXTRA_REG_MAX];
 
 	/*
 	 * Intel host/guest support (KVM)
@@ -525,6 +531,21 @@ extern u64 __read_mostly hw_cache_extra_regs
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX];
 
+/*
+ * Under certain circumstances, access certain MSR may cause #GP.
+ * The function tests if the input MSR can be safely accessed.
+ */
+static inline bool check_msr(unsigned long msr)
+{
+	u64 value;
+
+	if (rdmsrl_safe(msr, &value) < 0)
+		return false;
+	if (wrmsrl_safe(msr, value) < 0)
+		return false;
+	return true;
+}
+
 u64 x86_perf_event_update(struct perf_event *event);
 
 static inline unsigned int x86_pmu_config_addr(int index)
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index adb02aa..2be44be 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1471,11 +1471,14 @@ static void intel_fixup_er(struct perf_event *event, int idx)
 {
 	event->hw.extra_reg.idx = idx;
 
-	if (idx == EXTRA_REG_RSP_0) {
+	/* The extra_reg doesn't update if msrs cannot be accessed safely */
+	if ((idx == EXTRA_REG_RSP_0) &&
+			x86_pmu.extra_msr_access[EXTRA_REG_RSP_0]) {
 		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
 		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
 		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
-	} else if (idx == EXTRA_REG_RSP_1) {
+	} else if ((idx == EXTRA_REG_RSP_1) &&
+			x86_pmu.extra_msr_access[EXTRA_REG_RSP_1]) {
 		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
 		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
 		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
@@ -2262,7 +2265,9 @@ __init int intel_pmu_init(void)
 	union cpuid10_ebx ebx;
 	struct event_constraint *c;
 	unsigned int unused;
-	int version;
+	int version, i;
+	struct extra_reg *er;
+	bool access;
 
 	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
 		switch (boot_cpu_data.x86) {
@@ -2565,6 +2570,38 @@ __init int intel_pmu_init(void)
 		}
 	}
 
+	/*
+	 * Access LBR MSR may cause #GP under certain circumstances.
+	 * E.g. KVM doesn't support LBR MSR
+	 * Check all LBT MSR here.
+	 * Disable LBR access if any LBR MSRs can not be accessed.
+	 */
+	if (x86_pmu.lbr_nr) {
+		access = check_msr(x86_pmu.lbr_tos);
+		for (i = 0; i < x86_pmu.lbr_nr; i++) {
+			access &= check_msr(x86_pmu.lbr_from + i);
+			access &= check_msr(x86_pmu.lbr_to + i);
+		}
+		if (!access)
+			x86_pmu.lbr_nr = 0;
+	}
+	/*
+	 * Access extra MSR may cause #GP under certain circumstances.
+	 * E.g. KVM doesn't support offcore event
+	 * Check all extra_regs here.
+	 */
+	if (x86_pmu.extra_regs) {
+		memset(x86_pmu.extra_msr_access,
+			true, sizeof(bool) * EXTRA_REG_MAX);
+		for (er = x86_pmu.extra_regs; er->msr; er++) {
+			x86_pmu.extra_msr_access[er->idx] =
+				check_msr(er->msr);
+		}
+		/* Disable LBR select mapping */
+		if (!x86_pmu.extra_msr_access[EXTRA_REG_LBR])
+			x86_pmu.lbr_sel_map = NULL;
+	}
+
 	/* Support full width counters using alternative MSR range */
 	if (x86_pmu.intel_cap.full_width_write) {
 		x86_pmu.max_period = x86_pmu.cntval_mask;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V4 2/2] kvm: ignore LBR and extra_regs
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
@ 2014-07-08 16:49 ` kan.liang
  2014-07-09  8:32 ` [PATCH V4 1/2] perf " Peter Zijlstra
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: kan.liang @ 2014-07-08 16:49 UTC (permalink / raw)
  To: peterz; +Cc: andi, linux-kernel, kvm, Kan Liang, Andi Kleen

From: Kan Liang <kan.liang@intel.com>

With -cpu host KVM reports LBR and extra_regs support, so the perf driver may accesses the LBR and extra_regs MSRs.
However, there is no LBR and extra_regs virtualization support yet. This could causes guest to crash.
As a workaround, KVM just simply ignore the LBR and extra_regs MSRs to lie the guest.

For reproducing the issue, please build the kernel with CONFIG_KVM_INTEL = y (for host kernel).
And CONFIG_PARAVIRT = n and CONFIG_KVM_GUEST = n (for guest kernel).
Start the guest with -cpu host.
Run perf record with --branch-any or --branch-filter in guest to trigger LBR #GP.
Run perf stat offcore events (E.g. LLC-loads/LLC-load-misses ...) in guest to trigger offcore_rsp #GP

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@intel.com>

V3: add MSR_LBR_TOS
V4: add MSR_LBR_SELECT and MSR_PEBS_LD_LAT_THRESHOLD
---
 arch/x86/kvm/pmu.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index cbecaa9..cf0ed39 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -331,6 +331,18 @@ bool kvm_pmu_msr(struct kvm_vcpu *vcpu, u32 msr)
 	case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
 		ret = pmu->version > 1;
 		break;
+	case MSR_OFFCORE_RSP_0:
+	case MSR_OFFCORE_RSP_1:
+	case MSR_LBR_SELECT:
+	case MSR_PEBS_LD_LAT_THRESHOLD:
+	case MSR_LBR_TOS:
+	/* At most 8-deep LBR for core and atom */
+	case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 7:
+	case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 7:
+	/* 16-deep LBR for core i3/i5/i7 series processors */
+	case MSR_LBR_NHM_FROM ... MSR_LBR_NHM_FROM + 15:
+	case MSR_LBR_NHM_TO ... MSR_LBR_NHM_TO + 15:
+		return 1; /* to avoid crashes */
 	default:
 		ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)
 			|| get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0)
@@ -358,6 +370,19 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
 	case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
 		*data = pmu->global_ovf_ctrl;
 		return 0;
+	case MSR_OFFCORE_RSP_0:
+	case MSR_OFFCORE_RSP_1:
+	case MSR_LBR_SELECT:
+	case MSR_PEBS_LD_LAT_THRESHOLD:
+	case MSR_LBR_TOS:
+	/* At most 8-deep LBR for core and atom */
+	case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 7:
+	case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 7:
+	/* 16-deep LBR for core i3/i5/i7 series processors */
+	case MSR_LBR_NHM_FROM ... MSR_LBR_NHM_FROM + 15:
+	case MSR_LBR_NHM_TO ... MSR_LBR_NHM_TO + 15:
+		*data = 0;
+		return 0;
 	default:
 		if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
 				(pmc = get_fixed_pmc(pmu, index))) {
@@ -409,6 +434,19 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 0;
 		}
 		break;
+	case MSR_OFFCORE_RSP_0:
+	case MSR_OFFCORE_RSP_1:
+	case MSR_LBR_SELECT:
+	case MSR_PEBS_LD_LAT_THRESHOLD:
+	case MSR_LBR_TOS:
+	/* At most 8-deep LBR for core and atom */
+	case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 7:
+	case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 7:
+	/* 16-deep LBR for core i3/i5/i7 series processors */
+	case MSR_LBR_NHM_FROM ... MSR_LBR_NHM_FROM + 15:
+	case MSR_LBR_NHM_TO ... MSR_LBR_NHM_TO + 15:
+		/* dummy for now */
+		break;
 	default:
 		if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
 				(pmc = get_fixed_pmc(pmu, index))) {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
  2014-07-08 16:49 ` [PATCH V4 2/2] kvm: " kan.liang
@ 2014-07-09  8:32 ` Peter Zijlstra
  2014-07-09  9:14 ` Peter Zijlstra
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09  8:32 UTC (permalink / raw)
  To: kan.liang; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 807 bytes --]

On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
> index 2bdfbff..f0e8022 100644
> --- a/arch/x86/kernel/cpu/perf_event.c
> +++ b/arch/x86/kernel/cpu/perf_event.c
> @@ -118,6 +118,9 @@ static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
>  			continue;
>  		if (event->attr.config1 & ~er->valid_mask)
>  			return -EINVAL;
> +		/* Check if the extra msrs can be safely accessed*/
> +		if (!x86_pmu.extra_msr_access[er->idx])
> +			continue;
>  
>  		reg->idx = er->idx;
>  		reg->config = event->attr.config1;

You should return an error here; doing continue will eventually make
it return 0, which is no-error and things will happily create the event
and malfunction.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
  2014-07-08 16:49 ` [PATCH V4 2/2] kvm: " kan.liang
  2014-07-09  8:32 ` [PATCH V4 1/2] perf " Peter Zijlstra
@ 2014-07-09  9:14 ` Peter Zijlstra
  2014-07-09  9:19 ` Peter Zijlstra
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09  9:14 UTC (permalink / raw)
  To: kan.liang; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 1734 bytes --]

On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
> index 2bdfbff..f0e8022 100644
> --- a/arch/x86/kernel/cpu/perf_event.c
> +++ b/arch/x86/kernel/cpu/perf_event.c
> @@ -118,6 +118,9 @@ static int x86_pmu_extra_regs(u64 config, struct perf_event *event)
>  			continue;
>  		if (event->attr.config1 & ~er->valid_mask)
>  			return -EINVAL;
> +		/* Check if the extra msrs can be safely accessed*/
> +		if (!x86_pmu.extra_msr_access[er->idx])
> +			continue;

If you fail here;

>  		reg->idx = er->idx;
>  		reg->config = event->attr.config1;

> diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
> index adb02aa..2be44be 100644
> --- a/arch/x86/kernel/cpu/perf_event_intel.c
> +++ b/arch/x86/kernel/cpu/perf_event_intel.c
> @@ -1471,11 +1471,14 @@ static void intel_fixup_er(struct perf_event *event, int idx)
>  {
>  	event->hw.extra_reg.idx = idx;
>  
> -	if (idx == EXTRA_REG_RSP_0) {
> +	/* The extra_reg doesn't update if msrs cannot be accessed safely */
> +	if ((idx == EXTRA_REG_RSP_0) &&
> +			x86_pmu.extra_msr_access[EXTRA_REG_RSP_0]) {
>  		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
>  		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_0].event;
>  		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
> -	} else if (idx == EXTRA_REG_RSP_1) {
> +	} else if ((idx == EXTRA_REG_RSP_1) &&
> +			x86_pmu.extra_msr_access[EXTRA_REG_RSP_1]) {
>  		event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
>  		event->hw.config |= x86_pmu.extra_regs[EXTRA_REG_RSP_1].event;
>  		event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;

You should never get here..


[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
                   ` (2 preceding siblings ...)
  2014-07-09  9:14 ` Peter Zijlstra
@ 2014-07-09  9:19 ` Peter Zijlstra
  2014-07-09  9:27 ` Peter Zijlstra
  2014-07-09 14:16 ` Peter Zijlstra
  5 siblings, 0 replies; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09  9:19 UTC (permalink / raw)
  To: kan.liang; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 897 bytes --]

On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> +	/*
> +	 * Access LBR MSR may cause #GP under certain circumstances.
> +	 * E.g. KVM doesn't support LBR MSR
> +	 * Check all LBT MSR here.
> +	 * Disable LBR access if any LBR MSRs can not be accessed.
> +	 */
> +	if (x86_pmu.lbr_nr) {
> +		access = check_msr(x86_pmu.lbr_tos);
> +		for (i = 0; i < x86_pmu.lbr_nr; i++) {
> +			access &= check_msr(x86_pmu.lbr_from + i);
> +			access &= check_msr(x86_pmu.lbr_to + i);
> +		}
> +		if (!access)
> +			x86_pmu.lbr_nr = 0;
> +	}

You _could_ write that as:

	if (x86_pmu.lbr_nr) {
		if (!check_msr(x86_pmu.lbr_tos))
			x86_pmu.lbr_nr = 0;
		for (i = 0; i < x86_pmu.lbr_nr; i++) {
			if (!(check_msr(x86_pmu.lbr_from + i) &&
			      check_msr(x86_pmu.lbr_to + i)))
			      x86_pmu.lbr_nr = 0;
		}
	}

There is no point in checking any more MSRs after the first fail after
all.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
                   ` (3 preceding siblings ...)
  2014-07-09  9:19 ` Peter Zijlstra
@ 2014-07-09  9:27 ` Peter Zijlstra
  2014-07-09 14:04   ` Liang, Kan
  2014-07-09 14:16 ` Peter Zijlstra
  5 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09  9:27 UTC (permalink / raw)
  To: kan.liang; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 1355 bytes --]

On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> --- a/arch/x86/kernel/cpu/perf_event.h
> +++ b/arch/x86/kernel/cpu/perf_event.h
> @@ -464,6 +464,12 @@ struct x86_pmu {
>  	 */
>  	struct extra_reg *extra_regs;
>  	unsigned int er_flags;
> +	/*
> +	 * EXTRA REG MSR can be accessed
> +	 * The extra registers are completely unrelated to each other.
> +	 * So it needs a flag for each extra register.
> +	 */
> +	bool		extra_msr_access[EXTRA_REG_MAX];
>  
>  	/*
>  	 * Intel host/guest support (KVM)

# pahole -C extra_reg arch/x86/kernel/cpu/perf_event_intel.o
struct extra_reg {
        unsigned int               event;                /*     0     4 */
        unsigned int               msr;                  /*     4     4 */
        u64                        config_mask;          /*     8     8 */
        u64                        valid_mask;           /*    16     8 */
        int                        idx;                  /*    24     4 */

        /* size: 32, cachelines: 1, members: 5 */
        /* padding: 4 */
        /* last cacheline: 32 bytes */
};

There's still 4 empty bytes at the tail of extra_reg itself; would it
make sense to store the availability of the reg in there?

After all; the place we use it (x86_pmu_extra_regs) already has the
pointer to the structure.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09  9:27 ` Peter Zijlstra
@ 2014-07-09 14:04   ` Liang, Kan
  0 siblings, 0 replies; 14+ messages in thread
From: Liang, Kan @ 2014-07-09 14:04 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: andi, linux-kernel, kvm


> 
> On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > --- a/arch/x86/kernel/cpu/perf_event.h
> > +++ b/arch/x86/kernel/cpu/perf_event.h
> > @@ -464,6 +464,12 @@ struct x86_pmu {
> >  	 */
> >  	struct extra_reg *extra_regs;
> >  	unsigned int er_flags;
> > +	/*
> > +	 * EXTRA REG MSR can be accessed
> > +	 * The extra registers are completely unrelated to each other.
> > +	 * So it needs a flag for each extra register.
> > +	 */
> > +	bool		extra_msr_access[EXTRA_REG_MAX];
> >
> >  	/*
> >  	 * Intel host/guest support (KVM)
> 
> # pahole -C extra_reg arch/x86/kernel/cpu/perf_event_intel.o
> struct extra_reg {
>         unsigned int               event;                /*     0     4 */
>         unsigned int               msr;                  /*     4     4 */
>         u64                        config_mask;          /*     8     8 */
>         u64                        valid_mask;           /*    16     8 */
>         int                        idx;                  /*    24     4 */
> 
>         /* size: 32, cachelines: 1, members: 5 */
>         /* padding: 4 */
>         /* last cacheline: 32 bytes */
> };
> 
> There's still 4 empty bytes at the tail of extra_reg itself; would it make sense
> to store the availability of the reg in there?
> 

Now, it perfectly matches the 4 empty bytes. However, the extra_reg_type may be extended in the near future.   


> After all; the place we use it (x86_pmu_extra_regs) already has the pointer
> to the structure.


Yes, it's doable. However, if we move extra_msr_access to extra_reg, I guess we have to modify all the related micros (i.e EVENT_EXTRA_REG) to initialize the new items. That could be a big change.
On the other side, in x86_pmu structure, there are extra_regs related items defined under the comments "Extra registers for events". And the bit holes are enough for current usage and future extension.
I guess  x86_pmu should be a good place to store the availability of the reg. 


        /* --- cacheline 6 boundary (384 bytes) --- */
        bool                       lbr_double_abort;     /*   384     1 */

        /* XXX 7 bytes hole, try to pack */

        struct extra_reg *         extra_regs;           /*   392     8 */
        unsigned int               er_flags;             /*   400     4 */

        /* XXX 4 bytes hole, try to pack */

        struct perf_guest_switch_msr * (*guest_get_msrs)(int *); /*   408     8 */

        /* size: 416, cachelines: 7, members: 64 */
        /* sum members: 391, holes: 6, sum holes: 25 */
        /* bit holes: 1, sum bit holes: 27 bits */
        /* last cacheline: 32 bytes */


Thanks,
Kan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
                   ` (4 preceding siblings ...)
  2014-07-09  9:27 ` Peter Zijlstra
@ 2014-07-09 14:16 ` Peter Zijlstra
  2014-07-09 14:32   ` Liang, Kan
  5 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09 14:16 UTC (permalink / raw)
  To: kan.liang; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 536 bytes --]

On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> +/*
> + * Under certain circumstances, access certain MSR may cause #GP.
> + * The function tests if the input MSR can be safely accessed.
> + */
> +static inline bool check_msr(unsigned long msr)
> +{
> +	u64 value;
> +
> +	if (rdmsrl_safe(msr, &value) < 0)
> +		return false;
> +	if (wrmsrl_safe(msr, value) < 0)
> +		return false;
> +	return true;
> +}

What does this thing return after patch 2? does the write still fault or
will KVM silently take writes too?

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 14:16 ` Peter Zijlstra
@ 2014-07-09 14:32   ` Liang, Kan
  2014-07-09 14:58     ` Peter Zijlstra
  0 siblings, 1 reply; 14+ messages in thread
From: Liang, Kan @ 2014-07-09 14:32 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: andi, linux-kernel, kvm



> On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > +/*
> > + * Under certain circumstances, access certain MSR may cause #GP.
> > + * The function tests if the input MSR can be safely accessed.
> > + */
> > +static inline bool check_msr(unsigned long msr) {
> > +	u64 value;
> > +
> > +	if (rdmsrl_safe(msr, &value) < 0)
> > +		return false;
> > +	if (wrmsrl_safe(msr, value) < 0)
> > +		return false;
> > +	return true;
> > +}
> 
> What does this thing return after patch 2? does the write still fault or will
> KVM silently take writes too?

If applying patch 2, the function will return true. The KVM just simply ignore the reads/writes.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 14:32   ` Liang, Kan
@ 2014-07-09 14:58     ` Peter Zijlstra
  2014-07-09 15:43       ` Liang, Kan
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09 14:58 UTC (permalink / raw)
  To: Liang, Kan; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 947 bytes --]

On Wed, Jul 09, 2014 at 02:32:28PM +0000, Liang, Kan wrote:
> 
> 
> > On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > > +/*
> > > + * Under certain circumstances, access certain MSR may cause #GP.
> > > + * The function tests if the input MSR can be safely accessed.
> > > + */
> > > +static inline bool check_msr(unsigned long msr) {
> > > +	u64 value;
> > > +
> > > +	if (rdmsrl_safe(msr, &value) < 0)
> > > +		return false;
> > > +	if (wrmsrl_safe(msr, value) < 0)
> > > +		return false;
> > > +	return true;
> > > +}
> > 
> > What does this thing return after patch 2? does the write still fault or will
> > KVM silently take writes too?
> 
> If applying patch 2, the function will return true. The KVM just simply ignore the reads/writes.

OK, then that's broken too. We want a function to return false for any
malfunctioning MSR, ignoring writes and returning 0s is not proper
functioning.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 14:58     ` Peter Zijlstra
@ 2014-07-09 15:43       ` Liang, Kan
  2014-07-09 16:41         ` Peter Zijlstra
  0 siblings, 1 reply; 14+ messages in thread
From: Liang, Kan @ 2014-07-09 15:43 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: andi, linux-kernel, kvm



> -----Original Message-----
> From: Peter Zijlstra [mailto:peterz@infradead.org]
> Sent: Wednesday, July 09, 2014 10:58 AM
> To: Liang, Kan
> Cc: andi@firstfloor.org; linux-kernel@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
> 
> On Wed, Jul 09, 2014 at 02:32:28PM +0000, Liang, Kan wrote:
> >
> >
> > > On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > > > +/*
> > > > + * Under certain circumstances, access certain MSR may cause #GP.
> > > > + * The function tests if the input MSR can be safely accessed.
> > > > + */
> > > > +static inline bool check_msr(unsigned long msr) {
> > > > +	u64 value;
> > > > +
> > > > +	if (rdmsrl_safe(msr, &value) < 0)
> > > > +		return false;
> > > > +	if (wrmsrl_safe(msr, value) < 0)
> > > > +		return false;
> > > > +	return true;
> > > > +}
> > >
> > > What does this thing return after patch 2? does the write still
> > > fault or will KVM silently take writes too?
> >
> > If applying patch 2, the function will return true. The KVM just simply ignore
> the reads/writes.
> 
> OK, then that's broken too. We want a function to return false for any
> malfunctioning MSR, ignoring writes and returning 0s is not proper
> functioning.

The patch 2 is to handle the case that the administrator can only patch the host. Don't need to force user to upgrade their guest to fix the crash.  
And ignore the annoying "unhandled...." KVM messages


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 15:43       ` Liang, Kan
@ 2014-07-09 16:41         ` Peter Zijlstra
  2014-07-09 19:32           ` Liang, Kan
  0 siblings, 1 reply; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-09 16:41 UTC (permalink / raw)
  To: Liang, Kan; +Cc: andi, linux-kernel, kvm

[-- Attachment #1: Type: text/plain, Size: 1865 bytes --]

On Wed, Jul 09, 2014 at 03:43:45PM +0000, Liang, Kan wrote:
> 
> 
> > -----Original Message-----
> > From: Peter Zijlstra [mailto:peterz@infradead.org]
> > Sent: Wednesday, July 09, 2014 10:58 AM
> > To: Liang, Kan
> > Cc: andi@firstfloor.org; linux-kernel@vger.kernel.org; kvm@vger.kernel.org
> > Subject: Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
> > 
> > On Wed, Jul 09, 2014 at 02:32:28PM +0000, Liang, Kan wrote:
> > >
> > >
> > > > On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > > > > +/*
> > > > > + * Under certain circumstances, access certain MSR may cause #GP.
> > > > > + * The function tests if the input MSR can be safely accessed.
> > > > > + */
> > > > > +static inline bool check_msr(unsigned long msr) {
> > > > > +	u64 value;
> > > > > +
> > > > > +	if (rdmsrl_safe(msr, &value) < 0)
> > > > > +		return false;
> > > > > +	if (wrmsrl_safe(msr, value) < 0)
> > > > > +		return false;
> > > > > +	return true;
> > > > > +}
> > > >
> > > > What does this thing return after patch 2? does the write still
> > > > fault or will KVM silently take writes too?
> > >
> > > If applying patch 2, the function will return true. The KVM just simply ignore
> > the reads/writes.
> > 
> > OK, then that's broken too. We want a function to return false for any
> > malfunctioning MSR, ignoring writes and returning 0s is not proper
> > functioning.
> 
> The patch 2 is to handle the case that the administrator can only
> patch the host. Don't need to force user to upgrade their guest to fix
> the crash.  And ignore the annoying "unhandled...." KVM messages

Sure; but what I meant was, check_msr() is broken when ran on such a
kernel. You need to fix check_msr() to return failure on these 'ignored'
MSRs, after all they don't function as expected, they're effectively
broken.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 16:41         ` Peter Zijlstra
@ 2014-07-09 19:32           ` Liang, Kan
  2014-07-10  9:02             ` Peter Zijlstra
  0 siblings, 1 reply; 14+ messages in thread
From: Liang, Kan @ 2014-07-09 19:32 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: andi, linux-kernel, kvm



> > >
> > > On Wed, Jul 09, 2014 at 02:32:28PM +0000, Liang, Kan wrote:
> > > >
> > > >
> > > > > On Tue, Jul 08, 2014 at 09:49:40AM -0700, kan.liang@intel.com wrote:
> > > > > > +/*
> > > > > > + * Under certain circumstances, access certain MSR may cause #GP.
> > > > > > + * The function tests if the input MSR can be safely accessed.
> > > > > > + */
> > > > > > +static inline bool check_msr(unsigned long msr) {
> > > > > > +	u64 value;
> > > > > > +
> > > > > > +	if (rdmsrl_safe(msr, &value) < 0)
> > > > > > +		return false;
> > > > > > +	if (wrmsrl_safe(msr, value) < 0)
> > > > > > +		return false;
> > > > > > +	return true;
> > > > > > +}
> > > > >
> > > > > What does this thing return after patch 2? does the write still
> > > > > fault or will KVM silently take writes too?
> > > >
> > > > If applying patch 2, the function will return true. The KVM just
> > > > simply ignore
> > > the reads/writes.
> > >
> > > OK, then that's broken too. We want a function to return false for
> > > any malfunctioning MSR, ignoring writes and returning 0s is not
> > > proper functioning.
> >
> > The patch 2 is to handle the case that the administrator can only
> > patch the host. Don't need to force user to upgrade their guest to fix
> > the crash.  And ignore the annoying "unhandled...." KVM messages
> 
> Sure; but what I meant was, check_msr() is broken when ran on such a
> kernel. You need to fix check_msr() to return failure on these 'ignored'
> MSRs, after all they don't function as expected, they're effectively broken.

The function is designed to check if the MSRs can be safely accessed (no #GP). It cannot guarantee the correctness of the MSRs.
If KVM applied patch 2 and guest applied patch 1, from the guest's perspective, the MSRs can be accessed (no #GP triggered). So return true is expected. It should not be a broken.
The only unexpected thing for guest is that the counting/sampling result for LBR/extra reg is always 0. But the patch is a short term fix to stop things from crashing. I think it should be acceptable.



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/2] perf ignore LBR and extra_regs.
  2014-07-09 19:32           ` Liang, Kan
@ 2014-07-10  9:02             ` Peter Zijlstra
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Zijlstra @ 2014-07-10  9:02 UTC (permalink / raw)
  To: Liang, Kan; +Cc: andi, linux-kernel, kvm

/me reminds you of 78 char text wrap.

On Wed, Jul 09, 2014 at 07:32:09PM +0000, Liang, Kan wrote:
> > Sure; but what I meant was, check_msr() is broken when ran on such a
> > kernel. You need to fix check_msr() to return failure on these 'ignored'
> > MSRs, after all they don't function as expected, they're effectively broken.
> 
> The function is designed to check if the MSRs can be safely accessed
> (no #GP). It cannot guarantee the correctness of the MSRs.  If KVM
> applied patch 2 and guest applied patch 1, from the guest's
> perspective, the MSRs can be accessed (no #GP triggered). So return
> true is expected. It should not be a broken. 

You're not understanding. I know you wrote that function to do that. I'm
saying that's wrong.

Look at check_hw_exists() it explicitly checks for fake MSRs and reports
them broken.

These fake MSRs _ARE_ broken, they do not behave as expected. Not
crashing is not the right consideration here, we're interested in higher
order correct behaviour.

> The only unexpected
> thing for guest is that the counting/sampling result for LBR/extra reg
> is always 0. But the patch is a short term fix to stop things from
> crashing. I think it should be acceptable.

Patch 2 is fine, patch 1, in particular your check_msr() routine is not.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-07-10  9:02 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-08 16:49 [PATCH V4 1/2] perf ignore LBR and extra_regs kan.liang
2014-07-08 16:49 ` [PATCH V4 2/2] kvm: " kan.liang
2014-07-09  8:32 ` [PATCH V4 1/2] perf " Peter Zijlstra
2014-07-09  9:14 ` Peter Zijlstra
2014-07-09  9:19 ` Peter Zijlstra
2014-07-09  9:27 ` Peter Zijlstra
2014-07-09 14:04   ` Liang, Kan
2014-07-09 14:16 ` Peter Zijlstra
2014-07-09 14:32   ` Liang, Kan
2014-07-09 14:58     ` Peter Zijlstra
2014-07-09 15:43       ` Liang, Kan
2014-07-09 16:41         ` Peter Zijlstra
2014-07-09 19:32           ` Liang, Kan
2014-07-10  9:02             ` Peter Zijlstra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.