Skip to content

Commit 5e6b211

Browse files
author
Marc Zyngier
committed
Merge tag 'kvmarm-fixes-5.11-2' into kvmarm-master/next
KVM/arm64 fixes for 5.11, take #2 - Don't allow tagged pointers to point to memslots - Filter out ARMv8.1+ PMU events on v8.0 hardware - Hide PMU registers from userspace when no PMU is configured - More PMU cleanups - Don't try to handle broken PSCI firmware - More sys_reg() to reg_to_encoding() conversions Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 19c329f + 139bc8a commit 5e6b211

File tree

6 files changed

+74
-49
lines changed

6 files changed

+74
-49
lines changed

Documentation/virt/kvm/api.rst

+3
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,9 @@ field userspace_addr, which must point at user addressable memory for
12811281
the entire memory slot size. Any object may back this memory, including
12821282
anonymous memory, ordinary files, and hugetlbfs.
12831283

1284+
On architectures that support a form of address tagging, userspace_addr must
1285+
be an untagged address.
1286+
12841287
It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
12851288
be identical. This allows large pages in the guest to be backed by large
12861289
pages in the host.

arch/arm64/kvm/arm.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1396,8 +1396,9 @@ static void cpu_init_hyp_mode(void)
13961396
* Calculate the raw per-cpu offset without a translation from the
13971397
* kernel's mapping to the linear mapping, and store it in tpidr_el2
13981398
* so that we can use adr_l to access per-cpu variables in EL2.
1399+
* Also drop the KASAN tag which gets in the way...
13991400
*/
1400-
params->tpidr_el2 = (unsigned long)this_cpu_ptr_nvhe_sym(__per_cpu_start) -
1401+
params->tpidr_el2 = (unsigned long)kasan_reset_tag(this_cpu_ptr_nvhe_sym(__per_cpu_start)) -
14011402
(unsigned long)kvm_ksym_ref(CHOOSE_NVHE_SYM(__per_cpu_start));
14021403

14031404
params->mair_el2 = read_sysreg(mair_el1);

arch/arm64/kvm/hyp/nvhe/psci-relay.c

+5-8
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,6 @@ static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt)
7777
cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3));
7878
}
7979

