Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS #1

Merged
merged 1 commit into from
Mar 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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