Skip to content

Commit

Permalink
target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS
Browse files Browse the repository at this point in the history
The new H-Call H_GET_CPU_CHARACTERISTICS is used by the guest to query
behaviours and available characteristics of the cpu.

Implement the handler for this new H-Call which formulates its response
based on the host capabilities.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

Manually backported from c59704b
upstream because it doesn't apply cleanly.

Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
Signed-off-by: Ricardo M. Matinata <rmm@br.ibm.com>
  • Loading branch information
Ricardo M. Matinata committed Mar 1, 2018
1 parent b1cd3ba commit 452a32c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
68 changes: 68 additions & 0 deletions hw/ppc/spapr_hcall.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
#include "cpu.h"
#include "helper_regs.h"
#include "hw/ppc/spapr.h"
Expand Down Expand Up @@ -1038,6 +1039,70 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
return H_SUCCESS;
}

static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS &
~H_CPU_CHAR_THR_RECONF_TRIG;
uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY;
int safe_cache = kvmppc_get_cap_safe_cache();
int safe_bounds_check = kvmppc_get_cap_safe_bounds_check();
int safe_indirect_branch = kvmppc_get_cap_safe_indirect_branch();

switch (safe_cache) {
case 1:
characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30;
characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2;
characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV;
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
break;
case 2:
break;
default: /* broken */
if (safe_cache != 0) {
error_report("Invalid value for safe cache (%d), assuming broken",
safe_cache);
}
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
break;
}

switch (safe_bounds_check) {
case 1:
characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31;
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
break;
case 2:
break;
default: /* broken */
if (safe_bounds_check != 0) {
error_report("Invalid value for safe bounds check (%d), assuming broken",
safe_bounds_check);
}
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
break;
}

switch (safe_indirect_branch) {
case 2:
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
break;
default: /* broken */
if (safe_indirect_branch != 0) {
error_report("Invalid value for safe indirect branch (%d), assuming broken",
safe_indirect_branch);
}
break;
}

args[0] = characteristics;
args[1] = behaviour;

return H_SUCCESS;
}

static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];

Expand Down Expand Up @@ -1100,6 +1165,9 @@ static void hypercall_register_types(void)
spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
spapr_register_hypercall(H_CEDE, h_cede);

/* hcall-get-cpu-characteristics */
spapr_register_hypercall(H_GET_CPU_CHARACTERISTICS, h_get_cpu_characteristics);

/* processor register resource access h-calls */
spapr_register_hypercall(H_SET_SPRG0, h_set_sprg0);
spapr_register_hypercall(H_SET_DABR, h_set_dabr);
Expand Down
1 change: 1 addition & 0 deletions include/hw/ppc/spapr.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ struct sPAPRMachineState {
#define H_GET_HCA_INFO 0x1B8
#define H_GET_PERF_COUNT 0x1BC
#define H_MANAGE_TRACE 0x1C0
#define H_GET_CPU_CHARACTERISTICS 0x1C8
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
#define H_QUERY_INT_STATE 0x1E4
#define H_POLL_PENDING 0x1D8
Expand Down

0 comments on commit 452a32c

Please sign in to comment.