spapr/xive: Add a 'hv-prio' property to represent the KVM escalation priority

On POWER9, the KVM XIVE device uses priority 7 for the escalation
interrupts. On POWER10, the host can use a reduced set of priorities
and KVM will configure the escalation priority to a lower number. In
any case, the guest is allowed to use priorities in a single range :

    [ 0 .. (maxprio - 1) ].

Introduce a 'hv-prio' property to represent the escalation priority
number and use it to compute the "ibm,plat-res-int-priorities"
property defining the priority ranges reserved by the hypervisor.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200819130843.2230799-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Cédric Le Goater 2020-08-19 15:08:36 +02:00 committed by David Gibson
parent 98b49b2bea
commit 4f311a7089
2 changed files with 16 additions and 19 deletions

View File

@ -595,6 +595,7 @@ static Property spapr_xive_properties[] = {
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
DEFINE_PROP_UINT8("hv-prio", SpaprXive, hv_prio, 7),
DEFINE_PROP_END_OF_LIST(),
};
@ -692,12 +693,13 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
cpu_to_be32(16), /* 64K */
};
/*
* The following array is in sync with the reserved priorities
* defined by the 'spapr_xive_priority_is_reserved' routine.
* QEMU/KVM only needs to define a single range to reserve the
* escalation priority. A priority bitmask would have been more
* appropriate.
*/
uint32_t plat_res_int_priorities[] = {
cpu_to_be32(7), /* start */
cpu_to_be32(0xf8), /* count */
cpu_to_be32(xive->hv_prio), /* start */
cpu_to_be32(0xff - xive->hv_prio), /* count */
};
/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
@ -844,19 +846,12 @@ type_init(spapr_xive_register_types)
*/
/*
* Linux hosts under OPAL reserve priority 7 for their own escalation
* interrupts (DD2.X POWER9). So we only allow the guest to use
* priorities [0..6].
* On POWER9, the KVM XIVE device uses priority 7 for the escalation
* interrupts. So we only allow the guest to use priorities [0..6].
*/
static bool spapr_xive_priority_is_reserved(uint8_t priority)
static bool spapr_xive_priority_is_reserved(SpaprXive *xive, uint8_t priority)
{
switch (priority) {
case 0 ... 6:
return false;
case 7: /* OPAL escalation queue */
default:
return true;
}
return priority >= xive->hv_prio;
}
/*
@ -1053,7 +1048,7 @@ static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
new_eas.w = eas.w & cpu_to_be64(~EAS_MASKED);
}
if (spapr_xive_priority_is_reserved(priority)) {
if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P4;
@ -1212,7 +1207,7 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
if (spapr_xive_priority_is_reserved(priority)) {
if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;
@ -1299,7 +1294,7 @@ static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
if (spapr_xive_priority_is_reserved(priority)) {
if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;
@ -1466,7 +1461,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
* This is not needed when running the emulation under QEMU
*/
if (spapr_xive_priority_is_reserved(priority)) {
if (spapr_xive_priority_is_reserved(xive, priority)) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
" is reserved\n", priority);
return H_P3;

View File

@ -49,6 +49,8 @@ typedef struct SpaprXive {
void *tm_mmap;
MemoryRegion tm_mmio_kvm;
VMChangeStateEntry *change;
uint8_t hv_prio;
} SpaprXive;
typedef struct SpaprXiveClass {