Commit 25c79a30 authored by Greg Kurz's avatar Greg Kurz Committed by David Gibson
Browse files

xics/spapr: Only emulated XICS should use RTAS/hypercalls emulation



Checking that we're not using the in-kernel XICS is ok with the "xics"
interrupt controller mode, but it is definitely not enough with the
other modes since the guest could be using XIVE.

Ensure XIVE is not in use when emulated XICS RTAS/hypercalls are
called.

Signed-off-by: default avatarGreg Kurz <groug@kaod.org>
Message-Id: <156077253666.424706.6104557911104491047.stgit@bahia.lan>
Reviewed-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 7e10b57d
Loading
Loading
Loading
Loading
+27 −26
Original line number Diff line number Diff line
@@ -41,20 +41,21 @@
 * Guest interfaces
 */

static bool check_in_kernel_xics(const char *func)
static bool check_emulated_xics(SpaprMachineState *spapr, const char *func)
{
    if (kvm_irqchip_in_kernel()) {
        error_report("pseries: %s must never be called for in-kernel XICS",
    if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ||
        kvm_irqchip_in_kernel()) {
        error_report("pseries: %s must only be called for emulated XICS",
                     func);
        return true;
        return false;
    }

    return false;
    return true;
}

#define CHECK_IN_KERNEL_XICS_HCALL              \
#define CHECK_EMULATED_XICS_HCALL(spapr)               \
    do {                                               \
        if (check_in_kernel_xics(__func__)) {   \
        if (!check_emulated_xics((spapr), __func__)) { \
            return H_HARDWARE;                         \
        }                                              \
    } while (0)
@@ -64,7 +65,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
    target_ulong cppr = args[0];

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
    return H_SUCCESS;
@@ -76,7 +77,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
    target_ulong mfrr = args[1];
    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    if (!icp) {
        return H_PARAMETER;
@@ -91,7 +92,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
    uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    args[0] = xirr;
    return H_SUCCESS;
@@ -102,7 +103,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
    uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    args[0] = xirr;
    args[1] = cpu_get_host_ticks();
@@ -114,7 +115,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
    target_ulong xirr = args[0];

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
    return H_SUCCESS;
@@ -127,7 +128,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
    uint32_t mfrr;
    uint32_t xirr;

    CHECK_IN_KERNEL_XICS_HCALL;
    CHECK_EMULATED_XICS_HCALL(spapr);

    if (!icp) {
        return H_PARAMETER;
@@ -141,9 +142,9 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
    return H_SUCCESS;
}

#define CHECK_IN_KERNEL_XICS_RTAS(rets)                 \
#define CHECK_EMULATED_XICS_RTAS(spapr, rets)          \
    do {                                               \
        if (check_in_kernel_xics(__func__)) {           \
        if (!check_emulated_xics((spapr), __func__)) { \
            rtas_st((rets), 0, RTAS_OUT_HW_ERROR);     \
            return;                                    \
        }                                              \
@@ -157,7 +158,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno, server, priority;

    CHECK_IN_KERNEL_XICS_RTAS(rets);
    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 3) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -192,7 +193,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_IN_KERNEL_XICS_RTAS(rets);
    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 3)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -224,7 +225,7 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_IN_KERNEL_XICS_RTAS(rets);
    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -257,7 +258,7 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
    ICSState *ics = spapr->ics;
    uint32_t nr, srcno;

    CHECK_IN_KERNEL_XICS_RTAS(rets);
    CHECK_EMULATED_XICS_RTAS(spapr, rets);

    if ((nargs != 1) || (nret != 1)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);