Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c93199e9
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c93199e9
编写于
2月 12, 2021
作者:
M
Marc Zyngier
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'kvm-arm64/pmu-debug-fixes-5.11' into kvmarm-master/next
Signed-off-by:
N
Marc Zyngier
<
maz@kernel.org
>
上级
8cb68a9d
8c358b29
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
64 addition
and
38 deletion
+64
-38
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/sysreg.h
+3
-0
arch/arm64/kvm/pmu-emul.c
arch/arm64/kvm/pmu-emul.c
+10
-4
arch/arm64/kvm/sys_regs.c
arch/arm64/kvm/sys_regs.c
+51
-34
未找到文件。
arch/arm64/include/asm/sysreg.h
浏览文件 @
c93199e9
...
...
@@ -846,7 +846,10 @@
#define ID_DFR0_PERFMON_SHIFT 24
#define ID_DFR0_PERFMON_8_0 0x3
#define ID_DFR0_PERFMON_8_1 0x4
#define ID_DFR0_PERFMON_8_4 0x5
#define ID_DFR0_PERFMON_8_5 0x6
#define ID_ISAR4_SWP_FRAC_SHIFT 28
#define ID_ISAR4_PSR_M_SHIFT 24
...
...
arch/arm64/kvm/pmu-emul.c
浏览文件 @
c93199e9
...
...
@@ -23,11 +23,11 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
static
u32
kvm_pmu_event_mask
(
struct
kvm
*
kvm
)
{
switch
(
kvm
->
arch
.
pmuver
)
{
case
1
:
/* ARMv8.0 */
case
ID_AA64DFR0_PMUVER_8_0
:
return
GENMASK
(
9
,
0
);
case
4
:
/* ARMv8.1 */
case
5
:
/* ARMv8.4 */
case
6
:
/* ARMv8.5 */
case
ID_AA64DFR0_PMUVER_8_1
:
case
ID_AA64DFR0_PMUVER_8_4
:
case
ID_AA64DFR0_PMUVER_8_5
:
return
GENMASK
(
15
,
0
);
default:
/* Shouldn't be here, just for sanity */
WARN_ONCE
(
1
,
"Unknown PMU version %d
\n
"
,
kvm
->
arch
.
pmuver
);
...
...
@@ -795,6 +795,12 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
base
=
0
;
}
else
{
val
=
read_sysreg
(
pmceid1_el0
);
/*
* Don't advertise STALL_SLOT, as PMMIR_EL0 is handled
* as RAZ
*/
if
(
vcpu
->
kvm
->
arch
.
pmuver
>=
ID_AA64DFR0_PMUVER_8_4
)
val
&=
~
BIT_ULL
(
ARMV8_PMUV3_PERFCTR_STALL_SLOT
-
32
);
base
=
32
;
}
...
...
arch/arm64/kvm/sys_regs.c
浏览文件 @
c93199e9
...
...
@@ -9,6 +9,7 @@
* Christoffer Dall <c.dall@virtualopensystems.com>
*/
#include <linux/bitfield.h>
#include <linux/bsearch.h>
#include <linux/kvm_host.h>
#include <linux/mm.h>
...
...
@@ -700,14 +701,18 @@ static bool access_pmselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
static
bool
access_pmceid
(
struct
kvm_vcpu
*
vcpu
,
struct
sys_reg_params
*
p
,
const
struct
sys_reg_desc
*
r
)
{
u64
pmceid
;
u64
pmceid
,
mask
,
shift
;
BUG_ON
(
p
->
is_write
);
if
(
pmu_access_el0_disabled
(
vcpu
))
return
false
;
get_access_mask
(
r
,
&
mask
,
&
shift
);
pmceid
=
kvm_pmu_get_pmceid
(
vcpu
,
(
p
->
Op2
&
1
));
pmceid
&=
mask
;
pmceid
>>=
shift
;
p
->
regval
=
pmceid
;
...
...
@@ -1021,6 +1026,8 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
return
true
;
}
#define FEATURE(x) (GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
/* Read a sanitised cpufeature ID register by sys_reg_desc */
static
u64
read_id_reg
(
const
struct
kvm_vcpu
*
vcpu
,
struct
sys_reg_desc
const
*
r
,
bool
raz
)
...
...
@@ -1028,36 +1035,41 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
u32
id
=
reg_to_encoding
(
r
);
u64
val
=
raz
?
0
:
read_sanitised_ftr_reg
(
id
);
if
(
id
==
SYS_ID_AA64PFR0_EL1
)
{
switch
(
id
)
{
case
SYS_ID_AA64PFR0_EL1
:
if
(
!
vcpu_has_sve
(
vcpu
))
val
&=
~
(
0xfUL
<<
ID_AA64PFR0_SVE_SHIFT
);
val
&=
~
(
0xfUL
<<
ID_AA64PFR0_AMU_SHIFT
);
val
&=
~
(
0xfUL
<<
ID_AA64PFR0_CSV2_SHIFT
);
val
|=
((
u64
)
vcpu
->
kvm
->
arch
.
pfr0_csv2
<<
ID_AA64PFR0_CSV2_SHIFT
);
val
&=
~
(
0xfUL
<<
ID_AA64PFR0_CSV3_SHIFT
);
val
|=
((
u64
)
vcpu
->
kvm
->
arch
.
pfr0_csv3
<<
ID_AA64PFR0_CSV3_SHIFT
);
}
else
if
(
id
==
SYS_ID_AA64PFR1_EL1
)
{
val
&=
~
(
0xfUL
<<
ID_AA64PFR1_MTE_SHIFT
);
}
else
if
(
id
==
SYS_ID_AA64ISAR1_EL1
&&
!
vcpu_has_ptrauth
(
vcpu
))
{
val
&=
~
((
0xfUL
<<
ID_AA64ISAR1_APA_SHIFT
)
|
(
0xfUL
<<
ID_AA64ISAR1_API_SHIFT
)
|
(
0xfUL
<<
ID_AA64ISAR1_GPA_SHIFT
)
|
(
0xfUL
<<
ID_AA64ISAR1_GPI_SHIFT
));
}
else
if
(
id
==
SYS_ID_AA64DFR0_EL1
)
{
u64
cap
=
0
;
/* Limit guests to PMUv3 for ARMv8.1 */
if
(
kvm_vcpu_has_pmu
(
vcpu
))
cap
=
ID_AA64DFR0_PMUVER_8_1
;
val
&=
~
FEATURE
(
ID_AA64PFR0_SVE
);
val
&=
~
FEATURE
(
ID_AA64PFR0_AMU
);
val
&=
~
FEATURE
(
ID_AA64PFR0_CSV2
);
val
|=
FIELD_PREP
(
FEATURE
(
ID_AA64PFR0_CSV2
),
(
u64
)
vcpu
->
kvm
->
arch
.
pfr0_csv2
);
val
&=
~
FEATURE
(
ID_AA64PFR0_CSV3
);
val
|=
FIELD_PREP
(
FEATURE
(
ID_AA64PFR0_CSV3
),
(
u64
)
vcpu
->
kvm
->
arch
.
pfr0_csv3
);
break
;
case
SYS_ID_AA64PFR1_EL1
:
val
&=
~
FEATURE
(
ID_AA64PFR1_MTE
);
break
;
case
SYS_ID_AA64ISAR1_EL1
:
if
(
!
vcpu_has_ptrauth
(
vcpu
))
val
&=
~
(
FEATURE
(
ID_AA64ISAR1_APA
)
|
FEATURE
(
ID_AA64ISAR1_API
)
|
FEATURE
(
ID_AA64ISAR1_GPA
)
|
FEATURE
(
ID_AA64ISAR1_GPI
));
break
;
case
SYS_ID_AA64DFR0_EL1
:
/* Limit debug to ARMv8.0 */
val
&=
~
FEATURE
(
ID_AA64DFR0_DEBUGVER
);
val
|=
FIELD_PREP
(
FEATURE
(
ID_AA64DFR0_DEBUGVER
),
6
);
/* Limit guests to PMUv3 for ARMv8.4 */
val
=
cpuid_feature_cap_perfmon_field
(
val
,
ID_AA64DFR0_PMUVER_SHIFT
,
cap
);
}
else
if
(
id
==
SYS_ID_DFR0_EL1
)
{
/* Limit guests to PMUv3 for ARMv8.1 */
ID_AA64DFR0_PMUVER_SHIFT
,
kvm_vcpu_has_pmu
(
vcpu
)
?
ID_AA64DFR0_PMUVER_8_4
:
0
);
break
;
case
SYS_ID_DFR0_EL1
:
/* Limit guests to PMUv3 for ARMv8.4 */
val
=
cpuid_feature_cap_perfmon_field
(
val
,
ID_DFR0_PERFMON_SHIFT
,
ID_DFR0_PERFMON_8_1
);
ID_DFR0_PERFMON_SHIFT
,
kvm_vcpu_has_pmu
(
vcpu
)
?
ID_DFR0_PERFMON_8_4
:
0
);
break
;
}
return
val
;
...
...
@@ -1493,6 +1505,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
.
access
=
access_pminten
,
.
reg
=
PMINTENSET_EL1
},
{
PMU_SYS_REG
(
SYS_PMINTENCLR_EL1
),
.
access
=
access_pminten
,
.
reg
=
PMINTENSET_EL1
},
{
SYS_DESC
(
SYS_PMMIR_EL1
),
trap_raz_wi
},
{
SYS_DESC
(
SYS_MAIR_EL1
),
access_vm_reg
,
reset_unknown
,
MAIR_EL1
},
{
SYS_DESC
(
SYS_AMAIR_EL1
),
access_vm_reg
,
reset_amair_el1
,
AMAIR_EL1
},
...
...
@@ -1720,7 +1733,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{
SYS_DESC
(
SYS_FPEXC32_EL2
),
NULL
,
reset_val
,
FPEXC32_EL2
,
0x700
},
};
static
bool
trap_dbgidr
(
struct
kvm_vcpu
*
vcpu
,
static
bool
trap_dbg
d
idr
(
struct
kvm_vcpu
*
vcpu
,
struct
sys_reg_params
*
p
,
const
struct
sys_reg_desc
*
r
)
{
...
...
@@ -1734,7 +1747,7 @@ static bool trap_dbgidr(struct kvm_vcpu *vcpu,
p
->
regval
=
((((
dfr
>>
ID_AA64DFR0_WRPS_SHIFT
)
&
0xf
)
<<
28
)
|
(((
dfr
>>
ID_AA64DFR0_BRPS_SHIFT
)
&
0xf
)
<<
24
)
|
(((
dfr
>>
ID_AA64DFR0_CTX_CMPS_SHIFT
)
&
0xf
)
<<
20
)
|
(
6
<<
16
)
|
(
el3
<<
14
)
|
(
el3
<<
12
));
|
(
6
<<
16
)
|
(
1
<<
15
)
|
(
el3
<<
14
)
|
(
el3
<<
12
));
return
true
;
}
}
...
...
@@ -1767,8 +1780,8 @@ static bool trap_dbgidr(struct kvm_vcpu *vcpu,
* guest. Revisit this one day, would this principle change.
*/
static
const
struct
sys_reg_desc
cp14_regs
[]
=
{
/* DBGIDR */
{
Op1
(
0
),
CRn
(
0
),
CRm
(
0
),
Op2
(
0
),
trap_dbgidr
},
/* DBG
D
IDR */
{
Op1
(
0
),
CRn
(
0
),
CRm
(
0
),
Op2
(
0
),
trap_dbg
d
idr
},
/* DBGDTRRXext */
{
Op1
(
0
),
CRn
(
0
),
CRm
(
0
),
Op2
(
2
),
trap_raz_wi
},
...
...
@@ -1918,8 +1931,8 @@ static const struct sys_reg_desc cp15_regs[] = {
{
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
3
),
access_pmovs
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
4
),
access_pmswinc
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
5
),
access_pmselr
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
6
),
access_pmceid
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
7
),
access_pmceid
},
{
AA32
(
LO
),
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
6
),
access_pmceid
},
{
AA32
(
LO
),
Op1
(
0
),
CRn
(
9
),
CRm
(
12
),
Op2
(
7
),
access_pmceid
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
13
),
Op2
(
0
),
access_pmu_evcntr
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
13
),
Op2
(
1
),
access_pmu_evtyper
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
13
),
Op2
(
2
),
access_pmu_evcntr
},
...
...
@@ -1927,6 +1940,10 @@ static const struct sys_reg_desc cp15_regs[] = {
{
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
1
),
access_pminten
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
2
),
access_pminten
},
{
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
3
),
access_pmovs
},
{
AA32
(
HI
),
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
4
),
access_pmceid
},
{
AA32
(
HI
),
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
5
),
access_pmceid
},
/* PMMIR */
{
Op1
(
0
),
CRn
(
9
),
CRm
(
14
),
Op2
(
6
),
trap_raz_wi
},
/* PRRR/MAIR0 */
{
AA32
(
LO
),
Op1
(
0
),
CRn
(
10
),
CRm
(
2
),
Op2
(
0
),
access_vm_reg
,
NULL
,
MAIR_EL1
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录