From de73708915adc1b3f05e617a86da6b2d68fae141 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 21 Jun 2018 10:43:59 +0100 Subject: KVM: arm/arm64: Enable adaptative WFE trapping Trapping blocking WFE is extremely beneficial in situations where the system is oversubscribed, as it allows another thread to run while being blocked. In a non-oversubscribed environment, this is the complete opposite, and trapping WFE is just unnecessary overhead. Let's only enable WFE trapping if the CPU has more than a single task to run (that is, more than just the vcpu thread). Reviewed-by: Christoffer Dall Signed-off-by: Marc Zyngier --- virt/kvm/arm/arm.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'virt/kvm/arm/arm.c') diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 04e554cae3a2..8e66b89a3db2 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -380,6 +381,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_timer_vcpu_load(vcpu); kvm_vcpu_load_sysregs(vcpu); kvm_arch_vcpu_load_fp(vcpu); + + if (single_task_running()) + vcpu_clear_wfe_traps(vcpu); + else + vcpu_set_wfe_traps(vcpu); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) -- cgit From b7b27facc7b50a5fce0afaa3df56157136ce181a Mon Sep 17 00:00:00 2001 From: Dongjiu Geng Date: Thu, 19 Jul 2018 16:24:22 +0100 Subject: arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS For the migrating VMs, user space may need to know the exception state. For example, in the machine A, KVM make an SError pending, when migrate to B, KVM also needs to pend an SError. This new IOCTL exports user-invisible states related to SError. Together with appropriate user space changes, user space can get/set the SError exception state to do migrate/snapshot/suspend. Signed-off-by: Dongjiu Geng Reviewed-by: James Morse [expanded documentation wording] Signed-off-by: James Morse Signed-off-by: Marc Zyngier --- virt/kvm/arm/arm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'virt/kvm/arm/arm.c') diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 8e66b89a3db2..1c72247aeb1d 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -1130,6 +1130,27 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_arm_vcpu_has_attr(vcpu, &attr); break; } +#ifdef __KVM_HAVE_VCPU_EVENTS + case KVM_GET_VCPU_EVENTS: { + struct kvm_vcpu_events events; + + if (kvm_arm_vcpu_get_events(vcpu, &events)) + return -EINVAL; + + if (copy_to_user(argp, &events, sizeof(events))) + return -EFAULT; + + return 0; + } + case KVM_SET_VCPU_EVENTS: { + struct kvm_vcpu_events events; + + if (copy_from_user(&events, argp, sizeof(events))) + return -EFAULT; + + return kvm_arm_vcpu_set_events(vcpu, &events); + } +#endif default: r = -EINVAL; } -- cgit From 539aee0edb9fdc8f465e3843c261acc88c47d8ee Mon Sep 17 00:00:00 2001 From: James Morse Date: Thu, 19 Jul 2018 16:24:24 +0100 Subject: KVM: arm64: Share the parts of get/set events useful to 32bit The get/set events helpers to do some work to check reserved and padding fields are zero. This is useful on 32bit too. Move this code into virt/kvm/arm/arm.c, and give the arch code some underscores. This is temporarily hidden behind __KVM_HAVE_VCPU_EVENTS until 32bit is wired up. Signed-off-by: James Morse Reviewed-by: Dongjiu Geng Signed-off-by: Marc Zyngier --- virt/kvm/arm/arm.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'virt/kvm/arm/arm.c') diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 1c72247aeb1d..14f8fad1c7ae 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -1050,6 +1050,34 @@ static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu, return ret; } +#ifdef __KVM_HAVE_VCPU_EVENTS /* temporary: until 32bit is wired up */ +static int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu, + struct kvm_vcpu_events *events) +{ + memset(events, 0, sizeof(*events)); + + return __kvm_arm_vcpu_get_events(vcpu, events); +} + +static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu, + struct kvm_vcpu_events *events) +{ + int i; + + /* check whether the reserved field is zero */ + for (i = 0; i < ARRAY_SIZE(events->reserved); i++) + if (events->reserved[i]) + return -EINVAL; + + /* check whether the pad field is zero */ + for (i = 0; i < ARRAY_SIZE(events->exception.pad); i++) + if (events->exception.pad[i]) + return -EINVAL; + + return __kvm_arm_vcpu_set_events(vcpu, events); +} +#endif /* __KVM_HAVE_VCPU_EVENTS */ + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { -- cgit From b0960b9569db6b2fe8a75967d47b9dcdeb44016b Mon Sep 17 00:00:00 2001 From: James Morse Date: Thu, 19 Jul 2018 16:24:25 +0100 Subject: KVM: arm: Add 32bit get/set events support arm64's new use of KVMs get_events/set_events API calls isn't just or RAS, it allows an SError that has been made pending by KVM as part of its device emulation to be migrated. Wire this up for 32bit too. We only need to read/write the HCR_VA bit, and check that no esr has been provided, as we don't yet support VDFSR. Signed-off-by: James Morse Reviewed-by: Dongjiu Geng Signed-off-by: Marc Zyngier --- virt/kvm/arm/arm.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'virt/kvm/arm/arm.c') diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 14f8fad1c7ae..ac658bd63196 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c @@ -1050,7 +1050,6 @@ static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu, return ret; } -#ifdef __KVM_HAVE_VCPU_EVENTS /* temporary: until 32bit is wired up */ static int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events) { @@ -1076,7 +1075,6 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu, return __kvm_arm_vcpu_set_events(vcpu, events); } -#endif /* __KVM_HAVE_VCPU_EVENTS */ long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) @@ -1158,7 +1156,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = kvm_arm_vcpu_has_attr(vcpu, &attr); break; } -#ifdef __KVM_HAVE_VCPU_EVENTS case KVM_GET_VCPU_EVENTS: { struct kvm_vcpu_events events; @@ -1178,7 +1175,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp, return kvm_arm_vcpu_set_events(vcpu, &events); } -#endif default: r = -EINVAL; } -- cgit