@@ -511,6 +511,7 @@ static void cap_nested_papr_apply(SpaprMachineState *spapr,
return;
}
spapr->nested.api = NESTED_API_PAPR;
+ spapr_register_nested_phyp();
} else if (kvm_enabled()) {
/*
* this gets executed in L1 qemu when L2 is launched,
@@ -6,6 +6,7 @@
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/spapr_nested.h"
+#include "cpu-models.h"
#ifdef CONFIG_TCG
#define PRTS_MASK 0x1f
@@ -375,6 +376,29 @@ void spapr_exit_nested(PowerPCCPU *cpu, int excp)
address_space_unmap(CPU(cpu)->as, regs, len, len, true);
}
+static target_ulong h_guest_get_capabilities(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ target_ulong opcode,
+ target_ulong *args)
+{
+ CPUPPCState *env = &cpu->env;
+ target_ulong flags = args[0];
+
+ if (flags) { /* don't handle any flags capabilities for now */
+ return H_PARAMETER;
+ }
+
+ if ((env->spr[SPR_PVR] & CPU_POWERPC_POWER_SERVER_MASK) ==
+ (CPU_POWERPC_POWER9_BASE))
+ env->gpr[4] = H_GUEST_CAPABILITIES_P9_MODE;
+
+ if ((env->spr[SPR_PVR] & CPU_POWERPC_POWER_SERVER_MASK) ==
+ (CPU_POWERPC_POWER10_BASE))
+ env->gpr[4] = H_GUEST_CAPABILITIES_P10_MODE;
+
+ return H_SUCCESS;
+}
+
void spapr_register_nested(void)
{
spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
@@ -382,6 +406,12 @@ void spapr_register_nested(void)
spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
}
+
+void spapr_register_nested_phyp(void)
+{
+ spapr_register_hypercall(H_GUEST_GET_CAPABILITIES, h_guest_get_capabilities);
+}
+
#else
void spapr_exit_nested(PowerPCCPU *cpu, int excp)
{
@@ -392,4 +422,9 @@ void spapr_register_nested(void)
{
/* DO NOTHING */
}
+
+void spapr_register_nested_phyp(void)
+{
+ /* DO NOTHING */
+}
#endif
@@ -189,6 +189,11 @@
/* End of list of Guest State Buffer Element IDs */
#define GSB_LAST GSB_VCPU_SPR_ASDR
+/* Bit masks to be used in nested PAPR API */
+#define H_GUEST_CAPABILITIES_COPY_MEM 0x8000000000000000
+#define H_GUEST_CAPABILITIES_P9_MODE 0x4000000000000000
+#define H_GUEST_CAPABILITIES_P10_MODE 0x2000000000000000
+
typedef struct SpaprMachineStateNestedGuest {
unsigned long vcpus;
struct SpaprMachineStateNestedGuestVcpu *vcpu;
@@ -331,6 +336,7 @@ struct nested_ppc_state {
};
void spapr_register_nested(void);
+void spapr_register_nested_phyp(void);
void spapr_exit_nested(PowerPCCPU *cpu, int excp);
#endif /* HW_SPAPR_NESTED_H */