Commit 25b72cf7 authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvmarm-fixes-6.2-3' of...

Merge tag 'kvmarm-fixes-6.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.2, take #3

- Yet another fix for non-CPU accesses to the memory backing
  the VGICv3 subsystem

- A set of fixes for the setlftest checking for the S1PTW
  behaviour after the fix that went in ealier in the cycle
parents c2c46b10 08ddbbdf
...@@ -8070,9 +8070,13 @@ considering the state as complete. VMM needs to ensure that the dirty ...@@ -8070,9 +8070,13 @@ considering the state as complete. VMM needs to ensure that the dirty
state is final and avoid missing dirty pages from another ioctl ordered state is final and avoid missing dirty pages from another ioctl ordered
after the bitmap collection. after the bitmap collection.
NOTE: One example of using the backup bitmap is saving arm64 vgic/its NOTE: Multiple examples of using the backup bitmap: (1) save vgic/its
tables through KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} command on tables through command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_SAVE_TABLES} on
KVM device "kvm-arm-vgic-its" when dirty ring is enabled. KVM device "kvm-arm-vgic-its". (2) restore vgic/its tables through
command KVM_DEV_ARM_{VGIC_GRP_CTRL, ITS_RESTORE_TABLES} on KVM device
"kvm-arm-vgic-its". VGICv3 LPI pending status is restored. (3) save
vgic3 pending table through KVM_DEV_ARM_VGIC_{GRP_CTRL, SAVE_PENDING_TABLES}
command on KVM device "kvm-arm-vgic-v3".
8.30 KVM_CAP_XEN_HVM 8.30 KVM_CAP_XEN_HVM
-------------------- --------------------
......
...@@ -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,
......
...@@ -339,7 +339,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) ...@@ -339,7 +339,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq)
if (status) { if (status) {
/* clear consumed data */ /* clear consumed data */
val &= ~(1 << bit_nr); val &= ~(1 << bit_nr);
ret = kvm_write_guest_lock(kvm, ptr, &val, 1); ret = vgic_write_guest_lock(kvm, ptr, &val, 1);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -434,7 +434,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) ...@@ -434,7 +434,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
else else
val &= ~(1 << bit_nr); val &= ~(1 << bit_nr);
ret = kvm_write_guest_lock(kvm, ptr, &val, 1); ret = vgic_write_guest_lock(kvm, ptr, &val, 1);
if (ret) if (ret)
goto out; goto out;
} }
......
...@@ -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