[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH 13/25] spapr: introduce the XIVE Event Queues
From: |
Cédric Le Goater |
Subject: |
Re: [Qemu-ppc] [PATCH 13/25] spapr: introduce the XIVE Event Queues |
Date: |
Fri, 24 Nov 2017 09:15:50 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 |
On 11/23/2017 09:31 PM, Benjamin Herrenschmidt wrote:
> On Thu, 2017-11-23 at 14:29 +0100, Cédric Le Goater wrote:
>> The Event Queue Descriptor (EQD) table, also known as Event Notification
>> Descriptor (END), is one of the internal tables the XIVE interrupt
>> controller uses to redirect exception from event sources to CPU
>> threads.
>
> Keep in mind tha we want to only expose to the guest priorities 0..6
> as priority 7 will not be available with KVM on DD2.0 chips.
The hcall patch 19 introduces the "ibm,plat-res-int-priorities" property.
The priority ranges reserved by the hypervisor are the following :
static const uint32_t reserved_priorities[] = {
7, /* start */
0xf8, /* count */
};
So The Linux driver is expected to choose priority 6. The priority
validity is then checked in each hcall returning H_P4/H_P3 in case of
failure.
But it is true that we scale the arrays with :
#define XIVE_PRIORITY_MAX 7
Do you want QEMU to completely remove prio 7 ?
C.
>> The EQD specifies on which Event Queue the event data should be posted
>> when an exception occurs (later on pulled by the OS) and which server
>> (VPD in XIVE terminology) to notify. The Event Queue is a much more
>> complex structure but we start with a simple model for the sPAPR
>> machine.
>>
>> There is one XiveEQ per priority and the model chooses to store them
>> under the Xive Interrupt presenter model. It will be retrieved, just
>> like for XICS, through the 'intc' object pointer of the CPU.
>>
>> The EQ indexing follows a simple pattern:
>>
>> (server << 3) | (priority & 0x7)
>>
>> Signed-off-by: Cédric Le Goater <address@hidden>
>> ---
>> hw/intc/spapr_xive.c | 56
>> +++++++++++++++++++++++++++++++++++++++++++++++++
>> hw/intc/xive-internal.h | 50 +++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 106 insertions(+)
>>
>> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
>> index 554b25e0884c..983317a6b3f6 100644
>> --- a/hw/intc/spapr_xive.c
>> +++ b/hw/intc/spapr_xive.c
>> @@ -23,6 +23,7 @@
>> #include "sysemu/dma.h"
>> #include "monitor/monitor.h"
>> #include "hw/ppc/spapr_xive.h"
>> +#include "hw/ppc/spapr.h"
>> #include "hw/ppc/xics.h"
>>
>> #include "xive-internal.h"
>> @@ -34,6 +35,8 @@ struct sPAPRXiveICP {
>> uint8_t tima[TM_RING_COUNT * 0x10];
>> uint8_t *tima_os;
>> qemu_irq output;
>> +
>> + XiveEQ eqt[XIVE_PRIORITY_MAX + 1];
>> };
>>
>> static uint64_t spapr_xive_icp_accept(sPAPRXiveICP *icp)
>> @@ -183,6 +186,13 @@ static const MemoryRegionOps spapr_xive_tm_ops = {
>> },
>> };
>>
>> +static sPAPRXiveICP *spapr_xive_icp_get(sPAPRXive *xive, int server)
>> +{
>> + PowerPCCPU *cpu = spapr_find_cpu(server);
>> +
>> + return cpu ? SPAPR_XIVE_ICP(cpu->intc) : NULL;
>> +}
>> +
>> static void spapr_xive_irq(sPAPRXive *xive, int lisn)
>> {
>>
>> @@ -632,6 +642,8 @@ static void spapr_xive_icp_reset(void *dev)
>> sPAPRXiveICP *xicp = SPAPR_XIVE_ICP(dev);
>>
>> memset(xicp->tima, 0, sizeof(xicp->tima));
>> +
>> + memset(xicp->eqt, 0, sizeof(xicp->eqt));
>> }
>>
>> static void spapr_xive_icp_realize(DeviceState *dev, Error **errp)
>> @@ -683,6 +695,23 @@ static void spapr_xive_icp_init(Object *obj)
>> xicp->tima_os = &xicp->tima[TM_QW1_OS];
>> }
>>
>> +static const VMStateDescription vmstate_spapr_xive_icp_eq = {
>> + .name = TYPE_SPAPR_XIVE_ICP "/eq",
>> + .version_id = 1,
>> + .minimum_version_id = 1,
>> + .fields = (VMStateField []) {
>> + VMSTATE_UINT32(w0, XiveEQ),
>> + VMSTATE_UINT32(w1, XiveEQ),
>> + VMSTATE_UINT32(w2, XiveEQ),
>> + VMSTATE_UINT32(w3, XiveEQ),
>> + VMSTATE_UINT32(w4, XiveEQ),
>> + VMSTATE_UINT32(w5, XiveEQ),
>> + VMSTATE_UINT32(w6, XiveEQ),
>> + VMSTATE_UINT32(w7, XiveEQ),
>> + VMSTATE_END_OF_LIST()
>> + },
>> +};
>> +
>> static bool vmstate_spapr_xive_icp_needed(void *opaque)
>> {
>> /* TODO check machine XIVE support */
>> @@ -696,6 +725,8 @@ static const VMStateDescription vmstate_spapr_xive_icp =
>> {
>> .needed = vmstate_spapr_xive_icp_needed,
>> .fields = (VMStateField[]) {
>> VMSTATE_BUFFER(tima, sPAPRXiveICP),
>> + VMSTATE_STRUCT_ARRAY(eqt, sPAPRXiveICP, (XIVE_PRIORITY_MAX + 1), 1,
>> + vmstate_spapr_xive_icp_eq, XiveEQ),
>> VMSTATE_END_OF_LIST()
>> },
>> };
>> @@ -755,3 +786,28 @@ bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t
>> lisn)
>> ive->w &= ~IVE_VALID;
>> return true;
>> }
>> +
>> +/*
>> + * Use a simple indexing for the EQs.
>> + */
>> +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t eq_idx)
>> +{
>> + int priority = eq_idx & 0x7;
>> + sPAPRXiveICP *xicp = spapr_xive_icp_get(xive, eq_idx >> 3);
>> +
>> + return xicp ? &xicp->eqt[priority] : NULL;
>> +}
>> +
>> +bool spapr_xive_eq_for_server(sPAPRXive *xive, uint32_t server,
>> + uint8_t priority, uint32_t *out_eq_idx)
>> +{
>> + if (priority > XIVE_PRIORITY_MAX) {
>> + return false;
>> + }
>> +
>> + if (out_eq_idx) {
>> + *out_eq_idx = (server << 3) | (priority & 0x7);
>> + }
>> +
>> + return true;
>> +}
>> diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h
>> index 7d329f203a9b..c3949671aa03 100644
>> --- a/hw/intc/xive-internal.h
>> +++ b/hw/intc/xive-internal.h
>> @@ -131,9 +131,59 @@ typedef struct XiveIVE {
>> #define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ
>> */
>> } XiveIVE;
>>
>> +/* EQ */
>> +typedef struct XiveEQ {
>> + uint32_t w0;
>> +#define EQ_W0_VALID PPC_BIT32(0)
>> +#define EQ_W0_ENQUEUE PPC_BIT32(1)
>> +#define EQ_W0_UCOND_NOTIFY PPC_BIT32(2)
>> +#define EQ_W0_BACKLOG PPC_BIT32(3)
>> +#define EQ_W0_PRECL_ESC_CTL PPC_BIT32(4)
>> +#define EQ_W0_ESCALATE_CTL PPC_BIT32(5)
>> +#define EQ_W0_END_OF_INTR PPC_BIT32(6)
>> +#define EQ_W0_QSIZE PPC_BITMASK32(12, 15)
>> +#define EQ_W0_SW0 PPC_BIT32(16)
>> +#define EQ_W0_FIRMWARE EQ_W0_SW0 /* Owned by FW */
>> +#define EQ_QSIZE_4K 0
>> +#define EQ_QSIZE_64K 4
>> +#define EQ_W0_HWDEP PPC_BITMASK32(24, 31)
>> + uint32_t w1;
>> +#define EQ_W1_ESn PPC_BITMASK32(0, 1)
>> +#define EQ_W1_ESn_P PPC_BIT32(0)
>> +#define EQ_W1_ESn_Q PPC_BIT32(1)
>> +#define EQ_W1_ESe PPC_BITMASK32(2, 3)
>> +#define EQ_W1_ESe_P PPC_BIT32(2)
>> +#define EQ_W1_ESe_Q PPC_BIT32(3)
>> +#define EQ_W1_GENERATION PPC_BIT32(9)
>> +#define EQ_W1_PAGE_OFF PPC_BITMASK32(10, 31)
>> + uint32_t w2;
>> +#define EQ_W2_MIGRATION_REG PPC_BITMASK32(0, 3)
>> +#define EQ_W2_OP_DESC_HI PPC_BITMASK32(4, 31)
>> + uint32_t w3;
>> +#define EQ_W3_OP_DESC_LO PPC_BITMASK32(0, 31)
>> + uint32_t w4;
>> +#define EQ_W4_ESC_EQ_BLOCK PPC_BITMASK32(4, 7)
>> +#define EQ_W4_ESC_EQ_INDEX PPC_BITMASK32(8, 31)
>> + uint32_t w5;
>> +#define EQ_W5_ESC_EQ_DATA PPC_BITMASK32(1, 31)
>> + uint32_t w6;
>> +#define EQ_W6_FORMAT_BIT PPC_BIT32(8)
>> +#define EQ_W6_NVT_BLOCK PPC_BITMASK32(9, 12)
>> +#define EQ_W6_NVT_INDEX PPC_BITMASK32(13, 31)
>> + uint32_t w7;
>> +#define EQ_W7_F0_IGNORE PPC_BIT32(0)
>> +#define EQ_W7_F0_BLK_GROUPING PPC_BIT32(1)
>> +#define EQ_W7_F0_PRIORITY PPC_BITMASK32(8, 15)
>> +#define EQ_W7_F1_WAKEZ PPC_BIT32(0)
>> +#define EQ_W7_F1_LOG_SERVER_ID PPC_BITMASK32(1, 31)
>> +} XiveEQ;
>> +
>> #define XIVE_PRIORITY_MAX 7
>>
>> void spapr_xive_reset(void *dev);
>> XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn);
>> +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t idx);
>> +bool spapr_xive_eq_for_server(sPAPRXive *xive, uint32_t server, uint8_t
>> prio,
>> + uint32_t *out_eq_idx);
>>
>> #endif /* _INTC_XIVE_INTERNAL_H */
- [Qemu-ppc] [PATCH 11/25] spapr: describe the XIVE interrupt source flags, (continued)
[Qemu-ppc] [PATCH 13/25] spapr: introduce the XIVE Event Queues, Cédric Le Goater, 2017/11/23
Re: [Qemu-ppc] [PATCH 13/25] spapr: introduce the XIVE Event Queues, David Gibson, 2017/11/30
[Qemu-ppc] [PATCH 14/25] spapr: push the XIVE EQ data in OS event queue, Cédric Le Goater, 2017/11/23
[Qemu-ppc] [PATCH 15/25] spapr: notify the CPU when the XIVE interrupt priority is more privileged, Cédric Le Goater, 2017/11/23
[Qemu-ppc] [PATCH 16/25] spapr: add support for the SET_OS_PENDING command (XIVE), Cédric Le Goater, 2017/11/23