[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1564612877-7598-7-git-send-email-akrowiak@linux.ibm.com>
Date: Wed, 31 Jul 2019 18:41:16 -0400
From: Tony Krowiak <akrowiak@...ux.ibm.com>
To: linux-s390@...r.kernel.org, linux-kernel@...r.kernel.org,
kvm@...r.kernel.org
Cc: freude@...ux.ibm.com, borntraeger@...ibm.com, cohuck@...hat.com,
frankja@...ux.ibm.com, david@...hat.com, mjrosato@...ux.ibm.com,
schwidefsky@...ibm.com, heiko.carstens@...ibm.com,
pmorel@...ux.ibm.com, pasic@...ux.ibm.com,
alex.williamson@...hat.com, kwankhede@...dia.com,
Tony Krowiak <akrowiak@...ux.ibm.com>
Subject: [PATCH v5 6/7] s390: vfio-ap: add logging to vfio_ap driver
Added two DBF log files for logging events and errors; one for the vfio_ap
driver, and one for each matrix mediated device.
Signed-off-by: Tony Krowiak <akrowiak@...ux.ibm.com>
---
drivers/s390/crypto/vfio_ap_drv.c | 34 +++++++
drivers/s390/crypto/vfio_ap_ops.c | 187 ++++++++++++++++++++++++++++++----
drivers/s390/crypto/vfio_ap_private.h | 20 ++++
3 files changed, 223 insertions(+), 18 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c
index d8da520ae1fa..04a77246c22a 100644
--- a/drivers/s390/crypto/vfio_ap_drv.c
+++ b/drivers/s390/crypto/vfio_ap_drv.c
@@ -22,6 +22,10 @@ MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("VFIO AP device driver, Copyright IBM Corp. 2018");
MODULE_LICENSE("GPL v2");
+uint dbglvl = 3;
+module_param(dbglvl, uint, 0444);
+MODULE_PARM_DESC(dbglvl, "VFIO_AP driver debug level.");
+
static struct ap_driver vfio_ap_drv;
struct ap_matrix_dev *matrix_dev;
@@ -158,6 +162,21 @@ static void vfio_ap_matrix_dev_destroy(void)
root_device_unregister(root_device);
}
+static void vfio_ap_log_queues_in_use(struct ap_matrix_mdev *matrix_mdev,
+ unsigned long *apm, unsigned long *aqm)
+{
+ unsigned long apid, apqi;
+
+ for_each_set_bit_inv(apid, apm, AP_DEVICES) {
+ for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) {
+ VFIO_AP_DBF(matrix_dev, DBF_ERR,
+ "queue %02lx.%04lx in use by mdev %s\n",
+ apid, apqi,
+ dev_name(mdev_dev(matrix_mdev->mdev)));
+ }
+ }
+}
+
static bool vfio_ap_resource_in_use(unsigned long *apm, unsigned long *aqm)
{
bool in_use = false;
@@ -179,6 +198,8 @@ static bool vfio_ap_resource_in_use(unsigned long *apm, unsigned long *aqm)
continue;
in_use = true;
+ vfio_ap_log_queues_in_use(matrix_mdev, apm_intrsctn,
+ aqm_intrsctn);
}
mutex_unlock(&matrix_dev->lock);
@@ -186,6 +207,16 @@ static bool vfio_ap_resource_in_use(unsigned long *apm, unsigned long *aqm)
return in_use;
}
+static int __init vfio_ap_debug_init(void)
+{
+ matrix_dev->dbf = debug_register(VFIO_AP_DRV_NAME, 1, 1,
+ DBF_SPRINTF_MAX_ARGS * sizeof(long));
+ debug_register_view(matrix_dev->dbf, &debug_sprintf_view);
+ debug_set_level(matrix_dev->dbf, dbglvl);
+
+ return 0;
+}
+
static int __init vfio_ap_init(void)
{
int ret;
@@ -219,6 +250,8 @@ static int __init vfio_ap_init(void)
return ret;
}
+ vfio_ap_debug_init();
+
return 0;
}
@@ -227,6 +260,7 @@ static void __exit vfio_ap_exit(void)
vfio_ap_mdev_unregister();
ap_driver_unregister(&vfio_ap_drv);
vfio_ap_matrix_dev_destroy();
+ debug_unregister(matrix_dev->dbf);
}
module_init(vfio_ap_init);
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 0e748819abb6..1aa18eba43d0 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -167,17 +167,23 @@ static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q)
case AP_RESPONSE_INVALID_ADDRESS:
default:
/* All cases in default means AP not operational */
- WARN_ONCE(1, "%s: ap_aqic status %d\n", __func__,
- status.response_code);
goto end_free;
}
} while (retries--);
- WARN_ONCE(1, "%s: ap_aqic status %d\n", __func__,
- status.response_code);
end_free:
vfio_ap_free_aqic_resources(q);
q->matrix_mdev = NULL;
+ if (status.response_code) {
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_WARN,
+ "IRQ disable failed for queue %02x.%04x: status response code=%u\n",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
+ status.response_code);
+ } else {
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_INFO,
+ "IRQ disabled for queue %02x.%04x\n",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn));
+ }
return status;
}
@@ -215,6 +221,10 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q,
case 1:
break;
default:
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_ERR,
+ "IRQ enable failed for queue %02x.%04x: vfio_pin_pages rc=%d\n",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
+ ret);
status.response_code = AP_RESPONSE_INVALID_ADDRESS;
return status;
}
@@ -235,16 +245,25 @@ static struct ap_queue_status vfio_ap_irq_enable(struct vfio_ap_queue *q,
vfio_ap_free_aqic_resources(q);
q->saved_pfn = g_pfn;
q->saved_isc = isc;
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_INFO,
+ "IRQ enabled for queue %02x.%04x",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn));
break;
case AP_RESPONSE_OTHERWISE_CHANGED:
/* We could not modify IRQ setings: clear new configuration */
vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), &g_pfn, 1);
kvm_s390_gisc_unregister(kvm, isc);
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_WARN,
+ "IRQ enable failed for queue %02x.%04x: status response code=%u",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
+ status.response_code);
break;
default:
- pr_warn("%s: apqn %04x: response: %02x\n", __func__, q->apqn,
- status.response_code);
vfio_ap_irq_disable(q);
+ VFIO_AP_MDEV_DBF(q->matrix_mdev, DBF_WARN,
+ "IRQ enable failed for queue %02x.%04x: status response code=%u",
+ AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
+ status.response_code);
break;
}
@@ -321,8 +340,29 @@ static void vfio_ap_matrix_init(struct ap_config_info *info,
matrix->adm_max = info->apxa ? info->Nd : 15;
}
+static int vfio_ap_mdev_debug_init(struct ap_matrix_mdev *matrix_mdev)
+{
+ int ret;
+
+ matrix_mdev->dbf = debug_register(dev_name(mdev_dev(matrix_mdev->mdev)),
+ 1, 1,
+ DBF_SPRINTF_MAX_ARGS * sizeof(long));
+
+ if (!matrix_mdev->dbf)
+ return -ENOMEM;
+
+ ret = debug_register_view(matrix_mdev->dbf, &debug_sprintf_view);
+ if (ret)
+ return ret;
+
+ debug_set_level(matrix_mdev->dbf, dbglvl);
+
+ return 0;
+}
+
static int vfio_ap_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
{
+ int ret;
struct ap_matrix_mdev *matrix_mdev;
if ((atomic_dec_if_positive(&matrix_dev->available_instances) < 0))
@@ -335,6 +375,13 @@ static int vfio_ap_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
}
matrix_mdev->mdev = mdev;
+
+ ret = vfio_ap_mdev_debug_init(matrix_mdev);
+ if (ret) {
+ kfree(matrix_mdev);
+ return ret;
+ }
+
vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
mdev_set_drvdata(mdev, matrix_mdev);
matrix_mdev->pqap_hook.hook = handle_pqap;
@@ -350,14 +397,19 @@ static int vfio_ap_mdev_remove(struct mdev_device *mdev)
{
struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
- if (matrix_mdev->kvm)
+ if (matrix_mdev->kvm) {
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "remove rejected, mdev in use by %s",
+ matrix_mdev->kvm->debugfs_dentry->d_iname);
return -EBUSY;
+ }
mutex_lock(&matrix_dev->lock);
vfio_ap_mdev_reset_queues(mdev);
list_del(&matrix_mdev->node);
mutex_unlock(&matrix_dev->lock);
+ debug_unregister(matrix_mdev->dbf);
kfree(matrix_mdev);
mdev_set_drvdata(mdev, NULL);
atomic_inc(&matrix_dev->available_instances);
@@ -406,6 +458,22 @@ static struct attribute_group *vfio_ap_mdev_type_groups[] = {
NULL,
};
+static void vfio_ap_mdev_log_sharing_error(struct ap_matrix_mdev *logdev,
+ const char *assigned_to,
+ unsigned long *apm,
+ unsigned long *aqm)
+{
+ unsigned long apid, apqi;
+
+ for_each_set_bit_inv(apid, apm, AP_DEVICES) {
+ for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) {
+ VFIO_AP_MDEV_DBF(logdev, DBF_ERR,
+ "queue %02lx.%04lx already assigned to %s\n",
+ apid, apqi, assigned_to);
+ }
+ }
+}
+
/**
* vfio_ap_mdev_verify_no_sharing
*
@@ -448,22 +516,39 @@ static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *matrix_mdev,
if (!bitmap_and(aqm, mdev_aqm, lstdev->matrix.aqm, AP_DOMAINS))
continue;
+ vfio_ap_mdev_log_sharing_error(matrix_mdev,
+ dev_name(mdev_dev(lstdev->mdev)),
+ apm, aqm);
+
return -EADDRINUSE;
}
return 0;
}
-static int vfio_ap_mdev_validate_masks(struct ap_matrix_mdev *matrix_mdev,
+static int vfio_ap_mdev_validate_masks(struct ap_matrix_mdev *logdev,
unsigned long *apm, unsigned long *aqm)
{
- int ret;
+ int ret = 0;
+ unsigned long apid, apqi;
+
+ for_each_set_bit_inv(apid, apm, AP_DEVICES) {
+ for_each_set_bit_inv(apqi, aqm, AP_DEVICES) {
+ if (!ap_owned_by_def_drv(apid, apqi))
+ continue;
+
+ VFIO_AP_MDEV_DBF(logdev, DBF_ERR,
+ "queue %02lx.%04lx owned by zcrypt\n",
+ apid, apqi);
+
+ ret = -EADDRNOTAVAIL;
+ }
+ }
- ret = ap_apqn_in_matrix_owned_by_def_drv(apm, aqm);
if (ret)
- return (ret == 1) ? -EADDRNOTAVAIL : ret;
+ return ret;
- return vfio_ap_mdev_verify_no_sharing(matrix_mdev, apm, aqm);
+ return vfio_ap_mdev_verify_no_sharing(logdev, apm, aqm);
}
static void vfio_ap_mdev_update_crycb(struct ap_matrix_mdev *matrix_mdev)
@@ -536,13 +621,20 @@ static ssize_t assign_adapter_store(struct device *dev,
matrix_mdev->matrix.aqm);
if (ret) {
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "failed to assign adapter %lu(%#02lx)\n",
+ apid, apid);
return ret;
}
+
set_bit_inv(apid, matrix_mdev->matrix.apm);
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "assigned adapter %lu(%#02lx)\n", apid, apid);
+
return count;
}
static DEVICE_ATTR_WO(assign_adapter);
@@ -587,6 +679,9 @@ static ssize_t unassign_adapter_store(struct device *dev,
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "unassigned adapter %lu(%#02lx)\n", apid, apid);
+
return count;
}
static DEVICE_ATTR_WO(unassign_adapter);
@@ -651,6 +746,9 @@ static ssize_t assign_domain_store(struct device *dev,
aqm);
if (ret) {
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "failed to assign domain %lu(%#04lx)\n",
+ apqi, apqi);
return ret;
}
@@ -658,6 +756,9 @@ static ssize_t assign_domain_store(struct device *dev,
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "assigned domain %lu(%#04lx)\n", apqi, apqi);
+
return count;
}
static DEVICE_ATTR_WO(assign_domain);
@@ -703,6 +804,9 @@ static ssize_t unassign_domain_store(struct device *dev,
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "unassigned domain %lu(%#02lx)\n", apqi, apqi);
+
return count;
}
static DEVICE_ATTR_WO(unassign_domain);
@@ -746,6 +850,9 @@ static ssize_t assign_control_domain_store(struct device *dev,
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "assigned control domain %lu(%#02lx)\n", id, id);
+
return count;
}
static DEVICE_ATTR_WO(assign_control_domain);
@@ -789,6 +896,10 @@ static ssize_t unassign_control_domain_store(struct device *dev,
vfio_ap_mdev_update_crycb(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "unassigned control domain %lu(%#02lx)\n",
+ domid, domid);
+
return count;
}
static DEVICE_ATTR_WO(unassign_control_domain);
@@ -910,6 +1021,9 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
list_for_each_entry(m, &matrix_dev->mdev_list, node) {
if ((m != matrix_mdev) && (m->kvm == kvm)) {
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "KVM already set for mdev %s\n",
+ dev_name(mdev_dev(m->mdev)));
return -EPERM;
}
}
@@ -919,6 +1033,8 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev *matrix_mdev,
kvm->arch.crypto.pqap_hook = &matrix_mdev->pqap_hook;
mutex_unlock(&matrix_dev->lock);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO, "KVM set for mdev\n");
+
return 0;
}
@@ -972,8 +1088,11 @@ static int vfio_ap_mdev_group_notifier(struct notifier_block *nb,
return NOTIFY_DONE;
/* If there is no CRYCB pointer, then we can't copy the masks */
- if (!matrix_mdev->kvm->arch.crypto.crycbd)
+ if (!matrix_mdev->kvm->arch.crypto.crycbd) {
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "Failed to set CRYCB masks: missing CRYCBD\n");
return NOTIFY_DONE;
+ }
kvm_arch_crypto_set_masks(matrix_mdev->kvm, matrix_mdev->matrix.apm,
matrix_mdev->matrix.aqm,
@@ -1013,9 +1132,10 @@ static void vfio_ap_mdev_wait_for_qempty(ap_qid_t qid)
msleep(20);
break;
default:
- pr_warn("%s: tapq response %02x waiting for queue %04x.%02x empty\n",
- __func__, status.response_code,
- AP_QID_CARD(qid), AP_QID_QUEUE(qid));
+ WARN_ONCE(1,
+ "%s: tapq response %02x waiting for queue %04x.%02x empty\n",
+ __func__, status.response_code,
+ AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return;
}
} while (--retry);
@@ -1062,8 +1182,16 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm,
matrix_mdev->matrix.aqm_max + 1) {
ret = vfio_ap_mdev_reset_queue(apid, apqi);
- if (ret)
+ if (ret) {
rc = ret;
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "queue %02lx.%04lx reset failed: rc=%d\n",
+ apid, apqi, ret);
+ } else {
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_INFO,
+ "queue %02lx.%04lx reset\n",
+ apid, apqi);
+ }
vfio_ap_irq_disable_apqn(AP_MKQID(apid, apqi));
}
@@ -1089,6 +1217,9 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev)
&events, &matrix_mdev->group_notifier);
if (ret) {
module_put(THIS_MODULE);
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "failed to open mdev fd: VFIO_GROUP_NOTIFY notifier registration failed with rc=%d\n",
+ ret);
return ret;
}
@@ -1096,12 +1227,19 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev)
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
&events, &matrix_mdev->iommu_notifier);
- if (!ret)
+ if (!ret) {
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_DEBUG,
+ "opened mdev fd: guest started\n");
return ret;
+ }
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_ERR,
+ "failed to open mdev fd: VFIO_IOMMU_NOTIFY notifier registration failed with rc=%d\n",
+ ret);
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
&matrix_mdev->group_notifier);
module_put(THIS_MODULE);
+
return ret;
}
@@ -1124,6 +1262,9 @@ static void vfio_ap_mdev_release(struct mdev_device *mdev)
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
&matrix_mdev->group_notifier);
module_put(THIS_MODULE);
+
+ VFIO_AP_MDEV_DBF(matrix_mdev, DBF_DEBUG,
+ "released mdev fd: guest terminated\n");
}
static int vfio_ap_mdev_get_device_info(unsigned long arg)
@@ -1202,6 +1343,11 @@ int vfio_ap_mdev_probe_queue(struct ap_queue *queue)
q->apqn = queue->qid;
q->saved_isc = VFIO_AP_ISC_INVALID;
+ VFIO_AP_DBF(matrix_dev, DBF_DEBUG,
+ "queue %02x.%04x bound to %s\n",
+ AP_QID_CARD(queue->qid), AP_QID_QUEUE(queue->qid),
+ VFIO_AP_DRV_NAME);
+
return 0;
}
@@ -1217,4 +1363,9 @@ void vfio_ap_mdev_remove_queue(struct ap_queue *queue)
vfio_ap_mdev_reset_queue(apid, apqi);
vfio_ap_irq_disable(q);
kfree(q);
+
+ VFIO_AP_DBF(matrix_dev, DBF_DEBUG,
+ "queue %02x.%04x unbound from %s\n",
+ AP_QID_CARD(queue->qid), AP_QID_QUEUE(queue->qid),
+ VFIO_AP_DRV_NAME);
}
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 5cc3c2ebf151..f717e43e10cf 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -24,6 +24,21 @@
#define VFIO_AP_MODULE_NAME "vfio_ap"
#define VFIO_AP_DRV_NAME "vfio_ap"
+#define DBF_ERR 3 /* error conditions */
+#define DBF_WARN 4 /* warning conditions */
+#define DBF_INFO 5 /* informational */
+#define DBF_DEBUG 6 /* for debugging only */
+
+#define DBF_SPRINTF_MAX_ARGS 5
+
+#define VFIO_AP_DBF(d_matrix_dev, ...) \
+ debug_sprintf_event(d_matrix_dev->dbf, ##__VA_ARGS__)
+
+#define VFIO_AP_MDEV_DBF(d_matrix_mdev, ...) \
+ debug_sprintf_event(d_matrix_mdev->dbf, ##__VA_ARGS__)
+
+extern uint dbglvl;
+
/**
* ap_matrix_dev - the AP matrix device structure
* @device: generic device structure associated with the AP matrix device
@@ -43,6 +58,7 @@ struct ap_matrix_dev {
struct list_head mdev_list;
struct mutex lock;
struct ap_driver *vfio_ap_drv;
+ debug_info_t *dbf;
};
extern struct ap_matrix_dev *matrix_dev;
@@ -77,6 +93,9 @@ struct ap_matrix {
* @group_notifier: notifier block used for specifying callback function for
* handling the VFIO_GROUP_NOTIFY_SET_KVM event
* @kvm: the struct holding guest's state
+ * @pqap_hook: handler for PQAP instruction
+ * @mdev: the matrix mediated device
+ * @dbf: the debug info log
*/
struct ap_matrix_mdev {
struct list_head node;
@@ -86,6 +105,7 @@ struct ap_matrix_mdev {
struct kvm *kvm;
struct kvm_s390_module_hook pqap_hook;
struct mdev_device *mdev;
+ debug_info_t *dbf;
};
extern int vfio_ap_mdev_register(void);
--
2.7.4
Powered by blists - more mailing lists