]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RISC-V: KVM: Enable ring-based dirty memory tracking
authorQuan Zhou <zhouquan@iscas.ac.cn>
Fri, 13 Jun 2025 11:29:57 +0000 (19:29 +0800)
committerAnup Patel <anup@brainfault.org>
Mon, 28 Jul 2025 16:58:22 +0000 (22:28 +0530)
Enable ring-based dirty memory tracking on riscv:

- Enable CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL as riscv is weakly
  ordered.
- Set KVM_DIRTY_LOG_PAGE_OFFSET for the ring buffer's physical page
  offset.
- Add a check to kvm_vcpu_kvm_riscv_check_vcpu_requests for checking
  whether the dirty ring is soft full.

To handle vCPU requests that cause exits to userspace, modified the
`kvm_riscv_check_vcpu_requests` to return a value (currently only
returns 0 or 1).

Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20e116efb1f7aff211dd8e3cf8990c5521ed5f34.1749810735.git.zhouquan@iscas.ac.cn
Signed-off-by: Anup Patel <anup@brainfault.org>
Documentation/virt/kvm/api.rst
arch/riscv/include/uapi/asm/kvm.h
arch/riscv/kvm/Kconfig
arch/riscv/kvm/vcpu.c

index 9abf93ee5f65adf01af5ecc21560821eb6253356..eea11690af0397951edc57ef7d9172bd73104679 100644 (file)
@@ -8373,7 +8373,7 @@ core crystal clock frequency, if a non-zero CPUID 0x15 is exposed to the guest.
 7.36 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL
 ----------------------------------------------------------
 
-:Architectures: x86, arm64
+:Architectures: x86, arm64, riscv
 :Type: vm
 :Parameters: args[0] - size of the dirty log ring
 
index 5f59fd226cc57af811706c4705fee12eafcc7d08..ef27d4289da1186d1f9e1f18daf65769e1927d67 100644 (file)
@@ -18,6 +18,7 @@
 #define __KVM_HAVE_IRQ_LINE
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+#define KVM_DIRTY_LOG_PAGE_OFFSET 64
 
 #define KVM_INTERRUPT_SET      -1U
 #define KVM_INTERRUPT_UNSET    -2U
index 704c2899197ea6e4d780409d80ea262822d44de1..5a62091b08090b308eef08f9cba68ab1d2ae3827 100644 (file)
@@ -25,6 +25,7 @@ config KVM
        select HAVE_KVM_MSI
        select HAVE_KVM_VCPU_ASYNC_IOCTL
        select HAVE_KVM_READONLY_MEM
+       select HAVE_KVM_DIRTY_RING_ACQ_REL
        select KVM_COMMON
        select KVM_GENERIC_DIRTYLOG_READ_PROTECT
        select KVM_GENERIC_HARDWARE_ENABLING
index ef266d7bbc31fb85872d57afa04dd789963fb6e3..f001e56403f9fa9aeb54cec06ee7631a49401d7d 100644 (file)
@@ -682,7 +682,14 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
        }
 }
 
-static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
+/**
+ * check_vcpu_requests - check and handle pending vCPU requests
+ * @vcpu:      the VCPU pointer
+ *
+ * Return: 1 if we should enter the guest
+ *         0 if we should exit to userspace
+ */
+static int kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
 {
        struct rcuwait *wait = kvm_arch_vcpu_get_wait(vcpu);
 
@@ -723,7 +730,12 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
 
                if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu))
                        kvm_riscv_vcpu_record_steal_time(vcpu);
+
+               if (kvm_dirty_ring_check_request(vcpu))
+                       return 0;
        }
+
+       return 1;
 }
 
 static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)
@@ -905,7 +917,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
                kvm_riscv_gstage_vmid_update(vcpu);
 
-               kvm_riscv_check_vcpu_requests(vcpu);
+               ret = kvm_riscv_check_vcpu_requests(vcpu);
+               if (ret <= 0)
+                       continue;
 
                preempt_disable();