Merge branch 'kvm-arm64/misc' into kvmarm/next

* kvm-arm64/misc:
  : Miscellaneous fixes/cleanups for KVM/arm64
  :
  :  - Fixes for computing POE output permissions
  :
  :  - Return ENXIO for invalid VGIC device attribute
  :
  :  - String helper conversions
  arm64: kvm: trace_handle_exit: use string choices helper
  arm64: kvm: sys_regs: use string choices helper
  KVM: arm64: Follow specification when implementing WXN
  KVM: arm64: Remove the wi->{e0,}poe vs wr->{p,u}ov confusion
  KVM: arm64: vgic-its: Return -ENXIO to invalid KVM_DEV_ARM_VGIC_GRP_CTRL attrs

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
Oliver Upton 2025-07-26 08:54:47 -07:00
commit 0a2c9d808a
5 changed files with 50 additions and 39 deletions

View file

@ -1047,34 +1047,51 @@ static void compute_s1_overlay_permissions(struct kvm_vcpu *vcpu,
idx = FIELD_GET(PTE_PO_IDX_MASK, wr->desc);
switch (wi->regime) {
case TR_EL10:
pov_perms = perm_idx(vcpu, POR_EL1, idx);
uov_perms = perm_idx(vcpu, POR_EL0, idx);
break;
case TR_EL20:
pov_perms = perm_idx(vcpu, POR_EL2, idx);
uov_perms = perm_idx(vcpu, POR_EL0, idx);
break;
case TR_EL2:
pov_perms = perm_idx(vcpu, POR_EL2, idx);
uov_perms = 0;
break;
}
if (wr->pov) {
switch (wi->regime) {
case TR_EL10:
pov_perms = perm_idx(vcpu, POR_EL1, idx);
break;
case TR_EL20:
pov_perms = perm_idx(vcpu, POR_EL2, idx);
break;
case TR_EL2:
pov_perms = perm_idx(vcpu, POR_EL2, idx);
break;
}
if (pov_perms & ~POE_RWX)
pov_perms = POE_NONE;
if (pov_perms & ~POE_RWX)
pov_perms = POE_NONE;
/* R_QXXPC, S1PrivOverflow enabled */
if (wr->pwxn && (pov_perms & POE_X))
pov_perms &= ~POE_W;
if (wi->poe && wr->pov) {
wr->pr &= pov_perms & POE_R;
wr->pw &= pov_perms & POE_W;
wr->px &= pov_perms & POE_X;
}
if (uov_perms & ~POE_RWX)
uov_perms = POE_NONE;
if (wr->uov) {
switch (wi->regime) {
case TR_EL10:
uov_perms = perm_idx(vcpu, POR_EL0, idx);
break;
case TR_EL20:
uov_perms = perm_idx(vcpu, POR_EL0, idx);
break;
case TR_EL2:
uov_perms = 0;
break;
}
if (uov_perms & ~POE_RWX)
uov_perms = POE_NONE;
/* R_NPBXC, S1UnprivOverlay enabled */
if (wr->uwxn && (uov_perms & POE_X))
uov_perms &= ~POE_W;
if (wi->e0poe && wr->uov) {
wr->ur &= uov_perms & POE_R;
wr->uw &= uov_perms & POE_W;
wr->ux &= uov_perms & POE_X;
@ -1095,24 +1112,15 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
if (!wi->hpd)
compute_s1_hierarchical_permissions(vcpu, wi, wr);
if (wi->poe || wi->e0poe)
compute_s1_overlay_permissions(vcpu, wi, wr);
compute_s1_overlay_permissions(vcpu, wi, wr);
/* R_QXXPC */
if (wr->pwxn) {
if (!wr->pov && wr->pw)
wr->px = false;
if (wr->pov && wr->px)
wr->pw = false;
}
/* R_QXXPC, S1PrivOverlay disabled */
if (!wr->pov)
wr->px &= !(wr->pwxn && wr->pw);
/* R_NPBXC */
if (wr->uwxn) {
if (!wr->uov && wr->uw)
wr->ux = false;
if (wr->uov && wr->ux)
wr->uw = false;
}
/* R_NPBXC, S1UnprivOverlay disabled */
if (!wr->uov)
wr->ux &= !(wr->uwxn && wr->uw);
pan = wi->pan && (wr->ur || wr->uw ||
(pan3_enabled(vcpu, wi->regime) && wr->ux));

View file

@ -4523,7 +4523,7 @@ static bool kvm_esr_cp10_id_to_sys64(u64 esr, struct sys_reg_params *params)
return true;
kvm_pr_unimpl("Unhandled cp10 register %s: %u\n",
params->is_write ? "write" : "read", reg_id);
str_write_read(params->is_write), reg_id);
return false;
}

View file

@ -108,7 +108,7 @@ inline void print_sys_reg_msg(const struct sys_reg_params *p,
/* Look, we even formatted it for you to paste into the table! */
kvm_pr_unimpl("%pV { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), func_%s },\n",
&(struct va_format){ fmt, &va },
p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, p->is_write ? "write" : "read");
p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, str_write_read(p->is_write));
va_end(va);
}

View file

@ -113,7 +113,7 @@ TRACE_EVENT(kvm_sys_access,
__entry->vcpu_pc, __entry->name ?: "UNKN",
__entry->Op0, __entry->Op1, __entry->CRn,
__entry->CRm, __entry->Op2,
__entry->is_write ? "write" : "read")
str_write_read(__entry->is_write))
);
TRACE_EVENT(kvm_set_guest_debug,

View file

@ -2694,6 +2694,9 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
case KVM_DEV_ARM_ITS_RESTORE_TABLES:
ret = abi->restore_tables(its);
break;
default:
ret = -ENXIO;
break;
}
mutex_unlock(&its->its_lock);