Merge tag 'vfio-v5.15-rc1' of git://github.com/awilliam/linux-vfio
[linux-2.6-microblaze.git] / drivers / md / dm-ioctl.c
index 2209cbc..21fe865 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include "dm-core.h"
-
+#include "dm-ima.h"
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/miscdevice.h>
@@ -20,6 +20,7 @@
 #include <linux/compat.h>
 
 #include <linux/uaccess.h>
+#include <linux/ima.h>
 
 #define DM_MSG_PREFIX "ioctl"
 #define DM_DRIVER_EMAIL "dm-devel@redhat.com"
@@ -347,6 +348,7 @@ retry:
                        dm_sync_table(md);
                        dm_table_destroy(t);
                }
+               dm_ima_measure_on_device_remove(md, true);
                dm_put(md);
                if (likely(keep_open_devices))
                        dm_destroy(md);
@@ -483,6 +485,9 @@ static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
                param->flags |= DM_UEVENT_GENERATED_FLAG;
 
        md = hc->md;
+
+       dm_ima_measure_on_device_rename(md);
+
        up_write(&_hash_lock);
        kfree(old_name);
 
@@ -981,6 +986,8 @@ static int dev_remove(struct file *filp, struct dm_ioctl *param, size_t param_si
 
        param->flags &= ~DM_DEFERRED_REMOVE;
 
+       dm_ima_measure_on_device_remove(md, false);
+
        if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
                param->flags |= DM_UEVENT_GENERATED_FLAG;
 
@@ -1159,8 +1166,12 @@ static int do_resume(struct dm_ioctl *param)
 
        if (dm_suspended_md(md)) {
                r = dm_resume(md);
-               if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
-                       param->flags |= DM_UEVENT_GENERATED_FLAG;
+               if (!r) {
+                       dm_ima_measure_on_device_resume(md, new_map ? true : false);
+
+                       if (!dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
+                               param->flags |= DM_UEVENT_GENERATED_FLAG;
+               }
        }
 
        /*
@@ -1224,6 +1235,8 @@ static void retrieve_status(struct dm_table *table,
 
        if (param->flags & DM_STATUS_TABLE_FLAG)
                type = STATUSTYPE_TABLE;
+       else if (param->flags & DM_IMA_MEASUREMENT_FLAG)
+               type = STATUSTYPE_IMA;
        else
                type = STATUSTYPE_INFO;
 
@@ -1425,6 +1438,8 @@ static int table_load(struct file *filp, struct dm_ioctl *param, size_t param_si
        if (r)
                goto err_unlock_md_type;
 
+       dm_ima_measure_on_table_load(t, STATUSTYPE_IMA);
+
        immutable_target_type = dm_get_immutable_target_type(md);
        if (immutable_target_type &&
            (immutable_target_type != dm_table_get_immutable_target_type(t)) &&
@@ -1436,9 +1451,6 @@ static int table_load(struct file *filp, struct dm_ioctl *param, size_t param_si
        }
 
        if (dm_get_md_type(md) == DM_TYPE_NONE) {
-               /* Initial table load: acquire type of table. */
-               dm_set_md_type(md, dm_table_get_type(t));
-
                /* setup md->queue to reflect md's type (may block) */
                r = dm_setup_md_queue(md, t);
                if (r) {
@@ -1496,6 +1508,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
        struct hash_cell *hc;
        struct mapped_device *md;
        struct dm_table *old_map = NULL;
+       bool has_new_map = false;
 
        down_write(&_hash_lock);
 
@@ -1509,6 +1522,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
        if (hc->new_map) {
                old_map = hc->new_map;
                hc->new_map = NULL;
+               has_new_map = true;
        }
 
        param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
@@ -1520,6 +1534,7 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
                dm_sync_table(md);
                dm_table_destroy(old_map);
        }
+       dm_ima_measure_on_table_clear(md, has_new_map);
        dm_put(md);
 
        return 0;
@@ -2187,7 +2202,6 @@ int __init dm_early_create(struct dm_ioctl *dmi,
        if (r)
                goto err_destroy_table;
 
-       md->type = dm_table_get_type(t);
        /* setup md->queue to reflect md's type (may block) */
        r = dm_setup_md_queue(md, t);
        if (r) {