Commit 9cb1096f authored by Gavin Shan's avatar Gavin Shan Committed by Marc Zyngier
Browse files

KVM: arm64: Enable ring-based dirty memory tracking



Enable ring-based dirty memory tracking on ARM64:

  - Enable CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL.

  - Enable CONFIG_NEED_KVM_DIRTY_RING_WITH_BITMAP.

  - Set KVM_DIRTY_LOG_PAGE_OFFSET for the ring buffer's physical page
    offset.

  - Add ARM64 specific kvm_arch_allow_write_without_running_vcpu() to
    keep the site of saving vgic/its tables out of the no-running-vcpu
    radar.

Signed-off-by: default avatarGavin Shan <gshan@redhat.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221110104914.31280-5-gshan@redhat.com
parent 86bdf3eb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7921,7 +7921,7 @@ regardless of what has actually been exposed through the CPUID leaf.
8.29 KVM_CAP_DIRTY_LOG_RING/KVM_CAP_DIRTY_LOG_RING_ACQ_REL
----------------------------------------------------------

:Architectures: x86
:Architectures: x86, arm64
:Parameters: args[0] - size of the dirty log ring

KVM is capable of tracking dirty memory using ring buffers that are
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#define __KVM_HAVE_VCPU_EVENTS

#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_DIRTY_LOG_PAGE_OFFSET 64

#define KVM_REG_SIZE(id)						\
	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ menuconfig KVM
	select KVM_VFIO
	select HAVE_KVM_EVENTFD
	select HAVE_KVM_IRQFD
	select HAVE_KVM_DIRTY_RING_ACQ_REL
	select NEED_KVM_DIRTY_RING_WITH_BITMAP
	select HAVE_KVM_MSI
	select HAVE_KVM_IRQCHIP
	select HAVE_KVM_IRQ_ROUTING
+3 −0
Original line number Diff line number Diff line
@@ -746,6 +746,9 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)

		if (kvm_check_request(KVM_REQ_SUSPEND, vcpu))
			return kvm_vcpu_suspend(vcpu);

		if (kvm_dirty_ring_check_request(vcpu))
			return 0;
	}

	return 1;
+20 −0
Original line number Diff line number Diff line
@@ -2743,6 +2743,7 @@ static int vgic_its_has_attr(struct kvm_device *dev,
static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
{
	const struct vgic_its_abi *abi = vgic_its_get_abi(its);
	struct vgic_dist *dist = &kvm->arch.vgic;
	int ret = 0;

	if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */
@@ -2762,7 +2763,9 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
		vgic_its_reset(kvm, its);
		break;
	case KVM_DEV_ARM_ITS_SAVE_TABLES:
		dist->save_its_tables_in_progress = true;
		ret = abi->save_tables(its);
		dist->save_its_tables_in_progress = false;
		break;
	case KVM_DEV_ARM_ITS_RESTORE_TABLES:
		ret = abi->restore_tables(its);
@@ -2775,6 +2778,23 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
	return ret;
}

/*
 * kvm_arch_allow_write_without_running_vcpu - allow writing guest memory
 * without the running VCPU when dirty ring is enabled.
 *
 * The running VCPU is required to track dirty guest pages when dirty ring
 * is enabled. Otherwise, the backup bitmap should be used to track the
 * dirty guest pages. When vgic/its tables are being saved, the backup
 * bitmap is used to track the dirty guest pages due to the missed running
 * VCPU in the period.
 */
bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm)
{
	struct vgic_dist *dist = &kvm->arch.vgic;

	return dist->save_its_tables_in_progress;
}

static int vgic_its_set_attr(struct kvm_device *dev,
			     struct kvm_device_attr *attr)
{
Loading