Commit ba6d8efb authored by Michael Ellerman's avatar Michael Ellerman
Browse files

Merge branch 'topic/ppc-kvm' into next

parents 27aef939 590d2f93
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_ARCH_31			LONG_ASM_CONST(0x0004000000000000)
#define CPU_FTR_DAWR1			LONG_ASM_CONST(0x0008000000000000)
#define CPU_FTR_DEXCR_NPHIE		LONG_ASM_CONST(0x0010000000000000)
#define CPU_FTR_P11_PVR			LONG_ASM_CONST(0x0020000000000000)

#ifndef __ASSEMBLY__

@@ -454,7 +455,7 @@ static inline void cpu_feature_keys_init(void) { }
	    CPU_FTR_DAWR | CPU_FTR_DAWR1 | \
	    CPU_FTR_DEXCR_NPHIE)

#define CPU_FTRS_POWER11	CPU_FTRS_POWER10
#define CPU_FTRS_POWER11	(CPU_FTRS_POWER10 | CPU_FTR_P11_PVR)

#define CPU_FTRS_CELL	(CPU_FTR_LWSYNC | \
	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
@@ -475,7 +476,7 @@ static inline void cpu_feature_keys_init(void) { }
	    (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
	     CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
	     CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \
	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10)
	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
#else
#define CPU_FTRS_POSSIBLE	\
	    (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
@@ -483,7 +484,7 @@ static inline void cpu_feature_keys_init(void) { }
	     CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
	     CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
	     CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | \
	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10)
	     CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
#endif
#else
@@ -547,7 +548,7 @@ enum {
	    (CPU_FTRS_POSSIBLE & ~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & \
	     CPU_FTRS_POWER7 & CPU_FTRS_POWER8E & CPU_FTRS_POWER8 & \
	     CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
	     CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE)
	     CPU_FTRS_POWER10 & CPU_FTRS_POWER11 & CPU_FTRS_DT_CPU_BASE)
#else
#define CPU_FTRS_ALWAYS		\
	    (CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
@@ -555,7 +556,7 @@ enum {
	     CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \
	     ~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & CPU_FTRS_POSSIBLE & \
	     CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
	     CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE)
	     CPU_FTRS_POWER10 & CPU_FTRS_POWER11 & CPU_FTRS_DT_CPU_BASE)
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
#endif
#else
+1 −0
Original line number Diff line number Diff line
@@ -495,6 +495,7 @@
#define H_GUEST_CAP_COPY_MEM	(1UL<<(63-0))
#define H_GUEST_CAP_POWER9	(1UL<<(63-1))
#define H_GUEST_CAP_POWER10	(1UL<<(63-2))
#define H_GUEST_CAP_POWER11	(1UL<<(63-3))
#define H_GUEST_CAP_BITMAP2	(1UL<<(63-63))

#ifndef __ASSEMBLY__
+2 −2
Original line number Diff line number Diff line
@@ -684,8 +684,8 @@ int kvmhv_nestedv2_set_ptbl_entry(unsigned long lpid, u64 dw0, u64 dw1);
int kvmhv_nestedv2_parse_output(struct kvm_vcpu *vcpu);
int kvmhv_nestedv2_set_vpa(struct kvm_vcpu *vcpu, unsigned long vpa);

int kmvhv_counters_tracepoint_regfunc(void);
void kmvhv_counters_tracepoint_unregfunc(void);
int kvmhv_counters_tracepoint_regfunc(void);
void kvmhv_counters_tracepoint_unregfunc(void);
int kvmhv_get_l2_counters_status(void);
void kvmhv_set_l2_counters_status(int cpu, bool status);

+18 −34
Original line number Diff line number Diff line
@@ -400,6 +400,9 @@ static inline unsigned long map_pcr_to_cap(unsigned long pcr)
		cap = H_GUEST_CAP_POWER9;
		break;
	case PCR_ARCH_31:
		if (cpu_has_feature(CPU_FTR_P11_PVR))
			cap = H_GUEST_CAP_POWER11;
		else
			cap = H_GUEST_CAP_POWER10;
		break;
	default:
@@ -415,7 +418,7 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	/* We can (emulate) our own architecture version and anything older */
	if (cpu_has_feature(CPU_FTR_ARCH_31))
	if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31))
		host_pcr_bit = PCR_ARCH_31;
	else if (cpu_has_feature(CPU_FTR_ARCH_300))
		host_pcr_bit = PCR_ARCH_300;
@@ -2060,36 +2063,9 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu)
		fallthrough; /* go to facility unavailable handler */
