Commit bd2e9513 authored by Oliver Upton's avatar Oliver Upton
Browse files

Merge branch kvm-arm64/misc into kvmarm/next



* kvm-arm64/misc:
  : Miscellaneous updates
  :
  :  - Provide a command-line parameter to statically control the WFx trap
  :    selection in KVM
  :
  :  - Make sysreg masks allocation accounted
  Revert "KVM: arm64: nv: Fix RESx behaviour of disabled FGTs with negative polarity"
  KVM: arm64: nv: Use GFP_KERNEL_ACCOUNT for sysreg_masks allocation
  KVM: arm64: nv: Fix RESx behaviour of disabled FGTs with negative polarity
  KVM: arm64: Add early_param to control WFx trapping

Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parents 83a7eefe cb52b5c8
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -2745,6 +2745,24 @@
			[KVM,ARM,EARLY] Allow use of GICv4 for direct
			injection of LPIs.

	kvm-arm.wfe_trap_policy=
			[KVM,ARM] Control when to set WFE instruction trap for
			KVM VMs. Traps are allowed but not guaranteed by the
			CPU architecture.

			trap: set WFE instruction trap

			notrap: clear WFE instruction trap

	kvm-arm.wfi_trap_policy=
			[KVM,ARM] Control when to set WFI instruction trap for
			KVM VMs. Traps are allowed but not guaranteed by the
			CPU architecture.

			trap: set WFI instruction trap

			notrap: clear WFI instruction trap

	kvm_cma_resv_ratio=n [PPC,EARLY]
			Reserves given percentage from system memory area for
			contiguous memory allocation for KVM hash pagetable
+65 −3
Original line number Diff line number Diff line
@@ -48,6 +48,15 @@

static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;

enum kvm_wfx_trap_policy {
	KVM_WFX_NOTRAP_SINGLE_TASK, /* Default option */
	KVM_WFX_NOTRAP,
	KVM_WFX_TRAP,
};

static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;
static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK;

DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);

DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
@@ -546,6 +555,24 @@ static void vcpu_set_pauth_traps(struct kvm_vcpu *vcpu)
	}
}

static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu)
{
	if (unlikely(kvm_wfi_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
		return kvm_wfi_trap_policy == KVM_WFX_NOTRAP;

	return single_task_running() &&
	       (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) ||
		vcpu->kvm->arch.vgic.nassgireq);
}

static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu *vcpu)
{
	if (unlikely(kvm_wfe_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
		return kvm_wfe_trap_policy == KVM_WFX_NOTRAP;

	return single_task_running();
}

void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
	struct kvm_s2_mmu *mmu;
@@ -579,10 +606,15 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
	if (kvm_arm_is_pvtime_enabled(&vcpu->arch))
		kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);

	if (single_task_running())
		vcpu_clear_wfx_traps(vcpu);
	if (kvm_vcpu_should_clear_twe(vcpu))
		vcpu->arch.hcr_el2 &= ~HCR_TWE;
	else
		vcpu->arch.hcr_el2 |= HCR_TWE;

	if (kvm_vcpu_should_clear_twi(vcpu))
		vcpu->arch.hcr_el2 &= ~HCR_TWI;
	else
		vcpu_set_wfx_traps(vcpu);
		vcpu->arch.hcr_el2 |= HCR_TWI;

	vcpu_set_pauth_traps(vcpu);

@@ -2858,6 +2890,36 @@ static int __init early_kvm_mode_cfg(char *arg)
}
early_param("kvm-arm.mode", early_kvm_mode_cfg);

static int __init early_kvm_wfx_trap_policy_cfg(char *arg, enum kvm_wfx_trap_policy *p)
{
	if (!arg)
		return -EINVAL;

	if (strcmp(arg, "trap") == 0) {
		*p = KVM_WFX_TRAP;
		return 0;
	}

	if (strcmp(arg, "notrap") == 0) {
		*p = KVM_WFX_NOTRAP;
		return 0;
	}

	return -EINVAL;
}

static int __init early_kvm_wfi_trap_policy_cfg(char *arg)
{
	return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfi_trap_policy);
}
early_param("kvm-arm.wfi_trap_policy", early_kvm_wfi_trap_policy_cfg);

static int __init early_kvm_wfe_trap_policy_cfg(char *arg)
{
	return early_kvm_wfx_trap_policy_cfg(arg, &kvm_wfe_trap_policy);
}
early_param("kvm-arm.wfe_trap_policy", early_kvm_wfe_trap_policy_cfg);

enum kvm_mode kvm_get_mode(void)
{
	return kvm_mode;
+1 −1
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
		goto out;

	kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
					 GFP_KERNEL);
					 GFP_KERNEL_ACCOUNT);
	if (!kvm->arch.sysreg_masks) {
		ret = -ENOMEM;
		goto out;