diff options
author | Bibo Mao <maobibo@loongson.cn> | 2024-07-09 16:25:51 +0800 |
---|---|---|
committer | Huacai Chen <chenhuacai@loongson.cn> | 2024-07-09 16:25:51 +0800 |
commit | b4ba157044ea433a66126603ad7140e12dbc794b (patch) | |
tree | 57e1e54b36213e391cea34a7aebc7a9883164b76 /arch/loongarch/kvm/exit.c | |
parent | d7ad41a31d91abd01a4d9b040074d808899636ea (diff) |
LoongArch: KVM: Add PV steal time support in host side
Add ParaVirt steal time feature in host side, VM can search supported
features provided by KVM hypervisor, a feature KVM_FEATURE_STEAL_TIME
is added here. Like x86, steal time structure is saved in guest memory,
one hypercall function KVM_HCALL_FUNC_NOTIFY is added to notify KVM to
enable this feature.
One CPU attr ioctl command KVM_LOONGARCH_VCPU_PVTIME_CTRL is added to
save and restore the base address of steal time structure when a VM is
migrated.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch/kvm/exit.c')
-rw-r--r-- | arch/loongarch/kvm/exit.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index a68573e091c0..ea73f9dc2cc6 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -24,7 +24,7 @@ static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst) { int rd, rj; - unsigned int index; + unsigned int index, ret; if (inst.reg2_format.opcode != cpucfg_op) return EMULATE_FAIL; @@ -50,7 +50,10 @@ static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst) vcpu->arch.gprs[rd] = *(unsigned int *)KVM_SIGNATURE; break; case CPUCFG_KVM_FEATURE: - vcpu->arch.gprs[rd] = KVM_FEATURE_IPI; + ret = KVM_FEATURE_IPI; + if (kvm_pvtime_supported()) + ret |= KVM_FEATURE_STEAL_TIME; + vcpu->arch.gprs[rd] = ret; break; default: vcpu->arch.gprs[rd] = 0; @@ -687,6 +690,34 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu) return RESUME_GUEST; } +static long kvm_save_notify(struct kvm_vcpu *vcpu) +{ + unsigned long id, data; + + id = kvm_read_reg(vcpu, LOONGARCH_GPR_A1); + data = kvm_read_reg(vcpu, LOONGARCH_GPR_A2); + switch (id) { + case KVM_FEATURE_STEAL_TIME: + if (!kvm_pvtime_supported()) + return KVM_HCALL_INVALID_CODE; + + if (data & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID)) + return KVM_HCALL_INVALID_PARAMETER; + + vcpu->arch.st.guest_addr = data; + if (!(data & KVM_STEAL_PHYS_VALID)) + break; + + vcpu->arch.st.last_steal = current->sched_info.run_delay; + kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); + break; + default: + break; + }; + + return 0; +}; + /* * kvm_handle_lsx_disabled() - Guest used LSX while disabled in root. * @vcpu: Virtual CPU context. @@ -758,6 +789,9 @@ static void kvm_handle_service(struct kvm_vcpu *vcpu) kvm_send_pv_ipi(vcpu); ret = KVM_HCALL_SUCCESS; break; + case KVM_HCALL_FUNC_NOTIFY: + ret = kvm_save_notify(vcpu); + break; default: ret = KVM_HCALL_INVALID_CODE; break; |