Merge ~paelzer/ubuntu/+source/qemu:fix-1832622-ppc-spectre-cosmic into ubuntu/+source/qemu:ubuntu/cosmic-devel

Proposed by Christian Ehrhardt  on 2019-06-13
Status: Merged
Approved by: Christian Ehrhardt  on 2019-06-26
Approved revision: 561b5e275c415c66b614d01f18e60e66721fa64c
Merge reported by: Christian Ehrhardt 
Merged at revision: 561b5e275c415c66b614d01f18e60e66721fa64c
Proposed branch: ~paelzer/ubuntu/+source/qemu:fix-1832622-ppc-spectre-cosmic
Merge into: ubuntu/+source/qemu:ubuntu/cosmic-devel
Diff against target: 528 lines (+494/-0)
5 files modified
debian/changelog (+7/-0)
debian/patches/series (+3/-0)
debian/patches/ubuntu/lp-1832622-0001-target-ppc-Factor-out-the-parsing-in-kvmppc_get_cpu_.patch (+101/-0)
debian/patches/ubuntu/lp-1832622-0002-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch (+159/-0)
debian/patches/ubuntu/lp-1832622-0004-target-ppc-spapr-Add-SPAPR_CAP_CCF_ASSIST.patch (+224/-0)
Reviewer Review Type Date Requested Status
Rafael David Tinoco 2019-06-13 Approve on 2019-06-26
Canonical Server Team 2019-06-13 Pending
Ubuntu Server Dev import team 2019-06-13 Pending
Review via email: mp+368750@code.launchpad.net
To post a comment you must log in.
Christian Ehrhardt  (paelzer) wrote :

Related test PPA at [1].
This started with the provided backports for 2.11 and then one by one taking away changes no more needed on the backports. The commits that "undo some backports" are intentionally not squashed so one can see what changes in between the versions and what is the same.

[1]: https://launchpad.net/~paelzer/+archive/ubuntu/bug-1832622-qemu-spectre-ppc

Paride Legovini (legovini) wrote :

Looks good from a formal point view; the packages in the PPA seem to be working as expected, however I don't think I can test the specific fix.

Rafael David Tinoco (rafaeldtinoco) wrote :

I did a full bionic review into eoan merge request:

https://code.launchpad.net/~paelzer/ubuntu/+source/qemu/+git/qemu/+merge/368748/comments/964720

All others are a subset of that, I did a quick look and compilation tests only.

+1 from me.

review: Approve
Christian Ehrhardt  (paelzer) wrote :

