Commit a23eaf93 authored by Gavin Shan's avatar Gavin Shan Committed by Marc Zyngier

KVM: arm64: Add helper vgic_write_guest_lock()

Currently, the unknown no-running-vcpu sites are reported when a
dirty page is tracked by mark_page_dirty_in_slot(). Until now, the
only known no-running-vcpu site is saving vgic/its tables through
KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} command on KVM device
"kvm-arm-vgic-its". Unfortunately, there are more unknown sites to
be handled and no-running-vcpu context will be allowed in these
sites: (1) KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_RESTORE_TABLES} command
on KVM device "kvm-arm-vgic-its" to restore vgic/its tables. The
vgic3 LPI pending status could be restored. (2) Save vgic3 pending
table through KVM_DEV_ARM_{VGIC_GRP_CTRL, VGIC_SAVE_PENDING_TABLES}
command on KVM device "kvm-arm-vgic-v3".

In order to handle those unknown cases, we need a unified helper
vgic_write_guest_lock(). struct vgic_dist::save_its_tables_in_progress
is also renamed to struct vgic_dist::save_tables_in_progress.

No functional change intended.
Suggested-by: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarGavin Shan <gshan@redhat.com>
Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230126235451.469087-3-gshan@redhat.com
parent ef369168
...@@ -2187,7 +2187,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev, ...@@ -2187,7 +2187,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) | ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
ite->collection->collection_id; ite->collection->collection_id;
val = cpu_to_le64(val); val = cpu_to_le64(val);
return kvm_write_guest_lock(kvm, gpa, &val, ite_esz); return vgic_write_guest_lock(kvm, gpa, &val, ite_esz);
} }
/** /**
...@@ -2339,7 +2339,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev, ...@@ -2339,7 +2339,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
(itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) | (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
(dev->num_eventid_bits - 1)); (dev->num_eventid_bits - 1));
val = cpu_to_le64(val); val = cpu_to_le64(val);
return kvm_write_guest_lock(kvm, ptr, &val, dte_esz); return vgic_write_guest_lock(kvm, ptr, &val, dte_esz);
} }
/** /**
...@@ -2526,7 +2526,7 @@ static int vgic_its_save_cte(struct vgic_its *its, ...@@ -2526,7 +2526,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) | ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
collection->collection_id); collection->collection_id);
val = cpu_to_le64(val); val = cpu_to_le64(val);
return kvm_write_guest_lock(its->dev->kvm, gpa, &val, esz); return vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz);
} }
/* /*
...@@ -2607,7 +2607,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its) ...@@ -2607,7 +2607,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
*/ */
val = 0; val = 0;
BUG_ON(cte_esz > sizeof(val)); BUG_ON(cte_esz > sizeof(val));
ret = kvm_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz); ret = vgic_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
return ret; return ret;
} }
...@@ -2743,7 +2743,6 @@ static int vgic_its_has_attr(struct kvm_device *dev, ...@@ -2743,7 +2743,6 @@ static int vgic_its_has_attr(struct kvm_device *dev,
static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr) 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); const struct vgic_its_abi *abi = vgic_its_get_abi(its);
struct vgic_dist *dist = &kvm->arch.vgic;
int ret = 0; int ret = 0;
if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */ if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */
...@@ -2763,9 +2762,7 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr) ...@@ -2763,9 +2762,7 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
vgic_its_reset(kvm, its); vgic_its_reset(kvm, its);
break; break;
case KVM_DEV_ARM_ITS_SAVE_TABLES: case KVM_DEV_ARM_ITS_SAVE_TABLES:
dist->save_its_tables_in_progress = true;
ret = abi->save_tables(its); ret = abi->save_tables(its);
dist->save_its_tables_in_progress = false;
break; break;
case KVM_DEV_ARM_ITS_RESTORE_TABLES: case KVM_DEV_ARM_ITS_RESTORE_TABLES:
ret = abi->restore_tables(its); ret = abi->restore_tables(its);
...@@ -2792,7 +2789,7 @@ bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm) ...@@ -2792,7 +2789,7 @@ bool kvm_arch_allow_write_without_running_vcpu(struct kvm *kvm)
{ {
struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_dist *dist = &kvm->arch.vgic;
return dist->save_its_tables_in_progress; return dist->table_write_in_progress;
} }
static int vgic_its_set_attr(struct kvm_device *dev, static int vgic_its_set_attr(struct kvm_device *dev,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define __KVM_ARM_VGIC_NEW_H__ #define __KVM_ARM_VGIC_NEW_H__
#include <linux/irqchip/arm-gic-common.h> #include <linux/irqchip/arm-gic-common.h>
#include <asm/kvm_mmu.h>
#define PRODUCT_ID_KVM 0x4b /* ASCII code K */ #define PRODUCT_ID_KVM 0x4b /* ASCII code K */
#define IMPLEMENTER_ARM 0x43b #define IMPLEMENTER_ARM 0x43b
...@@ -131,6 +132,19 @@ static inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq) ...@@ -131,6 +132,19 @@ static inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq)
return vgic_irq_get_lr_count(irq) > 1; return vgic_irq_get_lr_count(irq) > 1;
} }
static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa,
const void *data, unsigned long len)
{
struct vgic_dist *dist = &kvm->arch.vgic;
int ret;
dist->table_write_in_progress = true;
ret = kvm_write_guest_lock(kvm, gpa, data, len);
dist->table_write_in_progress = false;
return ret;
}
/* /*
* This struct provides an intermediate representation of the fields contained * This struct provides an intermediate representation of the fields contained
* in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
......
...@@ -263,7 +263,7 @@ struct vgic_dist { ...@@ -263,7 +263,7 @@ struct vgic_dist {
struct vgic_io_device dist_iodev; struct vgic_io_device dist_iodev;
bool has_its; bool has_its;
bool save_its_tables_in_progress; bool table_write_in_progress;
/* /*
* Contains the attributes and gpa of the LPI configuration table. * Contains the attributes and gpa of the LPI configuration table.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment