Skip to content

Commit ebf95e8

Browse files
hfreudehcahca
authored andcommitted
s390/ap,zcrypt,vfio: introduce and use ap_queue_status_reg union
Introduce a new ap queue status register wrapper union to access register wide values. So the inline assembler only sees register wide values but the surrounding code may use a more structured view of the same value and a reader of the code (and the compiler) gets a clear understanding about the mapping between fields and register values. All the changes to access the ap queue status are local to the inline functions within ap.h. However, the struct ap_qirq_ctrl has been replaces by a union for same reason and this needed slight adaptions in the calling code. Suggested-by: Halil Pasic <[email protected]> Suggested-by: Andreas Arnez <[email protected]> Signed-off-by: Harald Freudenberger <[email protected]> Acked-by: Heiko Carstens <[email protected]> Reviewed-by: Holger Dengler <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent ae4b60f commit ebf95e8

File tree

3 files changed

+55
-51
lines changed

3 files changed

+55
-51
lines changed

arch/s390/include/asm/ap.h

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ struct ap_queue_status {
4949
unsigned int _pad2 : 16;
5050
};
5151

52+
/*
53+
* AP queue status reg union to access the reg1
54+
* register with the lower 32 bits comprising the
55+
* ap queue status.
56+
*/
57+
union ap_queue_status_reg {
58+
unsigned long value;
59+
struct {
60+
u32 _pad;
61+
struct ap_queue_status status;
62+
};
63+
};
64+
5265
/**
5366
* ap_intructions_available() - Test if AP instructions are available.
5467
*
@@ -82,7 +95,7 @@ static inline bool ap_instructions_available(void)
8295
*/
8396
static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
8497
{
85-
struct ap_queue_status reg1;
98+
union ap_queue_status_reg reg1;
8699
unsigned long reg2;
87100

88101
asm volatile(
@@ -91,12 +104,12 @@ static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
91104
" .insn rre,0xb2af0000,0,0\n" /* PQAP(TAPQ) */
92105
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
93106
" lgr %[reg2],2\n" /* gr2 into reg2 */
94-
: [reg1] "=&d" (reg1), [reg2] "=&d" (reg2)
107+
: [reg1] "=&d" (reg1.value), [reg2] "=&d" (reg2)
95108
: [qid] "d" (qid)
96109
: "cc", "0", "1", "2");
97110
if (info)
98111
*info = reg2;
99-
return reg1;
112+
return reg1.status;
100113
}
101114

102115
/**
@@ -125,16 +138,16 @@ static inline struct ap_queue_status ap_test_queue(ap_qid_t qid,
125138
static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
126139
{
127140
unsigned long reg0 = qid | (1UL << 24); /* fc 1UL is RAPQ */
128-
struct ap_queue_status reg1;
141+
union ap_queue_status_reg reg1;
129142

130143
asm volatile(
131144
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
132145
" .insn rre,0xb2af0000,0,0\n" /* PQAP(RAPQ) */
133146
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
134-
: [reg1] "=&d" (reg1)
147+
: [reg1] "=&d" (reg1.value)
135148
: [reg0] "d" (reg0)
136149
: "cc", "0", "1");
137-
return reg1;
150+
return reg1.status;
138151
}
139152

140153
/**
@@ -146,16 +159,16 @@ static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
146159
static inline struct ap_queue_status ap_zapq(ap_qid_t qid)
147160
{
148161
unsigned long reg0 = qid | (2UL << 24); /* fc 2UL is ZAPQ */
149-
struct ap_queue_status reg1;
162+
union ap_queue_status_reg reg1;
150163

151164
asm volatile(
152165
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
153166
" .insn rre,0xb2af0000,0,0\n" /* PQAP(ZAPQ) */
154167
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
155-
: [reg1] "=&d" (reg1)
168+
: [reg1] "=&d" (reg1.value)
156169
: [reg0] "d" (reg0)
157170
: "cc", "0", "1");
158-
return reg1;
171+
return reg1.status;
159172
}
160173

