Commit f771b557 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

KVM: PPC: Use KVM_CAP_PPC_AIL_MODE_3

Use KVM_CAP_PPC_AIL_MODE_3 to advertise the capability to set the AIL
resource mode to 3 with the H_SET_MODE hypercall. This capability
differs between processor types and KVM types (PR, HV, Nested HV), and
affects guest-visible behaviour.

QEMU will implement a cap-ail-mode-3 to control this behaviour[1], and
use the KVM CAP if available to determine KVM support[2].

[1] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00437.html
[2] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00439.html



Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarFabiano Rosas <farosas@linux.ibm.com>
[mpe: Rebase onto 93b71801 from kvm-ppc-cap-210 branch, add EXPORT_SYMBOL]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220222064727.2314380-4-npiggin@gmail.com
parent 839d893b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -28,11 +28,13 @@ void setup_panic(void);
#define ARCH_PANIC_TIMEOUT 180

#ifdef CONFIG_PPC_PSERIES
extern bool pseries_reloc_on_exception(void);
extern bool pseries_enable_reloc_on_exc(void);
extern void pseries_disable_reloc_on_exc(void);
extern void pseries_big_endian_exceptions(void);
void __init pseries_little_endian_exceptions(void);
#else
static inline bool pseries_reloc_on_exception(void) { return false; }
static inline bool pseries_enable_reloc_on_exc(void) { return false; }
static inline void pseries_disable_reloc_on_exc(void) {}
static inline void pseries_big_endian_exceptions(void) {}
+17 −0
Original line number Diff line number Diff line
@@ -705,6 +705,23 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
		r = 1;
		break;
#endif
	case KVM_CAP_PPC_AIL_MODE_3:
		r = 0;
		/*
		 * KVM PR, POWER7, and some POWER9s don't support AIL=3 mode.
		 * The POWER9s can support it if the guest runs in hash mode,
		 * but QEMU doesn't necessarily query the capability in time.
		 */
		if (hv_enabled) {
			if (kvmhv_on_pseries()) {
				if (pseries_reloc_on_exception())
					r = 1;
			} else if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
				  !cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
				r = 1;
			}
		}
		break;
	default:
		r = 0;
		break;
+12 −1
Original line number Diff line number Diff line
@@ -353,6 +353,14 @@ static void pseries_lpar_idle(void)
	pseries_idle_epilog();
}

static bool pseries_reloc_on_exception_enabled;

bool pseries_reloc_on_exception(void)
{
	return pseries_reloc_on_exception_enabled;
}
EXPORT_SYMBOL_GPL(pseries_reloc_on_exception);

/*
 * Enable relocation on during exceptions. This has partition wide scope and
 * may take a while to complete, if it takes longer than one second we will
@@ -377,6 +385,7 @@ bool pseries_enable_reloc_on_exc(void)
					" on exceptions: %ld\n", rc);
				return false;
			}
			pseries_reloc_on_exception_enabled = true;
			return true;
		}

@@ -404,7 +413,9 @@ void pseries_disable_reloc_on_exc(void)
			break;
		mdelay(get_longbusy_msecs(rc));
	}
	if (rc != H_SUCCESS)
	if (rc == H_SUCCESS)
		pseries_reloc_on_exception_enabled = false;
	else
		pr_warn("Warning: Failed to disable relocation on exceptions: %ld\n",
			rc);
}