Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Browse files Browse the repository at this point in the history
Pull more kvm updates from Paolo Bonzini:

 - ARM fixes

 - RISC-V Svade and Svadu (accessed and dirty bit) extension support for
   host and guest

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list test
  RISC-V: KVM: Add Svade and Svadu Extensions Support for Guest/VM
  dt-bindings: riscv: Add Svade and Svadu Entries
  RISC-V: Add Svade and Svadu Extensions Support
  KVM: arm64: Use MDCR_EL2.HPME to evaluate overflow of hyp counters
  KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
  KVM: arm64: Mark set_sysreg_masks() as inline to avoid build failure
  KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes
  KVM: arm64: vgic: Kill VGIC_MAX_PRIVATE definition
  KVM: arm64: vgic: Make vgic_get_irq() more robust
  KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR
  • Loading branch information
torvalds committed Nov 30, 2024
2 parents 0ff86d8 + 4d911c7 commit c4bb3a2
Show file tree
Hide file tree
Showing 24 changed files with 257 additions and 119 deletions.
28 changes: 28 additions & 0 deletions Documentation/devicetree/bindings/riscv/extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,34 @@ properties:
ratified at commit 3f9ed34 ("Add ability to manually trigger
workflow. (#2)") of riscv-time-compare.
- const: svade
description: |
The standard Svade supervisor-level extension for SW-managed PTE A/D
bit updates as ratified in the 20240213 version of the privileged
ISA specification.
Both Svade and Svadu extensions control the hardware behavior when
the PTE A/D bits need to be set. The default behavior for the four
possible combinations of these extensions in the device tree are:
1) Neither Svade nor Svadu present in DT => It is technically
unknown whether the platform uses Svade or Svadu. Supervisor
software should be prepared to handle either hardware updating
of the PTE A/D bits or page faults when they need updated.
2) Only Svade present in DT => Supervisor must assume Svade to be
always enabled.
3) Only Svadu present in DT => Supervisor must assume Svadu to be
always enabled.
4) Both Svade and Svadu present in DT => Supervisor must assume
Svadu turned-off at boot time. To use Svadu, supervisor must
explicitly enable it using the SBI FWFT extension.
- const: svadu
description: |
The standard Svadu supervisor-level extension for hardware updating
of PTE A/D bits as ratified in the 20240528 version of the
privileged ISA specification. Please refer to Svade dt-binding
description for more details.
- const: svinval
description:
The standard Svinval supervisor-level extension for fine-grained
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kvm/nested.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *vcpu,
return v;
}

static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
static __always_inline void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
{
int i = sr - __SANITISED_REG_START__;

Expand Down
62 changes: 45 additions & 17 deletions arch/arm64/kvm/pmu-emul.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,23 @@ void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu)
irq_work_sync(&vcpu->arch.pmu.overflow_work);
}

bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx)
static u64 kvm_pmu_hyp_counter_mask(struct kvm_vcpu *vcpu)
{
unsigned int hpmn;
unsigned int hpmn, n;

if (!vcpu_has_nv(vcpu) || idx == ARMV8_PMU_CYCLE_IDX)
return false;
if (!vcpu_has_nv(vcpu))
return 0;

hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2));
n = vcpu->kvm->arch.pmcr_n;

/*
* Programming HPMN to a value greater than PMCR_EL0.N is
* CONSTRAINED UNPREDICTABLE. Make the implementation choice that an
* UNKNOWN number of counters (in our case, zero) are reserved for EL2.
*/
if (hpmn >= n)
return 0;

/*
* Programming HPMN=0 is CONSTRAINED UNPREDICTABLE if FEAT_HPMN0 isn't
Expand All @@ -288,20 +299,22 @@ bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx)
* implementation choice that all counters are included in the second
* range reserved for EL2/EL3.
*/
hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2));
return idx >= hpmn;
return GENMASK(n - 1, hpmn);
}

bool kvm_pmu_counter_is_hyp(struct kvm_vcpu *vcpu, unsigned int idx)
{
return kvm_pmu_hyp_counter_mask(vcpu) & BIT(idx);
}

u64 kvm_pmu_accessible_counter_mask(struct kvm_vcpu *vcpu)
{
u64 mask = kvm_pmu_implemented_counter_mask(vcpu);
u64 hpmn;

if (!vcpu_has_nv(vcpu) || vcpu_is_el2(vcpu))
return mask;

hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2));
return mask & ~GENMASK(vcpu->kvm->arch.pmcr_n - 1, hpmn);
return mask & ~kvm_pmu_hyp_counter_mask(vcpu);
}

u64 kvm_pmu_implemented_counter_mask(struct kvm_vcpu *vcpu)
Expand Down Expand Up @@ -375,15 +388,30 @@ void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val)
}
}

static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
/*
* Returns the PMU overflow state, which is true if there exists an event
* counter where the values of the global enable control, PMOVSSET_EL0[n], and
* PMINTENSET_EL1[n] are all 1.
*/
static bool kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
{
u64 reg = 0;
u64 reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);

if ((kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E)) {
reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
}
reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);

/*
* PMCR_EL0.E is the global enable control for event counters available
* to EL0 and EL1.
*/
if (!(kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E))
reg &= kvm_pmu_hyp_counter_mask(vcpu);

/*
* Otherwise, MDCR_EL2.HPME is the global enable control for event
* counters reserved for EL2.
*/
if (!(vcpu_read_sys_reg(vcpu, MDCR_EL2) & MDCR_EL2_HPME))
reg &= ~kvm_pmu_hyp_counter_mask(vcpu);

return reg;
}
Expand All @@ -396,7 +424,7 @@ static void kvm_pmu_update_state(struct kvm_vcpu *vcpu)
if (!kvm_vcpu_has_pmu(vcpu))
return;

overflow = !!kvm_pmu_overflow_status(vcpu);
overflow = kvm_pmu_overflow_status(vcpu);
if (pmu->irq_level == overflow)
return;

Expand Down
5 changes: 4 additions & 1 deletion arch/arm64/kvm/vgic/vgic-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ static int vgic_debug_show(struct seq_file *s, void *v)
* Expect this to succeed, as iter_mark_lpis() takes a reference on
* every LPI to be visited.
*/
irq = vgic_get_irq(kvm, vcpu, iter->intid);
if (iter->intid < VGIC_NR_PRIVATE_IRQS)
irq = vgic_get_vcpu_irq(vcpu, iter->intid);
else
irq = vgic_get_irq(kvm, iter->intid);
if (WARN_ON_ONCE(!irq))
return -EINVAL;

Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kvm/vgic/vgic-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ int vgic_init(struct kvm *kvm)
goto out;

for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) {
struct vgic_irq *irq = vgic_get_irq(kvm, vcpu, i);
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i);

switch (dist->vgic_model) {
case KVM_DEV_TYPE_ARM_VGIC_V3:
Expand Down
Loading

0 comments on commit c4bb3a2

Please sign in to comment.