OSDN Git Service

KVM: arm64: Remove PMSWINC_EL0 shadow register
authorMarc Zyngier <maz@kernel.org>
Mon, 19 Jul 2021 12:39:02 +0000 (13:39 +0100)
committerMarc Zyngier <maz@kernel.org>
Mon, 2 Aug 2021 13:26:34 +0000 (14:26 +0100)
We keep an entry for the PMSWINC_EL0 register in the vcpu structure,
while *never* writing anything there outside of reset.

Given that the register is defined as write-only, that we always
trap when this register is accessed, there is little point in saving
anything anyway.

Get rid of the entry, and save a mighty 8 bytes per vcpu structure.

We still need to keep it exposed to userspace in order to preserve
backward compatibility with previously saved VMs. Since userspace
cannot expect any effect of writing to PMSWINC_EL0, treat the
register as RAZ/WI for the purpose of userspace access.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210719123902.1493805-5-maz@kernel.org
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/sys_regs.c

index 4191158..afc1696 100644 (file)
@@ -185,7 +185,6 @@ enum vcpu_sysreg {
        PMCNTENSET_EL0, /* Count Enable Set Register */
        PMINTENSET_EL1, /* Interrupt Enable Set Register */
        PMOVSSET_EL0,   /* Overflow Flag Status Set Register */
-       PMSWINC_EL0,    /* Software Increment Register */
        PMUSERENR_EL0,  /* User Enable Register */
 
        /* Pointer Authentication Registers in a strict increasing order. */
index f221396..a1f5101 100644 (file)
@@ -1286,6 +1286,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
        return __set_id_reg(vcpu, rd, uaddr, true);
 }
 
+static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+                     const struct kvm_one_reg *reg, void __user *uaddr)
+{
+       int err;
+       u64 val;
+
+       /* Perform the access even if we are going to ignore the value */
+       err = reg_from_user(&val, uaddr, sys_reg_to_index(rd));
+       if (err)
+               return err;
+
+       return 0;
+}
+
 static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                       const struct sys_reg_desc *r)
 {
@@ -1629,8 +1643,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
          .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
        { PMU_SYS_REG(SYS_PMOVSCLR_EL0),
          .access = access_pmovs, .reg = PMOVSSET_EL0 },
+       /*
+        * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was
+        * previously (and pointlessly) advertised in the past...
+        */
        { PMU_SYS_REG(SYS_PMSWINC_EL0),
-         .access = access_pmswinc, .reg = PMSWINC_EL0 },
+         .get_user = get_raz_id_reg, .set_user = set_wi_reg,
+         .access = access_pmswinc, .reset = NULL },
        { PMU_SYS_REG(SYS_PMSELR_EL0),
          .access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 },
        { PMU_SYS_REG(SYS_PMCEID0_EL0),