#endif

	case BOOK3S_INTERRUPT_H_FAC_UNAVAIL: {
		u64 cause = vcpu->arch.hfscr >> 56;

		/*
		 * Only pass HFU interrupts to the L1 if the facility is
		 * permitted but disabled by the L1's HFSCR, otherwise
		 * the interrupt does not make sense to the L1 so turn
		 * it into a HEAI.
		 */
		if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) ||
				(vcpu->arch.nested_hfscr & (1UL << cause))) {
			ppc_inst_t pinst;
			vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST;

			/*
			 * If the fetch failed, return to guest and
			 * try executing it again.
			 */
			r = kvmppc_get_last_inst(vcpu, INST_GENERIC, &pinst);
			vcpu->arch.emul_inst = ppc_inst_val(pinst);
			if (r != EMULATE_DONE)
				r = RESUME_GUEST;
			else
				r = RESUME_HOST;
		} else {
	case BOOK3S_INTERRUPT_H_FAC_UNAVAIL:
		r = RESUME_HOST;
		}

		break;
	}

	case BOOK3S_INTERRUPT_HV_RM_HARD:
		vcpu->arch.trap = 0;
@@ -4154,7 +4130,7 @@ void kvmhv_set_l2_counters_status(int cpu, bool status)
		lppaca_of(cpu).l2_counters_enable = 0;
}

int kmvhv_counters_tracepoint_regfunc(void)
int kvmhv_counters_tracepoint_regfunc(void)
{
	int cpu;

@@ -4164,7 +4140,7 @@ int kmvhv_counters_tracepoint_regfunc(void)
	return 0;
}

void kmvhv_counters_tracepoint_unregfunc(void)
void kvmhv_counters_tracepoint_unregfunc(void)
{
	int cpu;

@@ -4309,6 +4285,15 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns
	}
	hvregs.hdec_expiry = time_limit;

	/*
	 * hvregs has the doorbell status, so zero it here which
	 * enables us to receive doorbells when H_ENTER_NESTED is
	 * in progress for this vCPU
	 */

	if (vcpu->arch.doorbell_request)
		vcpu->arch.doorbell_request = 0;

	/*
	 * When setting DEC, we must always deal with irq_work_raise
	 * via NMI vs setting DEC. The problem occurs right as we
@@ -4900,7 +4885,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
				lpcr |= LPCR_MER;
		}
	} else if (vcpu->arch.pending_exceptions ||
		   vcpu->arch.doorbell_request ||
		   xive_interrupt_pending(vcpu)) {
		vcpu->arch.ret = RESUME_HOST;
		goto out;
+12 −4
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	hr->pcr = vc->pcr | PCR_MASK;
	hr->dpdes = vc->dpdes;
	hr->dpdes = vcpu->arch.doorbell_request;
	hr->hfscr = vcpu->arch.hfscr;
	hr->tb_offset = vc->tb_offset;
	hr->dawr0 = vcpu->arch.dawr0;
@@ -105,7 +105,7 @@ static void save_hv_return_state(struct kvm_vcpu *vcpu,
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	hr->dpdes = vc->dpdes;
	hr->dpdes = vcpu->arch.doorbell_request;
	hr->purr = vcpu->arch.purr;
	hr->spurr = vcpu->arch.spurr;
	hr->ic = vcpu->arch.ic;
@@ -143,7 +143,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	vc->pcr = hr->pcr | PCR_MASK;
	vc->dpdes = hr->dpdes;
	vcpu->arch.doorbell_request = hr->dpdes;
	vcpu->arch.hfscr = hr->hfscr;
	vcpu->arch.dawr0 = hr->dawr0;
	vcpu->arch.dawrx0 = hr->dawrx0;
@@ -170,7 +170,13 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu,
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	vc->dpdes = hr->dpdes;
	/*
	 * This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled.
	 * Make sure we preserve the doorbell if it was either:
	 *   a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1)
	 *   b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1)
	 */
	vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes;
	vcpu->arch.hfscr = hr->hfscr;
	vcpu->arch.purr = hr->purr;
	vcpu->arch.spurr = hr->spurr;
@@ -445,6 +451,8 @@ long kvmhv_nested_init(void)
	if (rc == H_SUCCESS) {
		unsigned long capabilities = 0;

		if (cpu_has_feature(CPU_FTR_P11_PVR))
			capabilities |= H_GUEST_CAP_POWER11;
		if (cpu_has_feature(CPU_FTR_ARCH_31))
			capabilities |= H_GUEST_CAP_POWER10;
		if (cpu_has_feature(CPU_FTR_ARCH_300))
Loading