kvm/vfio: Refactor VFIO function calls
There are many function calls to VFIO that follows same pattern by
get/put symbol, we can just refactor these in a macro.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
index 06d4b0e..ef3c06b 100644
--- a/virt/kvm/vfio.c
+++ b/virt/kvm/vfio.c
@@ -36,6 +36,22 @@ struct kvm_vfio {
bool noncoherent;
};
+#define KVM_CALL_VFIO(fn, ret_type, ...) \
+ ({ \
+ ret_type ret; \
+ do { \
+ typeof(fn) *__fn; \
+ __fn = symbol_get(fn); \
+ if (!__fn) { \
+ ret = (ret_type)0; \
+ break; \
+ } \
+ ret = __fn(__VA_ARGS__); \
+ symbol_put(fn); \
+ } while (0); \
+ ret; \
+ })
+
static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)
{
void (*fn)(struct file *file, struct kvm *kvm);
@@ -49,103 +65,7 @@ static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)
symbol_put(vfio_file_set_kvm);
}
-static bool kvm_vfio_file_enforced_coherent(struct file *file)
-{
- bool (*fn)(struct file *file);
- bool ret;
-
- fn = symbol_get(vfio_file_enforced_coherent);
- if (!fn)
- return false;
-
- ret = fn(file);
-
- symbol_put(vfio_file_enforced_coherent);
-
- return ret;
-}
-
-static bool kvm_vfio_file_is_group(struct file *file)
-{
- bool (*fn)(struct file *file);
- bool ret;
-
- fn = symbol_get(vfio_file_is_group);
- if (!fn)
- return false;
-
- ret = fn(file);
-
- symbol_put(vfio_file_is_group);
-
- return ret;
-}
-
-static bool kvm_vfio_file_is_device(struct file *file)
-{
- bool (*fn)(struct file *file);
- bool ret;
-
- fn = symbol_get(vfio_file_is_device);
- if (!fn)
- return false;
-
- ret = fn(file);
-
- symbol_put(vfio_file_is_device);
-
- return ret;
-}
-
-static struct iommu_fwspec *kvm_vfio_iommu_fwspec(struct file *file)
-{
- struct iommu_fwspec *(*fn)(struct file *file);
- struct iommu_fwspec *ret;
-
- fn = symbol_get(vfio_file_device_get_iommu_fwspec);
- if (!fn)
- return NULL;
-
- ret = fn(file);
-
- symbol_put(vfio_file_device_get_iommu_fwspec);
-
- return ret;
-}
-
-static int kvm_vfio_iommu_detach_device(struct file *file)
-{
- int (*fn)(struct file *file);
- int ret;
-
- fn = symbol_get(vfio_detach_iommu_device);
- if (!fn)
- return NULL;
-
- ret = fn(file);
-
- symbol_put(vfio_detach_iommu_device);
-
- return ret;
-}
-
#ifdef CONFIG_SPAPR_TCE_IOMMU
-static struct iommu_group *kvm_vfio_file_iommu_group(struct file *file)
-{
- struct iommu_group *(*fn)(struct file *file);
- struct iommu_group *ret;
-
- fn = symbol_get(vfio_file_iommu_group);
- if (!fn)
- return NULL;
-
- ret = fn(file);
-
- symbol_put(vfio_file_iommu_group);
-
- return ret;
-}
-
static void kvm_spapr_tce_release_vfio_group(struct kvm *kvm,
struct kvm_vfio_group *kvg)
{
@@ -174,7 +94,7 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev)
mutex_lock(&kv->lock);
list_for_each_entry(kvg, &kv->group_list, node) {
- if (!kvm_vfio_file_enforced_coherent(kvg->file)) {
+ if (!KVM_CALL_VFIO(vfio_file_enforced_coherent, bool, kvg->file)) {
noncoherent = true;
break;
}
@@ -204,7 +124,7 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd)
return -EBADF;
/* Ensure the FD is a vfio group FD.*/
- if (!kvm_vfio_file_is_group(filp)) {
+ if (!KVM_CALL_VFIO(vfio_file_is_group, bool, filp)) {
ret = -EINVAL;
goto err_fput;
}
@@ -308,7 +228,8 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev,
continue;
if (!kvg->iommu_group) {
- kvg->iommu_group = kvm_vfio_file_iommu_group(kvg->file);
+ kvg->iommu_group = KVM_CALL_VFIO(vfio_file_iommu_group,
+ struct iommu_group *, kvg->file);
if (WARN_ON_ONCE(!kvg->iommu_group)) {
ret = -EIO;
goto err_fdput;
@@ -381,11 +302,12 @@ static int kvm_vfio_pviommu_get_info(struct kvm_device *dev,
if (!filp)
return -EBADF;
- if (!kvm_vfio_file_is_device(filp)) {
+ if (!KVM_CALL_VFIO(vfio_file_is_device, bool, filp)) {
ret = -EINVAL;
goto err_fput;
}
- info->nr_sids = kvm_vfio_iommu_fwspec(filp)->num_ids;
+ info->nr_sids = KVM_CALL_VFIO(vfio_file_device_get_iommu_fwspec,
+ struct iommu_fwspec *, filp)->num_ids;
err_fput:
fput(filp);
return ret;
@@ -405,7 +327,7 @@ int kvm_vfio_pviommu_set_config(struct kvm_device *dev,
if (!filp)
return -EBADF;
- fwspec = kvm_vfio_iommu_fwspec(filp);
+ fwspec = KVM_CALL_VFIO(vfio_file_device_get_iommu_fwspec, struct iommu_fwspec *, filp);
if (!fwspec) {
ret = -EINVAL;
goto err_fput;
@@ -428,7 +350,7 @@ int kvm_vfio_pviommu_set_config(struct kvm_device *dev,
}
/* Safe to call multiple time on same device. */
- ret = kvm_vfio_iommu_detach_device(filp);
+ ret = KVM_CALL_VFIO(vfio_detach_iommu_device, int, filp);
if (ret)
goto err_fput;