its_mask_encode(&cmd->raw_cmd[1], vpe_db_lpi, 31, 0);
 }
 
+static void its_encode_vmovp_default_db(struct its_cmd_block *cmd,
+                                       u32 vpe_db_lpi)
+{
+       its_mask_encode(&cmd->raw_cmd[3], vpe_db_lpi, 31, 0);
+}
+
+static void its_encode_db(struct its_cmd_block *cmd, bool db)
+{
+       its_mask_encode(&cmd->raw_cmd[2], db, 63, 63);
+}
+
 static inline void its_fixup_cmd(struct its_cmd_block *cmd)
 {
        /* Let's fixup BE commands */
        its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
        its_encode_target(cmd, target);
 
+       if (is_v4_1(its)) {
+               its_encode_db(cmd, true);
+               its_encode_vmovp_default_db(cmd, desc->its_vmovp_cmd.vpe->vpe_db_lpi);
+       }
+
        its_fixup_cmd(cmd);
 
        return valid_vpe(its, desc->its_vmovp_cmd.vpe);
                                bool force)
 {
        struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
-       int cpu = cpumask_first(mask_val);
+       int from, cpu = cpumask_first(mask_val);
 
        /*
         * Changing affinity is mega expensive, so let's be as lazy as
         * into the proxy device, we need to move the doorbell
         * interrupt to its new location.
         */
-       if (vpe->col_idx != cpu) {
-               int from = vpe->col_idx;
+       if (vpe->col_idx == cpu)
+               goto out;
 
-               vpe->col_idx = cpu;
-               its_send_vmovp(vpe);
-               its_vpe_db_proxy_move(vpe, from, cpu);
-       }
+       from = vpe->col_idx;
+       vpe->col_idx = cpu;
+
+       /*
+        * GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD
+        * is sharing its VPE table with the current one.
+        */
+       if (gic_data_rdist_cpu(cpu)->vpe_table_mask &&
+           cpumask_test_cpu(from, gic_data_rdist_cpu(cpu)->vpe_table_mask))
+               goto out;
 
+       its_send_vmovp(vpe);
+       its_vpe_db_proxy_move(vpe, from, cpu);
+
+out:
        irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
        return IRQ_SET_MASK_OK_DONE;