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:
parent
98b49b2bea
commit
4f311a7089
@ -595,6 +595,7 @@ static Property spapr_xive_properties[] = {
|
|||||||
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
|
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
|
||||||
DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
|
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_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
|
||||||
|
DEFINE_PROP_UINT8("hv-prio", SpaprXive, hv_prio, 7),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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 */
|
cpu_to_be32(16), /* 64K */
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* The following array is in sync with the reserved priorities
|
* QEMU/KVM only needs to define a single range to reserve the
|
||||||
* defined by the 'spapr_xive_priority_is_reserved' routine.
|
* escalation priority. A priority bitmask would have been more
|
||||||
|
* appropriate.
|
||||||
*/
|
*/
|
||||||
uint32_t plat_res_int_priorities[] = {
|
uint32_t plat_res_int_priorities[] = {
|
||||||
cpu_to_be32(7), /* start */
|
cpu_to_be32(xive->hv_prio), /* start */
|
||||||
cpu_to_be32(0xf8), /* count */
|
cpu_to_be32(0xff - xive->hv_prio), /* count */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
|
/* 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
|
* On POWER9, the KVM XIVE device uses priority 7 for the escalation
|
||||||
* interrupts (DD2.X POWER9). So we only allow the guest to use
|
* interrupts. So we only allow the guest to use priorities [0..6].
|
||||||
* 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) {
|
return priority >= xive->hv_prio;
|
||||||
case 0 ... 6:
|
|
||||||
return false;
|
|
||||||
case 7: /* OPAL escalation queue */
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1053,7 +1048,7 @@ static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
|
|||||||
new_eas.w = eas.w & cpu_to_be64(~EAS_MASKED);
|
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
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
||||||
" is reserved\n", priority);
|
" is reserved\n", priority);
|
||||||
return H_P4;
|
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
|
* 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
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
||||||
" is reserved\n", priority);
|
" is reserved\n", priority);
|
||||||
return H_P3;
|
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
|
* 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
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
||||||
" is reserved\n", priority);
|
" is reserved\n", priority);
|
||||||
return H_P3;
|
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
|
* 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
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
||||||
" is reserved\n", priority);
|
" is reserved\n", priority);
|
||||||
return H_P3;
|
return H_P3;
|
||||||
|
@ -49,6 +49,8 @@ typedef struct SpaprXive {
|
|||||||
void *tm_mmap;
|
void *tm_mmap;
|
||||||
MemoryRegion tm_mmio_kvm;
|
MemoryRegion tm_mmio_kvm;
|
||||||
VMChangeStateEntry *change;
|
VMChangeStateEntry *change;
|
||||||
|
|
||||||
|
uint8_t hv_prio;
|
||||||
} SpaprXive;
|
} SpaprXive;
|
||||||
|
|
||||||
typedef struct SpaprXiveClass {
|
typedef struct SpaprXiveClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user