Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46fde9a9 authored by Harald Freudenberger's avatar Harald Freudenberger Committed by Martin Schwidefsky
Browse files

s390/zcrypt: externalize AP queue interrupt control



KVM has a need to control the interrupts on real and virtualized
AP queue devices. This fix provides a new function to control
the interrupt facilities of an AP queue device.

Signed-off-by: default avatarHarald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 050349b5
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -87,4 +87,40 @@ struct ap_config_info {
 */
int ap_query_configuration(struct ap_config_info *info);

/*
 * struct ap_qirq_ctrl - convenient struct for easy invocation
 * of the ap_queue_irq_ctrl() function. This struct is passed
 * as GR1 parameter to the PQAP(AQIC) instruction. For details
 * please see the AR documentation.
 */
struct ap_qirq_ctrl {
	unsigned int _res1 : 8;
	unsigned int zone  : 8;  /* zone info */
	unsigned int ir    : 1;  /* ir flag: enable (1) or disable (0) irq */
	unsigned int _res2 : 4;
	unsigned int gisc  : 3;  /* guest isc field */
	unsigned int _res3 : 6;
	unsigned int gf    : 2;  /* gisa format */
	unsigned int _res4 : 1;
	unsigned int gisa  : 27; /* gisa origin */
	unsigned int _res5 : 1;
	unsigned int isc   : 3;  /* irq sub class */
};

/**
 * ap_queue_irq_ctrl(): Control interruption on a AP queue.
 * @qid: The AP queue number
 * @qirqctrl: struct ap_qirq_ctrl, see above
 * @ind: The notification indicator byte
 *
 * Returns AP queue status.
 *
 * Control interruption on the given AP queue.
 * Just a simple wrapper function for the low level PQAP(AQIC)
 * instruction available for other kernel modules.
 */
struct ap_queue_status ap_queue_irq_ctrl(ap_qid_t qid,
					 struct ap_qirq_ctrl qirqctrl,
					 void *ind);

#endif /* _ASM_S390_AP_H_ */
+6 −3
Original line number Diff line number Diff line
@@ -69,16 +69,19 @@ static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
}

/**
 * ap_aqic(): Enable interruption for a specific AP.
 * ap_aqic(): Control interruption for a specific AP.
 * @qid: The AP queue number
 * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
 * @ind: The notification indicator byte
 *
 * Returns AP queue status.
 */
static inline struct ap_queue_status ap_aqic(ap_qid_t qid, void *ind)
static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
					     struct ap_qirq_ctrl qirqctrl,
					     void *ind)
{
	register unsigned long reg0 asm ("0") = qid | (3UL << 24);
	register unsigned long reg1_in asm ("1") = (8UL << 44) | AP_ISC;
	register struct ap_qirq_ctrl reg1_in asm ("1") = qirqctrl;
	register struct ap_queue_status reg1_out asm ("1");
	register void *reg2 asm ("2") = ind;

+23 −1
Original line number Diff line number Diff line
@@ -15,6 +15,25 @@
#include "ap_bus.h"
#include "ap_asm.h"

/**
 * ap_queue_irq_ctrl(): Control interruption on a AP queue.
 * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
 * @ind: The notification indicator byte
 *
 * Returns AP queue status.
 *
 * Control interruption on the given AP queue.
 * Just a simple wrapper function for the low level PQAP(AQIC)
 * instruction available for other kernel modules.
 */
struct ap_queue_status ap_queue_irq_ctrl(ap_qid_t qid,
					 struct ap_qirq_ctrl qirqctrl,
					 void *ind)
{
	return ap_aqic(qid, qirqctrl, ind);
}
EXPORT_SYMBOL(ap_queue_irq_ctrl);

/**
 * ap_queue_enable_interruption(): Enable interruption on an AP queue.
 * @qid: The AP queue number
@@ -27,8 +46,11 @@
static int ap_queue_enable_interruption(struct ap_queue *aq, void *ind)
{
	struct ap_queue_status status;
	struct ap_qirq_ctrl qirqctrl = { 0 };

	status = ap_aqic(aq->qid, ind);
	qirqctrl.ir = 1;
	qirqctrl.isc = AP_ISC;
	status = ap_aqic(aq->qid, qirqctrl, ind);
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_OTHERWISE_CHANGED: