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

Commit e4945b9d authored by Cédric Le Goater's avatar Cédric Le Goater Committed by Paul Mackerras
Browse files

KVM: PPC: Book3S HV: XIVE: Add get/set accessors for the VP XIVE state



The state of the thread interrupt management registers needs to be
collected for migration. These registers are cached under the
'xive_saved_state.w01' field of the VCPU when the VPCU context is
pulled from the HW thread. An OPAL call retrieves the backup of the
IPB register in the underlying XIVE NVT structure and merges it in the
KVM state.

Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent e6714bd1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1985,6 +1985,7 @@ registers, find a list below:
  PPC   | KVM_REG_PPC_TLB3PS            | 32
  PPC   | KVM_REG_PPC_EPTCFG            | 32
  PPC   | KVM_REG_PPC_ICP_STATE         | 64
  PPC   | KVM_REG_PPC_VP_STATE          | 128
  PPC   | KVM_REG_PPC_TB_OFFSET         | 64
  PPC   | KVM_REG_PPC_SPMC1             | 32
  PPC   | KVM_REG_PPC_SPMC2             | 32
+17 −0
Original line number Diff line number Diff line
@@ -107,6 +107,23 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
    -ENOENT: Unknown source number
    -EINVAL: Not initialized source number

* VCPU state

  The XIVE IC maintains VP interrupt state in an internal structure
  called the NVT. When a VP is not dispatched on a HW processor
  thread, this structure can be updated by HW if the VP is the target
  of an event notification.

  It is important for migration to capture the cached IPB from the NVT
  as it synthesizes the priorities of the pending interrupts. We
  capture a bit more to report debug information.

  KVM_REG_PPC_VP_STATE (2 * 64bits)
  bits:     |  63  ....  32  |  31  ....  0  |
  values:   |   TIMA word0   |   TIMA word1  |
  bits:     | 127       ..........       64  |
  values:   |            unused              |

* Migration:

  Saving the state of a VM using the XIVE native exploitation mode
+11 −0
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ union kvmppc_one_reg {
		u64	addr;
		u64	length;
	}	vpaval;
	u64	xive_timaval[2];
};

struct kvmppc_ops {
@@ -604,6 +605,10 @@ extern int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
extern void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu);
extern void kvmppc_xive_native_init_module(void);
extern void kvmppc_xive_native_exit_module(void);
extern int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu,
				     union kvmppc_one_reg *val);
extern int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu,
				     union kvmppc_one_reg *val);

#else
static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server,
@@ -636,6 +641,12 @@ static inline int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
static inline void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) { }
static inline void kvmppc_xive_native_init_module(void) { }
static inline void kvmppc_xive_native_exit_module(void) { }
static inline int kvmppc_xive_native_get_vp(struct kvm_vcpu *vcpu,
					    union kvmppc_one_reg *val)
{ return 0; }
static inline int kvmppc_xive_native_set_vp(struct kvm_vcpu *vcpu,
					    union kvmppc_one_reg *val)
{ return -ENOENT; }

#endif /* CONFIG_KVM_XIVE */

+2 −0
Original line number Diff line number Diff line
@@ -482,6 +482,8 @@ struct kvm_ppc_cpu_char {
#define  KVM_REG_PPC_ICP_PPRI_SHIFT	16	/* pending irq priority */
#define  KVM_REG_PPC_ICP_PPRI_MASK	0xff

#define KVM_REG_PPC_VP_STATE	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x8d)

/* Device control API: PPC-specific devices */
#define KVM_DEV_MPIC_GRP_MISC		1
#define   KVM_DEV_MPIC_BASE_ADDR	0	/* 64-bit */
+24 −0
Original line number Diff line number Diff line
@@ -651,6 +651,18 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
				*val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
			break;
#endif /* CONFIG_KVM_XICS */
#ifdef CONFIG_KVM_XIVE
		case KVM_REG_PPC_VP_STATE:
			if (!vcpu->arch.xive_vcpu) {
				r = -ENXIO;
				break;
			}
			if (xive_enabled())
				r = kvmppc_xive_native_get_vp(vcpu, val);
			else
				r = -ENXIO;
			break;
#endif /* CONFIG_KVM_XIVE */
		case KVM_REG_PPC_FSCR:
			*val = get_reg_val(id, vcpu->arch.fscr);
			break;
@@ -724,6 +736,18 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
				r = kvmppc_xics_set_icp(vcpu, set_reg_val(id, *val));
			break;
#endif /* CONFIG_KVM_XICS */
#ifdef CONFIG_KVM_XIVE
		case KVM_REG_PPC_VP_STATE:
			if (!vcpu->arch.xive_vcpu) {
				r = -ENXIO;
				break;
			}
			if (xive_enabled())
				r = kvmppc_xive_native_set_vp(vcpu, val);
			else
				r = -ENXIO;
			break;
#endif /* CONFIG_KVM_XIVE */
		case KVM_REG_PPC_FSCR:
			vcpu->arch.fscr = set_reg_val(id, *val);
			break;
Loading