Skip to content

Commit 9e7dc71

Browse files
sjitindarsinghRicardo M. Matinata
authored andcommitted
target-ppc: Handle additional bits in H_GET_CPU_CHARACTERISTICS
The hcall H_GET_CPU_CHARACTERISTICS is used by the guest to determine information about the required behaviours and available characteristics of the cpu. Bits may be added to this hcall, the information for which is queried from the hypervisor using the KVM_PPC_GET_CPU_CHAR ioctl. In order to handle the case where additional bits may be added to this hcall, and thus to the ioctl, relax the parsing in qemu so that there is minimal modification of the data before it is passed to the guest. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: Ricardo M. Matinata <rmm@br.ibm.com>
1 parent 8188e66 commit 9e7dc71

File tree

3 files changed

+28
-96
lines changed

3 files changed

+28
-96
lines changed

hw/ppc/spapr_hcall.c

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,57 +1044,21 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
10441044
target_ulong opcode,
10451045
target_ulong *args)
10461046
{
1047-
uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS &
1048-
~H_CPU_CHAR_THR_RECONF_TRIG;
1049-
uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY;
1050-
int safe_cache = kvmppc_get_cap_safe_cache();
1051-
int safe_bounds_check = kvmppc_get_cap_safe_bounds_check();
1052-
int safe_indirect_branch = kvmppc_get_cap_safe_indirect_branch();
1053-
1054-
switch (safe_cache) {
1055-
case 1:
1056-
characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30;
1057-
characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2;
1058-
characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV;
1059-
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
1060-
break;
1061-
case 2:
1062-
break;
1063-
default: /* broken */
1064-
if (safe_cache != 0) {
1065-
error_report("Invalid value for safe cache (%d), assuming broken",
1066-
safe_cache);
1047+
uint64_t characteristics = kvmppc_get_cap_ppc_cpu_char_character();
1048+
uint64_t behaviour = kvmppc_get_cap_ppc_cpu_char_behaviour();
1049+
1050+
characteristics |= H_CPU_CHAR_HON_BRANCH_HINTS;
1051+
1052+
if (behaviour & H_CPU_BEHAV_L1D_FLUSH_PR) {
1053+
/*
1054+
* To enable P8->P9 & P9->P8 migration, if either of the cache flush
1055+
* instructions are available, then tell the guest to use both.
1056+
*/
1057+
if (characteristics & (H_CPU_CHAR_L1D_FLUSH_ORI30 |
1058+
H_CPU_CHAR_L1D_FLUSH_TRIG2)) {
1059+
characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30 |
1060+
H_CPU_CHAR_L1D_FLUSH_TRIG2;
10671061
}
1068-
behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
1069-
break;
1070-
}
1071-
1072-
switch (safe_bounds_check) {
1073-
case 1:
1074-
characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31;
1075-
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1076-
break;
1077-
case 2:
1078-
break;
1079-
default: /* broken */
1080-
if (safe_bounds_check != 0) {
1081-
error_report("Invalid value for safe bounds check (%d), assuming broken",
1082-
safe_bounds_check);
1083-
}
1084-
behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
1085-
break;
1086-
}
1087-
1088-
switch (safe_indirect_branch) {
1089-
case 2:
1090-
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
1091-
break;
1092-
default: /* broken */
1093-
if (safe_indirect_branch != 0) {
1094-
error_report("Invalid value for safe indirect branch (%d), assuming broken",
1095-
safe_indirect_branch);
1096-
}
1097-
break;
10981062
}
10991063

11001064
args[0] = characteristics;

target-ppc/kvm.c

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,8 @@ static int cap_ppc_watchdog;
8080
static int cap_papr;
8181
static int cap_htab_fd;
8282
static int cap_fixup_hcalls;
83-
static int cap_ppc_safe_cache;
84-
static int cap_ppc_safe_bounds_check;
85-
static int cap_ppc_safe_indirect_branch;
83+
static uint64_t cap_ppc_cpu_char_character;
84+
static uint64_t cap_ppc_cpu_char_behaviour;
8685

8786
static uint32_t debug_inst_opcode;
8887

@@ -2350,11 +2349,6 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
23502349
struct kvm_ppc_cpu_char c;
23512350
int ret;
23522351

2353-
/* Assume broken */
2354-
cap_ppc_safe_cache = 0;
2355-
cap_ppc_safe_bounds_check = 0;
2356-
cap_ppc_safe_indirect_branch = 0;
2357-
23582352
ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR);
23592353
if (!ret) {
23602354
return;
@@ -2363,39 +2357,19 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
23632357
if (ret < 0) {
23642358
return;
23652359
}
2366-
/* Parse and set cap_ppc_safe_cache */
2367-
if (~c.behaviour & c.b_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
2368-
cap_ppc_safe_cache = 2;
2369-
} else if ((c.character & c.c_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
2370-
(c.character & c.c_mask & (H_CPU_CHAR_L1D_FLUSH_ORI30 |
2371-
H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
2372-
cap_ppc_safe_cache = 1;
2373-
}
2374-
/* Parse and set cap_ppc_safe_bounds_check */
2375-
if (~c.behaviour & c.b_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
2376-
cap_ppc_safe_bounds_check = 2;
2377-
} else if (c.character & c.c_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
2378-
cap_ppc_safe_bounds_check = 1;
2379-
}
2380-
/* Parse and set cap_ppc_safe_indirect_branch */
2381-
if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) {
2382-
cap_ppc_safe_indirect_branch = 2;
2383-
}
2384-
}
23852360

2386-
int kvmppc_get_cap_safe_cache(void)
2387-
{
2388-
return cap_ppc_safe_cache;
2361+
cap_ppc_cpu_char_character = c.character & c.c_mask;
2362+
cap_ppc_cpu_char_behaviour = c.behaviour & c.b_mask;
23892363
}
23902364

2391-
int kvmppc_get_cap_safe_bounds_check(void)
2365+
uint64_t kvmppc_get_cap_ppc_cpu_char_character(void)
23922366
{
2393-
return cap_ppc_safe_bounds_check;
2367+
return cap_ppc_cpu_char_character;
23942368
}
23952369

2396-
int kvmppc_get_cap_safe_indirect_branch(void)
2370+
uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void)
23972371
{
2398-
return cap_ppc_safe_indirect_branch;
2372+
return cap_ppc_cpu_char_behaviour;
23992373
}
24002374

24012375
static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)

target-ppc/kvm_ppc.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ void kvmppc_hash64_free_pteg(uint64_t token);
5454
void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
5555
target_ulong pte0, target_ulong pte1);
5656
bool kvmppc_has_cap_fixup_hcalls(void);
57-
int kvmppc_get_cap_safe_cache(void);
58-
int kvmppc_get_cap_safe_bounds_check(void);
59-
int kvmppc_get_cap_safe_indirect_branch(void);
57+
uint64_t kvmppc_get_cap_ppc_cpu_char_character(void);
58+
uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void);
6059
int kvmppc_enable_hwrng(void);
6160
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
6261
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@@ -247,19 +246,14 @@ static inline bool kvmppc_has_cap_fixup_hcalls(void)
247246
abort();
248247
}
249248

250-
static inline int kvmppc_get_cap_safe_cache(void)
249+
static inline uint64_t kvmppc_get_cap_ppc_cpu_char_character(void)
251250
{
252-
return 0;
253-
}
254-
255-
static inline int kvmppc_get_cap_safe_bounds_check(void)
256-
{
257-
return 0;
251+
return 0ULL;
258252
}
259253

260-
static inline int kvmppc_get_cap_safe_indirect_branch(void)
254+
static inline uint64_t kvmppc_get_cap_ppc_cpu_char_behaviour(void)
261255
{
262-
return 0;
256+
return 0ULL;
263257
}
264258

265259
static inline int kvmppc_enable_hwrng(void)

0 commit comments

Comments
 (0)