matrix->adm_max = info->apxa ? info->Nd : 15;
 }
 
-static void vfio_ap_mdev_filter_cdoms(struct ap_matrix_mdev *matrix_mdev)
+static void vfio_ap_mdev_update_guest_apcb(struct ap_matrix_mdev *matrix_mdev)
 {
+       if (matrix_mdev->kvm)
+               kvm_arch_crypto_set_masks(matrix_mdev->kvm,
+                                         matrix_mdev->shadow_apcb.apm,
+                                         matrix_mdev->shadow_apcb.aqm,
+                                         matrix_mdev->shadow_apcb.adm);
+}
+
+static bool vfio_ap_mdev_filter_cdoms(struct ap_matrix_mdev *matrix_mdev)
+{
+       DECLARE_BITMAP(prev_shadow_adm, AP_DOMAINS);
+
+       bitmap_copy(prev_shadow_adm, matrix_mdev->shadow_apcb.adm, AP_DOMAINS);
        bitmap_and(matrix_mdev->shadow_apcb.adm, matrix_mdev->matrix.adm,
                   (unsigned long *)matrix_dev->info.adm, AP_DOMAINS);
+
+       return !bitmap_equal(prev_shadow_adm, matrix_mdev->shadow_apcb.adm,
+                            AP_DOMAINS);
 }
 
 /*
  *      driver, its APID will be filtered from the guest's APCB. The matrix
  *      structure precludes filtering an individual APQN, so its APID will be
  *      filtered.
+ *
+ * Return: a boolean value indicating whether the KVM guest's APCB was changed
+ *        by the filtering or not.
  */
-static void vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm,
+static bool vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm,
                                       struct ap_matrix_mdev *matrix_mdev)
 {
        int ret;
        unsigned long apid, apqi, apqn;
+       DECLARE_BITMAP(prev_shadow_apm, AP_DEVICES);
+       DECLARE_BITMAP(prev_shadow_aqm, AP_DOMAINS);
 
        ret = ap_qci(&matrix_dev->info);
        if (ret)
-               return;
+               return false;
 
+       bitmap_copy(prev_shadow_apm, matrix_mdev->shadow_apcb.apm, AP_DEVICES);
+       bitmap_copy(prev_shadow_aqm, matrix_mdev->shadow_apcb.aqm, AP_DOMAINS);
        vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->shadow_apcb);
 
        /*
                        }
                }
        }
+
+       return !bitmap_equal(prev_shadow_apm, matrix_mdev->shadow_apcb.apm,
+                            AP_DEVICES) ||
+              !bitmap_equal(prev_shadow_aqm, matrix_mdev->shadow_apcb.aqm,
+                            AP_DOMAINS);
 }
 
 static int vfio_ap_mdev_probe(struct mdev_device *mdev)
        int ret;
        unsigned long apid;
        DECLARE_BITMAP(apm_delta, AP_DEVICES);
-
        struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If the KVM guest is running, disallow assignment of adapter */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &apid);
        if (ret)
                goto done;
        vfio_ap_mdev_link_adapter(matrix_mdev, apid);
        memset(apm_delta, 0, sizeof(apm_delta));
        set_bit_inv(apid, apm_delta);
-       vfio_ap_mdev_filter_matrix(apm_delta,
-                                  matrix_mdev->matrix.aqm, matrix_mdev);
+
+       if (vfio_ap_mdev_filter_matrix(apm_delta,
+                                      matrix_mdev->matrix.aqm, matrix_mdev))
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+
        ret = count;
 done:
        release_update_locks_for_mdev(matrix_mdev);
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If the KVM guest is running, disallow unassignment of adapter */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &apid);
        if (ret)
                goto done;
        clear_bit_inv((unsigned long)apid, matrix_mdev->matrix.apm);
        vfio_ap_mdev_unlink_adapter(matrix_mdev, apid);
 
-       if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm))
+       if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm)) {
                clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+       }
 
        ret = count;
 done:
        unsigned long apqi;
        DECLARE_BITMAP(aqm_delta, AP_DOMAINS);
        struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
-       unsigned long max_apqi = matrix_mdev->matrix.aqm_max;
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If the KVM guest is running, disallow assignment of domain */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &apqi);
        if (ret)
                goto done;
-       if (apqi > max_apqi) {
+
+       if (apqi > matrix_mdev->matrix.aqm_max) {
                ret = -ENODEV;
                goto done;
        }
        vfio_ap_mdev_link_domain(matrix_mdev, apqi);
        memset(aqm_delta, 0, sizeof(aqm_delta));
        set_bit_inv(apqi, aqm_delta);
-       vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm, aqm_delta,
-                                  matrix_mdev);
+
+       if (vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm, aqm_delta,
+                                      matrix_mdev))
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+
        ret = count;
 done:
        release_update_locks_for_mdev(matrix_mdev);
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If the KVM guest is running, disallow unassignment of domain */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &apqi);
        if (ret)
                goto done;
        clear_bit_inv((unsigned long)apqi, matrix_mdev->matrix.aqm);
        vfio_ap_mdev_unlink_domain(matrix_mdev, apqi);
 
-       if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm))
+       if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
                clear_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm);
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+       }
 
        ret = count;
 
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If the KVM guest is running, disallow assignment of control domain */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &id);
        if (ret)
                goto done;
         * number of control domains that can be assigned.
         */
        set_bit_inv(id, matrix_mdev->matrix.adm);
-       vfio_ap_mdev_filter_cdoms(matrix_mdev);
+       if (vfio_ap_mdev_filter_cdoms(matrix_mdev))
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+
        ret = count;
 done:
        release_update_locks_for_mdev(matrix_mdev);
        int ret;
        unsigned long domid;
        struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
-       unsigned long max_domid =  matrix_mdev->matrix.adm_max;
 
        get_update_locks_for_mdev(matrix_mdev);
 
-       /* If a KVM guest is running, disallow unassignment of control domain */
-       if (matrix_mdev->kvm) {
-               ret = -EBUSY;
-               goto done;
-       }
-
        ret = kstrtoul(buf, 0, &domid);
        if (ret)
                goto done;
-       if (domid > max_domid) {
+
+       if (domid > matrix_mdev->matrix.adm_max) {
                ret = -ENODEV;
                goto done;
        }
 
        clear_bit_inv(domid, matrix_mdev->matrix.adm);
 
-       if (test_bit_inv(domid, matrix_mdev->shadow_apcb.adm))
+       if (test_bit_inv(domid, matrix_mdev->shadow_apcb.adm)) {
                clear_bit_inv(domid, matrix_mdev->shadow_apcb.adm);
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+       }
 
        ret = count;
 done:
 
                kvm_get_kvm(kvm);
                matrix_mdev->kvm = kvm;
-               kvm_arch_crypto_set_masks(kvm, matrix_mdev->shadow_apcb.apm,
-                                         matrix_mdev->shadow_apcb.aqm,
-                                         matrix_mdev->shadow_apcb.adm);
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 
                release_update_locks_for_kvm(kvm);
        }