Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9cf1e08 authored by Paul Mackerras's avatar Paul Mackerras
Browse files

KVM: PPC: Book3S HV: Add new POWER9 guest-accessible SPRs



This adds code to handle two new guest-accessible special-purpose
registers on POWER9: TIDR (thread ID register) and PSSCR (processor
stop status and control register).  They are context-switched
between host and guest, and the guest values can be read and set
via the one_reg interface.

The PSSCR contains some fields which are guest-accessible and some
which are only accessible in hypervisor mode.  We only allow the
guest-accessible fields to be read or set by userspace.

Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 83677f55
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2023,6 +2023,8 @@ registers, find a list below:
  PPC   | KVM_REG_PPC_WORT              | 64
  PPC	| KVM_REG_PPC_SPRG9             | 64
  PPC	| KVM_REG_PPC_DBSR              | 32
  PPC   | KVM_REG_PPC_TIDR              | 64
  PPC   | KVM_REG_PPC_PSSCR             | 64
  PPC   | KVM_REG_PPC_TM_GPR0           | 64
          ...
  PPC   | KVM_REG_PPC_TM_GPR31          | 64
+2 −0
Original line number Diff line number Diff line
@@ -517,6 +517,8 @@ struct kvm_vcpu_arch {
	ulong tcscr;
	ulong acop;
	ulong wort;
	ulong tid;
	ulong psscr;
	ulong shadow_srr1;
#endif
	u32 vrsave; /* also USPRG0 */
+4 −0
Original line number Diff line number Diff line
@@ -573,6 +573,10 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_SPRG9	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
#define KVM_REG_PPC_DBSR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb)

/* POWER9 registers */
#define KVM_REG_PPC_TIDR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
#define KVM_REG_PPC_PSSCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)

/* Transactional Memory checkpointed state:
 * This is all GPRs, all VSX regs and a subset of SPRs
 */
+2 −0
Original line number Diff line number Diff line
@@ -548,6 +548,8 @@ int main(void)
	DEFINE(VCPU_TCSCR, offsetof(struct kvm_vcpu, arch.tcscr));
	DEFINE(VCPU_ACOP, offsetof(struct kvm_vcpu, arch.acop));
	DEFINE(VCPU_WORT, offsetof(struct kvm_vcpu, arch.wort));
	DEFINE(VCPU_TID, offsetof(struct kvm_vcpu, arch.tid));
	DEFINE(VCPU_PSSCR, offsetof(struct kvm_vcpu, arch.psscr));
	DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_map));
	DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
	DEFINE(VCORE_NAPPING_THREADS, offsetof(struct kvmppc_vcore, napping_threads));
+12 −0
Original line number Diff line number Diff line
@@ -1230,6 +1230,12 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
	case KVM_REG_PPC_WORT:
		*val = get_reg_val(id, vcpu->arch.wort);
		break;
	case KVM_REG_PPC_TIDR:
		*val = get_reg_val(id, vcpu->arch.tid);
		break;
	case KVM_REG_PPC_PSSCR:
		*val = get_reg_val(id, vcpu->arch.psscr);
		break;
	case KVM_REG_PPC_VPA_ADDR:
		spin_lock(&vcpu->arch.vpa_update_lock);
		*val = get_reg_val(id, vcpu->arch.vpa.next_gpa);
@@ -1431,6 +1437,12 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
	case KVM_REG_PPC_WORT:
		vcpu->arch.wort = set_reg_val(id, *val);
		break;
	case KVM_REG_PPC_TIDR:
		vcpu->arch.tid = set_reg_val(id, *val);
		break;
	case KVM_REG_PPC_PSSCR:
		vcpu->arch.psscr = set_reg_val(id, *val) & PSSCR_GUEST_VIS;
		break;
	case KVM_REG_PPC_VPA_ADDR:
		addr = set_reg_val(id, *val);
		r = -EINVAL;
Loading