This migrated, closing forgotten MP

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index bb56b49..0f5786c 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+qemu (1:2.12+dfsg-3ubuntu8.10) cosmic; urgency=medium
7+
8+ * d/p/ubuntu/lp-1832622-*: count cache flush Spectre v2 mitigation for ppc64
9+ (LP: #1832622)
10+
11+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 13 Jun 2019 08:20:29 +0200
12+
13 qemu (1:2.12+dfsg-3ubuntu8.9) cosmic; urgency=medium
14
15 * d/p/ubuntu/define-ubuntu-machine-types.patch: fix wily machine type being
16diff --git a/debian/patches/series b/debian/patches/series
17index 7100e00..57f2a9e 100644
18--- a/debian/patches/series
19+++ b/debian/patches/series
20@@ -63,3 +63,6 @@ CVE-2018-20815.patch
21 CVE-2019-5008.patch
22 CVE-2019-9824.patch
23 ubuntu/lp-1830704-s390x-cpumodel-ignore-csske-for-expansion.patch
24+ubuntu/lp-1832622-0001-target-ppc-Factor-out-the-parsing-in-kvmppc_get_cpu_.patch
25+ubuntu/lp-1832622-0002-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch
26+ubuntu/lp-1832622-0004-target-ppc-spapr-Add-SPAPR_CAP_CCF_ASSIST.patch
27diff --git a/debian/patches/ubuntu/lp-1832622-0001-target-ppc-Factor-out-the-parsing-in-kvmppc_get_cpu_.patch b/debian/patches/ubuntu/lp-1832622-0001-target-ppc-Factor-out-the-parsing-in-kvmppc_get_cpu_.patch
28new file mode 100644
29index 0000000..44412f5
30--- /dev/null
31+++ b/debian/patches/ubuntu/lp-1832622-0001-target-ppc-Factor-out-the-parsing-in-kvmppc_get_cpu_.patch
32@@ -0,0 +1,101 @@
33+From 8fea70440eb0d095442de7e80d586a285cf96be5 Mon Sep 17 00:00:00 2001
34+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
35+Date: Fri, 11 May 2018 16:25:07 +1000
36+Subject: [PATCH] target/ppc: Factor out the parsing in
37+ kvmppc_get_cpu_characteristics()
38+
39+Factor out the parsing of struct kvm_ppc_cpu_char in
40+kvmppc_get_cpu_characteristics() into a separate function for each cap
41+for simplicity.
42+
43+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
44+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
45+
46+Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=8fea70440eb0d095442de7e80d586a285cf96be5
47+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1832622
48+Last-Update: 2019-06-13
49+
50+---
51+ target/ppc/kvm.c | 59 ++++++++++++++++++++++++++++++++----------------
52+ 1 file changed, 39 insertions(+), 20 deletions(-)
53+
54+diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
55+index cbe13b18d1..2c0c34e125 100644
56+--- a/target/ppc/kvm.c
57++++ b/target/ppc/kvm.c
58+@@ -2412,6 +2412,41 @@ bool kvmppc_has_cap_mmu_hash_v3(void)
59+ return cap_mmu_hash_v3;
60+ }
61+
62++static int parse_cap_ppc_safe_cache(struct kvm_ppc_cpu_char c)
63++{
64++ if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
65++ return 2;
66++ } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
67++ (c.character & c.character_mask
68++ & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
69++ return 1;
70++ }
71++
72++ return 0;
73++}
74++
75++static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
76++{
77++ if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
78++ return 2;
79++ } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
80++ return 1;
81++ }
82++
83++ return 0;
84++}
85++
86++static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
87++{
88++ if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
89++ return SPAPR_CAP_FIXED_CCD;
90++ } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
91++ return SPAPR_CAP_FIXED_IBS;
92++ }
93++
94++ return 0;
95++}
96++
97+ static void kvmppc_get_cpu_characteristics(KVMState *s)
98+ {
99+ struct kvm_ppc_cpu_char c;
100+@@ -2430,26 +2465,10 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
101+ if (ret < 0) {
102+ return;
103+ }
104+- /* Parse and set cap_ppc_safe_cache */
105+- if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
106+- cap_ppc_safe_cache = 2;
107+- } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
108+- (c.character & c.character_mask
109+- & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
110+- cap_ppc_safe_cache = 1;
111+- }
112+- /* Parse and set cap_ppc_safe_bounds_check */
113+- if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
114+- cap_ppc_safe_bounds_check = 2;
115+- } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
116+- cap_ppc_safe_bounds_check = 1;
117+- }
118+- /* Parse and set cap_ppc_safe_indirect_branch */
119+- if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
120+- cap_ppc_safe_indirect_branch = SPAPR_CAP_FIXED_CCD;
121+- } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
122+- cap_ppc_safe_indirect_branch = SPAPR_CAP_FIXED_IBS;
123+- }
124++
125++ cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
126++ cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
127++ cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
128+ }
129+
130+ int kvmppc_get_cap_safe_cache(void)
131+--
132+2.21.0
133+
134diff --git a/debian/patches/ubuntu/lp-1832622-0002-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch b/debian/patches/ubuntu/lp-1832622-0002-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch
135new file mode 100644
136index 0000000..58b3e88
137--- /dev/null
138+++ b/debian/patches/ubuntu/lp-1832622-0002-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch
139@@ -0,0 +1,159 @@
140+From 399b2896d4948a1ec0278d896ea3a561df768d64 Mon Sep 17 00:00:00 2001
141+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
142+Date: Fri, 1 Mar 2019 14:19:11 +1100
143+Subject: [PATCH 1/2] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS
144+
145+The spapr_cap SPAPR_CAP_IBS is used to indicate the level of capability
146+for mitigations for indirect branch speculation. Currently the available
147+values are broken (default), fixed-ibs (fixed by serialising indirect
148+branches) and fixed-ccd (fixed by diabling the count cache).
149+
150+Introduce a new value for this capability denoted workaround, meaning that
151+software can work around the issue by flushing the count cache on
152+context switch. This option is available if the hypervisor sets the
153+H_CPU_BEHAV_FLUSH_COUNT_CACHE flag in the cpu behaviours returned from
154+the KVM_PPC_GET_CPU_CHAR ioctl.
155+
156+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
157+Message-Id: <20190301031912.28809-1-sjitindarsingh@gmail.com>
158+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
159+
160+Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=399b2896d4948a1ec0278d896ea3a561df768d64
161+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1832622
162+Last-Update: 2019-06-13
163+
164+---
165+ hw/ppc/spapr_caps.c | 21 ++++++++++-----------
166+ hw/ppc/spapr_hcall.c | 5 +++++
167+ include/hw/ppc/spapr.h | 7 +++++++
168+ target/ppc/kvm.c | 8 +++++++-
169+ 4 files changed, 29 insertions(+), 12 deletions(-)
170+
171+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
172+index faab472d06..ca35b5153d 100644
173+--- a/hw/ppc/spapr_caps.c
174++++ b/hw/ppc/spapr_caps.c
175+@@ -276,11 +276,13 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
176+ }
177+
178+ sPAPRCapPossible cap_ibs_possible = {
179+- .num = 4,
180++ .num = 5,
181+ /* Note workaround only maintained for compatibility */
182+- .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd"},
183+- .help = "broken - no protection, fixed-ibs - indirect branch serialisation,"
184+- " fixed-ccd - cache count disabled",
185++ .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
186++ .help = "broken - no protection, workaround - count cache flush"
187++ ", fixed-ibs - indirect branch serialisation,"
188++ " fixed-ccd - cache count disabled,"
189++ " fixed-na - fixed in hardware (no longer applicable)",
190+ };
191+
192+ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
193+@@ -288,15 +290,11 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
194+ {
195+ uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
196+
197+- if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */
198+- error_setg(errp,
199+-"Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=%s",
200+- cap_ibs_possible.vals[kvm_val]);
201+- } else if (tcg_enabled() && val) {
202++ if (tcg_enabled() && val) {
203+ /* TODO - for now only allow broken for TCG */
204+ error_setg(errp,
205+ "Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
206+- } else if (kvm_enabled() && val && (val != kvm_val)) {
207++ } else if (kvm_enabled() && (val > kvm_val)) {
208+ error_setg(errp,
209+ "Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
210+ cap_ibs_possible.vals[kvm_val]);
211+@@ -494,7 +492,8 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
212+ [SPAPR_CAP_IBS] = {
213+ .name = "ibs",
214+ .description =
215+- "Indirect Branch Speculation (broken, fixed-ibs, fixed-ccd)",
216++ "Indirect Branch Speculation (broken, workaround, fixed-ibs,"
217++ "fixed-ccd, fixed-na)",
218+ .index = SPAPR_CAP_IBS,
219+ .get = spapr_cap_get_string,
220+ .set = spapr_cap_set_string,
221+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
222+index 476bad6271..4aa8036fc0 100644
223+--- a/hw/ppc/spapr_hcall.c
224++++ b/hw/ppc/spapr_hcall.c
225+@@ -1723,12 +1723,17 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
226+ }
227+
228+ switch (safe_indirect_branch) {
229++ case SPAPR_CAP_FIXED_NA:
230++ break;
231+ case SPAPR_CAP_FIXED_CCD:
232+ characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
233+ break;
234+ case SPAPR_CAP_FIXED_IBS:
235+ characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
236+ break;
237++ case SPAPR_CAP_WORKAROUND:
238++ behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
239++ break;
240+ default: /* broken */
241+ assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
242+ break;
243+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
244+index 8efc5e0779..a7f3b1bfdd 100644
245+--- a/include/hw/ppc/spapr.h
246++++ b/include/hw/ppc/spapr.h
247+@@ -85,12 +85,17 @@ typedef enum {
248+ /* Bool Caps */
249+ #define SPAPR_CAP_OFF 0x00
250+ #define SPAPR_CAP_ON 0x01
251++
252+ /* Custom Caps */
253++
254++/* Generic */
255+ #define SPAPR_CAP_BROKEN 0x00
256+ #define SPAPR_CAP_WORKAROUND 0x01
257+ #define SPAPR_CAP_FIXED 0x02
258++/* SPAPR_CAP_IBS (cap-ibs) */
259+ #define SPAPR_CAP_FIXED_IBS 0x02
260+ #define SPAPR_CAP_FIXED_CCD 0x03
261++#define SPAPR_CAP_FIXED_NA 0x10 /* Lets leave a bit of a gap... */
262+
263+ typedef struct sPAPRCapabilities sPAPRCapabilities;
264+ struct sPAPRCapabilities {
265+@@ -339,9 +344,11 @@ struct sPAPRMachineState {
266+ #define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
267+ #define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
268+ #define H_CPU_CHAR_CACHE_COUNT_DIS PPC_BIT(7)
269++#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST PPC_BIT(9)
270+ #define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
271+ #define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
272+ #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
273++#define H_CPU_BEHAV_FLUSH_COUNT_CACHE PPC_BIT(5)
274+
275+ /* Each control block has to be on a 4K boundary */
276+ #define H_CB_ALIGNMENT 4096
277+diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
278+index f0f5bf9391..4d46314276 100644
279+--- a/target/ppc/kvm.c
280++++ b/target/ppc/kvm.c
281+@@ -2392,7 +2392,13 @@ static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
282+
283+ static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
284+ {
285+- if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
286++ if ((~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) &&
287++ (~c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) &&
288++ (~c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED)) {
289++ return SPAPR_CAP_FIXED_NA;
290++ } else if (c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) {
291++ return SPAPR_CAP_WORKAROUND;
292++ } else if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
293+ return SPAPR_CAP_FIXED_CCD;
294+ } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
295+ return SPAPR_CAP_FIXED_IBS;
296+--
297+2.21.0
298+
299diff --git a/debian/patches/ubuntu/lp-1832622-0004-target-ppc-spapr-Add-SPAPR_CAP_CCF_ASSIST.patch b/debian/patches/ubuntu/lp-1832622-0004-target-ppc-spapr-Add-SPAPR_CAP_CCF_ASSIST.patch
300new file mode 100644
301index 0000000..e76d1fd
302--- /dev/null
303+++ b/debian/patches/ubuntu/lp-1832622-0004-target-ppc-spapr-Add-SPAPR_CAP_CCF_ASSIST.patch
304@@ -0,0 +1,224 @@
305+From 77012c6029ae15328f04ddcb713f459cdacffef9 Mon Sep 17 00:00:00 2001
306+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
307+Date: Fri, 1 Mar 2019 14:19:12 +1100
308+Subject: [PATCH] target/ppc/spapr: Add SPAPR_CAP_CCF_ASSIST
309+
310+Introduce a new spapr_cap SPAPR_CAP_CCF_ASSIST to be used to indicate
311+the requirement for a hw-assisted version of the count cache flush
312+workaround.
313+
314+The count cache flush workaround is a software workaround which can be
315+used to flush the count cache on context switch. Some revisions of
316+hardware may have a hardware accelerated flush, in which case the
317+software flush can be shortened. This cap is used to set the
318+availability of such hardware acceleration for the count cache flush
319+routine.
320+
321+The availability of such hardware acceleration is indicated by the
322+H_CPU_CHAR_BCCTR_FLUSH_ASSIST flag being set in the characteristics
323+returned from the KVM_PPC_GET_CPU_CHAR ioctl.
324+
325+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
326+Message-Id: <20190301031912.28809-2-sjitindarsingh@gmail.com>
327+[dwg: Small style fixes]
328+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
329+(cherry picked from commit 8ff43ee404d3e295839d1fd4e9e6571ca7a62a66)
330+* remove context dependencies on post-2.11 capabilities and migration
331+ state
332+* adjust SPAPR_CAP_CCF_ASSIST to be next avail index (SPAPR_CAP_IBS + 1)
333+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
334+(cherry picked from commit 2cdaf75db8ac825cb4b8b6a00b7bb114941cc51d)
335+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
336+
337+Author: Michael Roth <mdroth@linux.vnet.ibm.com>
338+Origin: upstream, https://git.qemu.org/?p=qemu.git;a=commit;h=8ff43ee404d3e295839d1fd4e9e6571ca7a62a66
339+Origin: backport, https://github.com/mdroth/qemu/commit/77012c6029ae15328f04ddcb713f459cdacffef9
340+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1832622
341+Last-Update: 2019-06-13
342+
343+---
344+ hw/ppc/spapr.c | 2 ++
345+ hw/ppc/spapr_caps.c | 25 +++++++++++++++++++++++++
346+ hw/ppc/spapr_hcall.c | 5 +++++
347+ include/hw/ppc/spapr.h | 5 ++++-
348+ target/ppc/kvm.c | 16 ++++++++++++++++
349+ target/ppc/kvm_ppc.h | 6 ++++++
350+ 6 files changed, 58 insertions(+), 1 deletion(-)
351+
352+--- a/hw/ppc/spapr.c
353++++ b/hw/ppc/spapr.c
354+@@ -1805,6 +1805,7 @@ static const VMStateDescription vmstate_
355+ &vmstate_spapr_cap_cfpc,
356+ &vmstate_spapr_cap_sbbc,
357+ &vmstate_spapr_cap_ibs,
358++ &vmstate_spapr_cap_ccf_assist,
359+ NULL
360+ }
361+ };
362+@@ -3938,6 +3939,7 @@ static void spapr_machine_class_init(Obj
363+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
364+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
365+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
366++ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
367+ spapr_caps_add_properties(smc, &error_abort);
368+ }
369+
370+--- a/hw/ppc/spapr_caps.c
371++++ b/hw/ppc/spapr_caps.c
372+@@ -263,6 +263,21 @@ static void cap_safe_indirect_branch_app
373+
374+ #define VALUE_DESC_TRISTATE " (broken, workaround, fixed)"
375+
376++static void cap_ccf_assist_apply(sPAPRMachineState *spapr, uint8_t val,
377++ Error **errp)
378++{
379++ uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
380++
381++ if (tcg_enabled() && val) {
382++ /* TODO - for now only allow broken for TCG */
383++ error_setg(errp,
384++"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off");
385++ } else if (kvm_enabled() && (val > kvm_val)) {
386++ error_setg(errp,
387++"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off");
388++ }
389++}
390++
391+ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
392+ [SPAPR_CAP_HTM] = {
393+ .name = "htm",
394+@@ -323,6 +338,15 @@ sPAPRCapabilityInfo capability_table[SPA
395+ .possible = &cap_ibs_possible,
396+ .apply = cap_safe_indirect_branch_apply,
397+ },
398++ [SPAPR_CAP_CCF_ASSIST] = {
399++ .name = "ccf-assist",
400++ .description = "Count Cache Flush Assist via HW Instruction",
401++ .index = SPAPR_CAP_CCF_ASSIST,
402++ .get = spapr_cap_get_bool,
403++ .set = spapr_cap_set_bool,
404++ .type = "bool",
405++ .apply = cap_ccf_assist_apply,
406++ },
407+ };
408+
409+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
410+@@ -442,6 +466,7 @@ SPAPR_CAP_MIG_STATE(dfp, SPAPR_CAP_DFP);
411+ SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
412+ SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
413+ SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
414++SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
415+
416+ void spapr_caps_reset(sPAPRMachineState *spapr)
417+ {
418+--- a/hw/ppc/spapr_hcall.c
419++++ b/hw/ppc/spapr_hcall.c
420+@@ -1675,6 +1675,8 @@ static target_ulong h_get_cpu_characteri
421+ uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
422+ uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
423+ uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
424++ uint8_t count_cache_flush_assist = spapr_get_cap(spapr,
425++ SPAPR_CAP_CCF_ASSIST);
426+
427+ switch (safe_cache) {
428+ case SPAPR_CAP_WORKAROUND:
429+@@ -1715,6 +1717,9 @@ static target_ulong h_get_cpu_characteri
430+ break;
431+ case SPAPR_CAP_WORKAROUND:
432+ behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
433++ if (count_cache_flush_assist) {
434++ characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST;
435++ }
436+ break;
437+ default: /* broken */
438+ assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
439+--- a/include/hw/ppc/spapr.h
440++++ b/include/hw/ppc/spapr.h
441+@@ -66,8 +66,10 @@ typedef enum {
442+ #define SPAPR_CAP_SBBC 0x04
443+ /* Indirect Branch Serialisation */
444+ #define SPAPR_CAP_IBS 0x05
445++/* Count Cache Flush Assist HW Instruction */
446++#define SPAPR_CAP_CCF_ASSIST 0x06
447+ /* Num Caps */
448+-#define SPAPR_CAP_NUM (SPAPR_CAP_IBS + 1)
449++#define SPAPR_CAP_NUM (SPAPR_CAP_CCF_ASSIST + 1)
450+
451+ /*
452+ * Capability Values
453+@@ -800,6 +802,7 @@ extern const VMStateDescription vmstate_
454+ extern const VMStateDescription vmstate_spapr_cap_cfpc;
455+ extern const VMStateDescription vmstate_spapr_cap_sbbc;
456+ extern const VMStateDescription vmstate_spapr_cap_ibs;
457++extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
458+
459+ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
460+ {
461+--- a/target/ppc/kvm.c
462++++ b/target/ppc/kvm.c
463+@@ -92,6 +92,7 @@ static int cap_ppc_pvr_compat;
464+ static int cap_ppc_safe_cache;
465+ static int cap_ppc_safe_bounds_check;
466+ static int cap_ppc_safe_indirect_branch;
467++static int cap_ppc_count_cache_flush_assist;
468+
469+ static uint32_t debug_inst_opcode;
470+
471+@@ -2502,6 +2503,14 @@ static int parse_cap_ppc_safe_indirect_b
472+ return 0;
473+ }
474+
475++static int parse_cap_ppc_count_cache_flush_assist(struct kvm_ppc_cpu_char c)
476++{
477++ if (c.character & c.character_mask & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) {
478++ return 1;
479++ }
480++ return 0;
481++}
482++
483+ static void kvmppc_get_cpu_characteristics(KVMState *s)
484+ {
485+ struct kvm_ppc_cpu_char c;
486+@@ -2524,6 +2533,8 @@ static void kvmppc_get_cpu_characteristi
487+ cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
488+ cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
489+ cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
490++ cap_ppc_count_cache_flush_assist =
491++ parse_cap_ppc_count_cache_flush_assist(c);
492+ }
493+
494+ int kvmppc_get_cap_safe_cache(void)
495+@@ -2546,6 +2557,11 @@ bool kvmppc_has_cap_spapr_vfio(void)
496+ return cap_spapr_vfio;
497+ }
498+
499++int kvmppc_get_cap_count_cache_flush_assist(void)
500++{
501++ return cap_ppc_count_cache_flush_assist;
502++}
503++
504+ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
505+ {
506+ uint32_t host_pvr = mfpvr();
507+--- a/target/ppc/kvm_ppc.h
508++++ b/target/ppc/kvm_ppc.h
509+@@ -63,6 +63,7 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
510+ int kvmppc_get_cap_safe_cache(void);
511+ int kvmppc_get_cap_safe_bounds_check(void);
512+ int kvmppc_get_cap_safe_indirect_branch(void);
513++int kvmppc_get_cap_count_cache_flush_assist(void);
514+ int kvmppc_enable_hwrng(void);
515+ int kvmppc_put_books_sregs(PowerPCCPU *cpu);
516+ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
517+@@ -313,6 +314,11 @@ static inline int kvmppc_get_cap_safe_in
518+ {
519+ return 0;
520+ }
521++
522++static inline int kvmppc_get_cap_count_cache_flush_assist(void)
523++{
524++ return 0;
525++}
526+
527+ static inline int kvmppc_enable_hwrng(void)
528+ {

Subscribers

People subscribed via source and target branches