161174
/**
@@ -209,18 +222,21 @@ static inline int ap_qci(struct ap_config_info *config)
209222
* parameter to the PQAP(AQIC) instruction. For details please
210223
* see the AR documentation.
211224
*/
212-
struct ap_qirq_ctrl {
213-
unsigned int _res1 : 8;
214-
unsigned int zone : 8; /* zone info */
215-
unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */
216-
unsigned int _res2 : 4;
217-
unsigned int gisc : 3; /* guest isc field */
218-
unsigned int _res3 : 6;
219-
unsigned int gf : 2; /* gisa format */
220-
unsigned int _res4 : 1;
221-
unsigned int gisa : 27; /* gisa origin */
222-
unsigned int _res5 : 1;
223-
unsigned int isc : 3; /* irq sub class */
225+
union ap_qirq_ctrl {
226+
unsigned long value;
227+
struct {
228+
unsigned int : 8;
229+
unsigned int zone : 8; /* zone info */
230+
unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */
231+
unsigned int : 4;
232+
unsigned int gisc : 3; /* guest isc field */
233+
unsigned int : 6;
234+
unsigned int gf : 2; /* gisa format */
235+
unsigned int : 1;
236+
unsigned int gisa : 27; /* gisa origin */
237+
unsigned int : 1;
238+
unsigned int isc : 3; /* irq sub class */
239+
};
224240
};
225241

226242
/**
@@ -232,29 +248,22 @@ struct ap_qirq_ctrl {
232248
* Returns AP queue status.
233249
*/
234250
static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
235-
struct ap_qirq_ctrl qirqctrl,
251+
union ap_qirq_ctrl qirqctrl,
236252
phys_addr_t pa_ind)
237253
{
238254
unsigned long reg0 = qid | (3UL << 24); /* fc 3UL is AQIC */
239-
union {
240-
unsigned long value;
241-
struct ap_qirq_ctrl qirqctrl;
242-
struct {
243-
u32 _pad;
244-
struct ap_queue_status status;
245-
};
246-
} reg1;
255+
union ap_queue_status_reg reg1;
247256
unsigned long reg2 = pa_ind;
248257

249-
reg1.qirqctrl = qirqctrl;
258+
reg1.value = qirqctrl.value;
250259

251260
asm volatile(
252261
" lgr 0,%[reg0]\n" /* qid param into gr0 */
253262
" lgr 1,%[reg1]\n" /* irq ctrl into gr1 */
254263
" lgr 2,%[reg2]\n" /* ni addr into gr2 */
255264
" .insn rre,0xb2af0000,0,0\n" /* PQAP(AQIC) */
256265
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
257-
: [reg1] "+&d" (reg1)
266+
: [reg1] "+&d" (reg1.value)
258267
: [reg0] "d" (reg0), [reg2] "d" (reg2)
259268
: "cc", "memory", "0", "1", "2");
260269

@@ -291,13 +300,7 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
291300
union ap_qact_ap_info *apinfo)
292301
{
293302
unsigned long reg0 = qid | (5UL << 24) | ((ifbit & 0x01) << 22);
294-
union {
295-
unsigned long value;
296-
struct {
297-
u32 _pad;
298-
struct ap_queue_status status;
299-
};
300-
} reg1;
303+
union ap_queue_status_reg reg1;
301304
unsigned long reg2;
302305

303306
reg1.value = apinfo->val;
@@ -308,7 +311,7 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
308311
" .insn rre,0xb2af0000,0,0\n" /* PQAP(QACT) */
309312
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
310313
" lgr %[reg2],2\n" /* qact out info into reg2 */
311-
: [reg1] "+&d" (reg1), [reg2] "=&d" (reg2)
314+
: [reg1] "+&d" (reg1.value), [reg2] "=&d" (reg2)
312315
: [reg0] "d" (reg0)
313316
: "cc", "0", "1", "2");
314317
apinfo->val = reg2;
@@ -333,7 +336,7 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
333336
{
334337
unsigned long reg0 = qid | 0x40000000UL; /* 0x4... is last msg part */
335338
union register_pair nqap_r1, nqap_r2;
336-
struct ap_queue_status reg1;
339+
union ap_queue_status_reg reg1;
337340

338341
nqap_r1.even = (unsigned int)(psmid >> 32);
339342
nqap_r1.odd = psmid & 0xffffffff;
@@ -345,11 +348,11 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
345348
"0: .insn rre,0xb2ad0000,%[nqap_r1],%[nqap_r2]\n"
346349
" brc 2,0b\n" /* handle partial completion */
347350
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
348-
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1),
351+
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
349352
[nqap_r2] "+&d" (nqap_r2.pair)
350353
: [nqap_r1] "d" (nqap_r1.pair)
351354
: "cc", "memory", "0", "1");
352-
return reg1;
355+
return reg1.status;
353356
}
354357

355358
/**
@@ -389,7 +392,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
389392
unsigned long *resgr0)
390393
{
391394
unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL;
392-
struct ap_queue_status reg1;
395+
union ap_queue_status_reg reg1;
393396
unsigned long reg2;
394397
union register_pair rp1, rp2;
395398

@@ -408,8 +411,9 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
408411
"2: lgr %[reg0],0\n" /* gr0 (qid + info) into reg0 */
409412
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
410413
" lgr %[reg2],2\n" /* gr2 (res length) into reg2 */
411-
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1), [reg2] "=&d" (reg2),
412-
[rp1] "+&d" (rp1.pair), [rp2] "+&d" (rp2.pair)
414+
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
415+
[reg2] "=&d" (reg2), [rp1] "+&d" (rp1.pair),
416+
[rp2] "+&d" (rp2.pair)
413417
:
414418
: "cc", "memory", "0", "1", "2");
415419

@@ -421,7 +425,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
421425
* Signal the caller that this dqap is only partially received
422426
* with a special status response code 0xFF and *resgr0 updated
423427
*/
424-
reg1.response_code = 0xFF;
428+
reg1.status.response_code = 0xFF;
425429
if (resgr0)
426430
*resgr0 = reg0;
427431
} else {
@@ -430,7 +434,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
430434
*resgr0 = 0;
431435
}
432436

433-
return reg1;
437+
return reg1.status;
434438
}
435439

436440
/*

drivers/s390/crypto/ap_queue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ static void __ap_flush_queue(struct ap_queue *aq);
2929
*/
3030
static int ap_queue_enable_irq(struct ap_queue *aq, void *ind)
3131
{
32+
union ap_qirq_ctrl qirqctrl = { .value = 0 };
3233
struct ap_queue_status status;
33-
struct ap_qirq_ctrl qirqctrl = { 0 };
3434

3535
qirqctrl.ir = 1;
3636
qirqctrl.isc = AP_ISC;

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q)
301301
*/
302302
static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q)
303303
{
304-
struct ap_qirq_ctrl aqic_gisa = {};
304+
union ap_qirq_ctrl aqic_gisa = { .value = 0 };
305305
struct ap_queue_status status;
306306
int retries = 5;
307307

@@ -384,7 +384,7 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q,
384384
int isc,
385385
struct kvm_vcpu *vcpu)
386386
{
387-
struct ap_qirq_ctrl aqic_gisa = {};
387+
union ap_qirq_ctrl aqic_gisa = { .value = 0 };
388388
struct ap_queue_status status = {};
389389
struct kvm_s390_gisa *gisa;
390390
struct page *h_page;

0 commit comments

Comments
 (0)