80-
static __noreturn unsigned long psci_forward_noreturn(struct kvm_cpu_context *host_ctxt)
81-
{
82-
psci_forward(host_ctxt);
83-
hyp_panic(); /* unreachable */
84-
}
85-
8680
static unsigned int find_cpu_id(u64 mpidr)
8781
{
8882
unsigned int i;
@@ -251,10 +245,13 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_
251245
case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
252246
case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
253247
return psci_forward(host_ctxt);
248+
/*
249+
* SYSTEM_OFF/RESET should not return according to the spec.
250+
* Allow it so as to stay robust to broken firmware.
251+
*/
254252
case PSCI_0_2_FN_SYSTEM_OFF:
255253
case PSCI_0_2_FN_SYSTEM_RESET:
256-
psci_forward_noreturn(host_ctxt);
257-
unreachable();
254+
return psci_forward(host_ctxt);
258255
case PSCI_0_2_FN64_CPU_SUSPEND:
259256
return psci_cpu_suspend(func_id, host_ctxt);
260257
case PSCI_0_2_FN64_CPU_ON:

arch/arm64/kvm/pmu-emul.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
788788
{
789789
unsigned long *bmap = vcpu->kvm->arch.pmu_filter;
790790
u64 val, mask = 0;
791-
int base, i;
791+
int base, i, nr_events;
792792

793793
if (!pmceid1) {
794794
val = read_sysreg(pmceid0_el0);
@@ -801,13 +801,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
801801
if (!bmap)
802802
return val;
803803

804+
nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
805+
804806
for (i = 0; i < 32; i += 8) {
805807
u64 byte;
806808

807809
byte = bitmap_get_value8(bmap, base + i);
808810
mask |= byte << i;
809-
byte = bitmap_get_value8(bmap, 0x4000 + base + i);
810-
mask |= byte << (32 + i);
811+
if (nr_events >= (0x4000 + base + 32)) {
812+
byte = bitmap_get_value8(bmap, 0x4000 + base + i);
813+
mask |= byte << (32 + i);
814+
}
811815
}
812816

813817
return val & mask;

arch/arm64/kvm/sys_regs.c

+56-37
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
* 64bit interface.
4444
*/
4545

46+
#define reg_to_encoding(x) \
47+
sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
48+
(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
49+
4650
static bool read_from_write_only(struct kvm_vcpu *vcpu,
4751
struct sys_reg_params *params,
4852
const struct sys_reg_desc *r)
@@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
273277
const struct sys_reg_desc *r)
274278
{
275279
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
276-
u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1,
277-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
280+
u32 sr = reg_to_encoding(r);
278281

279282
if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
280283
kvm_inject_undefined(vcpu);
@@ -590,6 +593,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
590593
vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1);
591594
}
592595

596+
static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
597+
const struct sys_reg_desc *r)
598+
{
599+
if (kvm_vcpu_has_pmu(vcpu))
600+
return 0;
601+
602+
return REG_HIDDEN;
603+
}
604+
593605
static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
594606
{
595607
u64 pmcr, val;
@@ -613,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
613625
static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags)
614626
{
615627
u64 reg = __vcpu_sys_reg(vcpu, PMUSERENR_EL0);
616-
bool enabled = kvm_vcpu_has_pmu(vcpu);
628+
bool enabled = (reg & flags) || vcpu_mode_priv(vcpu);
617629

618-
enabled &= (reg & flags) || vcpu_mode_priv(vcpu);
619630
if (!enabled)
620631
kvm_inject_undefined(vcpu);
621632

@@ -900,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
900911
static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
901912
const struct sys_reg_desc *r)
902913
{
903-
if (!kvm_vcpu_has_pmu(vcpu)) {
904-
kvm_inject_undefined(vcpu);
905-
return false;
906-
}
907-
908914
if (p->is_write) {
909915
if (!vcpu_mode_priv(vcpu)) {
910916
kvm_inject_undefined(vcpu);
@@ -921,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
921927
return true;
922928
}
923929

924-
#define reg_to_encoding(x) \
925-
sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
926-
(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
927-
928930
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
929931
#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
930932
{ SYS_DESC(SYS_DBGBVRn_EL1(n)), \
@@ -936,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
936938
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
937939
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
938940

941+
#define PMU_SYS_REG(r) \
942+
SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility
943+
939944
/* Macro to expand the PMEVCNTRn_EL0 register */
940945
#define PMU_PMEVCNTR_EL0(n) \
941-
{ SYS_DESC(SYS_PMEVCNTRn_EL0(n)), \
942-
access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
946+
{ PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \
947+
.access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
943948

944949
/* Macro to expand the PMEVTYPERn_EL0 register */
945950
#define PMU_PMEVTYPER_EL0(n) \
946-
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
947-
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
951+
{ PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \
952+
.access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
948953

949954
static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
950955
const struct sys_reg_desc *r)
@@ -1020,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
10201025
static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10211026
struct sys_reg_desc const *r, bool raz)
10221027
{
1023-
u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
1024-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
1028+
u32 id = reg_to_encoding(r);
10251029
u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
10261030

10271031
if (id == SYS_ID_AA64PFR0_EL1) {
@@ -1062,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10621066
static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
10631067
const struct sys_reg_desc *r)
10641068
{
1065-
u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
1066-
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
1069+
u32 id = reg_to_encoding(r);
10671070

10681071
switch (id) {
10691072
case SYS_ID_AA64ZFR0_EL1:
@@ -1486,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
14861489
{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
14871490
{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
14881491

1489-
{ SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
1490-
{ SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
1492+
{ PMU_SYS_REG(SYS_PMINTENSET_EL1),
1493+
.access = access_pminten, .reg = PMINTENSET_EL1 },
1494+
{ PMU_SYS_REG(SYS_PMINTENCLR_EL1),
1495+
.access = access_pminten, .reg = PMINTENSET_EL1 },
14911496

14921497
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
14931498
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
@@ -1526,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15261531
{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
15271532
{ SYS_DESC(SYS_CTR_EL0), access_ctr },
15281533

1529-
{ SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 },
1530-
{ SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
1531-
{ SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 },
1532-
{ SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
1533-
{ SYS_DESC(SYS_PMSWINC_EL0), access_pmswinc, reset_unknown, PMSWINC_EL0 },
1534-
{ SYS_DESC(SYS_PMSELR_EL0), access_pmselr, reset_unknown, PMSELR_EL0 },
1535-
{ SYS_DESC(SYS_PMCEID0_EL0), access_pmceid },
1536-
{ SYS_DESC(SYS_PMCEID1_EL0), access_pmceid },
1537-
{ SYS_DESC(SYS_PMCCNTR_EL0), access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 },
1538-
{ SYS_DESC(SYS_PMXEVTYPER_EL0), access_pmu_evtyper },
1539-
{ SYS_DESC(SYS_PMXEVCNTR_EL0), access_pmu_evcntr },
1534+
{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
1535+
.reset = reset_pmcr, .reg = PMCR_EL0 },
1536+
{ PMU_SYS_REG(SYS_PMCNTENSET_EL0),
1537+
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
1538+
{ PMU_SYS_REG(SYS_PMCNTENCLR_EL0),
1539+
.access = access_pmcnten, .reg = PMCNTENSET_EL0 },
1540+
{ PMU_SYS_REG(SYS_PMOVSCLR_EL0),
1541+
.access = access_pmovs, .reg = PMOVSSET_EL0 },
1542+
{ PMU_SYS_REG(SYS_PMSWINC_EL0),
1543+
.access = access_pmswinc, .reg = PMSWINC_EL0 },
1544+
{ PMU_SYS_REG(SYS_PMSELR_EL0),
1545+
.access = access_pmselr, .reg = PMSELR_EL0 },
1546+
{ PMU_SYS_REG(SYS_PMCEID0_EL0),
1547+
.access = access_pmceid, .reset = NULL },
1548+
{ PMU_SYS_REG(SYS_PMCEID1_EL0),
1549+
.access = access_pmceid, .reset = NULL },
1550+
{ PMU_SYS_REG(SYS_PMCCNTR_EL0),
1551+
.access = access_pmu_evcntr, .reg = PMCCNTR_EL0 },
1552+
{ PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
1553+
.access = access_pmu_evtyper, .reset = NULL },
1554+
{ PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
1555+
.access = access_pmu_evcntr, .reset = NULL },
15401556
/*
15411557
* PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
15421558
* in 32bit mode. Here we choose to reset it as zero for consistency.
15431559
*/
1544-
{ SYS_DESC(SYS_PMUSERENR_EL0), access_pmuserenr, reset_val, PMUSERENR_EL0, 0 },
1545-
{ SYS_DESC(SYS_PMOVSSET_EL0), access_pmovs, reset_unknown, PMOVSSET_EL0 },
1560+
{ PMU_SYS_REG(SYS_PMUSERENR_EL0), .access = access_pmuserenr,
1561+
.reset = reset_val, .reg = PMUSERENR_EL0, .val = 0 },
1562+
{ PMU_SYS_REG(SYS_PMOVSSET_EL0),
1563+
.access = access_pmovs, .reg = PMOVSSET_EL0 },
15461564

15471565
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
15481566
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
@@ -1694,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
16941712
* PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
16951713
* in 32bit mode. Here we choose to reset it as zero for consistency.
16961714
*/
1697-
{ SYS_DESC(SYS_PMCCFILTR_EL0), access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 },
1715+
{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
1716+
.reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
16981717

16991718
{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
17001719
{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },

virt/kvm/kvm_main.c

+1
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
12921292
return -EINVAL;
12931293
/* We can read the guest memory with __xxx_user() later on. */
12941294
if ((mem->userspace_addr & (PAGE_SIZE - 1)) ||
1295+
(mem->userspace_addr != untagged_addr(mem->userspace_addr)) ||
12951296
!access_ok((void __user *)(unsigned long)mem->userspace_addr,
12961297
mem->memory_size))
12971298
return -EINVAL;

0 commit comments

Comments
 (0)