ppc: Check the availability of transactional memory

KVM-PR currently does not support transactional memory, and the
implementation in TCG is just a fake. We should not announce TM
support in the ibm,pa-features property when running on such a
system, so disable it by default and only enable it if the KVM
implementation supports it (i.e. recent versions of KVM-HV).
These changes are based on some earlier work from Anton Blanchard
(thanks!).

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit bac3bf287a)
This commit is contained in:
Thomas Huth 2016-09-28 13:16:30 +02:00 committed by David Gibson
parent 45a4f18e2e
commit 2e68f28854
3 changed files with 17 additions and 1 deletions

View File

@ -603,7 +603,7 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, 0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }; 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
uint8_t *pa_features; uint8_t *pa_features;
size_t pa_size; size_t pa_size;
@ -632,6 +632,9 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
*/ */
pa_features[3] |= 0x20; pa_features[3] |= 0x20;
} }
if (kvmppc_has_cap_htm() && pa_size > 24) {
pa_features[24] |= 0x80; /* Transactional memory support */
}
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size))); _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
} }

View File

@ -79,6 +79,7 @@ static int cap_ppc_watchdog;
static int cap_papr; static int cap_papr;
static int cap_htab_fd; static int cap_htab_fd;
static int cap_fixup_hcalls; static int cap_fixup_hcalls;
static int cap_htm; /* Hardware transactional memory support */
static uint32_t debug_inst_opcode; static uint32_t debug_inst_opcode;
@ -121,6 +122,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
* only activated after this by kvmppc_set_papr() */ * only activated after this by kvmppc_set_papr() */
cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD); cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL); cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
if (!cap_interrupt_level) { if (!cap_interrupt_level) {
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@ -2339,6 +2341,11 @@ bool kvmppc_has_cap_fixup_hcalls(void)
return cap_fixup_hcalls; return cap_fixup_hcalls;
} }
bool kvmppc_has_cap_htm(void)
{
return cap_htm;
}
static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc) static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
{ {
ObjectClass *oc = OBJECT_CLASS(pcc); ObjectClass *oc = OBJECT_CLASS(pcc);

View File

@ -54,6 +54,7 @@ void kvmppc_hash64_free_pteg(uint64_t token);
void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
target_ulong pte0, target_ulong pte1); target_ulong pte0, target_ulong pte1);
bool kvmppc_has_cap_fixup_hcalls(void); bool kvmppc_has_cap_fixup_hcalls(void);
bool kvmppc_has_cap_htm(void);
int kvmppc_enable_hwrng(void); int kvmppc_enable_hwrng(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu); int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@ -244,6 +245,11 @@ static inline bool kvmppc_has_cap_fixup_hcalls(void)
abort(); abort();
} }
static inline bool kvmppc_has_cap_htm(void)
{
return false;
}
static inline int kvmppc_enable_hwrng(void) static inline int kvmppc_enable_hwrng(void)
{ {
return -1; return -1;