aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2014-10-16 11:00:18 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2014-12-13 08:15:27 -0500
commitcf5d318865e25f887d49a0c6083bbc6dcd1905b1 (patch)
treeb7576479421357172188c4a2bedf9a80af55de5d
parentf7fa034dc8559c7d7326bfc8bd1a26175abd931a (diff)
arm/arm64: KVM: Turn off vcpus on PSCI shutdown/reboot
When a vcpu calls SYSTEM_OFF or SYSTEM_RESET with PSCI v0.2, the vcpus should really be turned off for the VM adhering to the suggestions in the PSCI spec, and it's the sane thing to do. Also, clarify the behavior and expectations for exits to user space with the KVM_EXIT_SYSTEM_EVENT case. Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--Documentation/virtual/kvm/api.txt9
-rw-r--r--arch/arm/kvm/psci.c18
-rw-r--r--arch/arm64/include/asm/kvm_host.h1
3 files changed, 28 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 81f1b974c06a..228f9cf5a5b5 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2957,6 +2957,15 @@ HVC instruction based PSCI call from the vcpu. The 'type' field describes
2957the system-level event type. The 'flags' field describes architecture 2957the system-level event type. The 'flags' field describes architecture
2958specific flags for the system-level event. 2958specific flags for the system-level event.
2959 2959
2960Valid values for 'type' are:
2961 KVM_SYSTEM_EVENT_SHUTDOWN -- the guest has requested a shutdown of the
2962 VM. Userspace is not obliged to honour this, and if it does honour
2963 this does not need to destroy the VM synchronously (ie it may call
2964 KVM_RUN again before shutdown finally occurs).
2965 KVM_SYSTEM_EVENT_RESET -- the guest has requested a reset of the VM.
2966 As with SHUTDOWN, userspace can choose to ignore the request, or
2967 to schedule the reset to occur in the future and may call KVM_RUN again.
2968
2960 /* Fix the size of the union. */ 2969 /* Fix the size of the union. */
2961 char padding[256]; 2970 char padding[256];
2962 }; 2971 };
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 09cf37737ee2..58cb3248d277 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -15,6 +15,7 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18#include <linux/preempt.h>
18#include <linux/kvm_host.h> 19#include <linux/kvm_host.h>
19#include <linux/wait.h> 20#include <linux/wait.h>
20 21
@@ -166,6 +167,23 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
166 167
167static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type) 168static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
168{ 169{
170 int i;
171 struct kvm_vcpu *tmp;
172
173 /*
174 * The KVM ABI specifies that a system event exit may call KVM_RUN
175 * again and may perform shutdown/reboot at a later time that when the
176 * actual request is made. Since we are implementing PSCI and a
177 * caller of PSCI reboot and shutdown expects that the system shuts
178 * down or reboots immediately, let's make sure that VCPUs are not run
179 * after this call is handled and before the VCPUs have been
180 * re-initialized.
181 */
182 kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
183 tmp->arch.pause = true;
184 kvm_vcpu_kick(tmp);
185 }
186
169 memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); 187 memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
170 vcpu->run->system_event.type = type; 188 vcpu->run->system_event.type = type;
171 vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; 189 vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 65c615294589..0b7dfdb931df 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -198,6 +198,7 @@ struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
198struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void); 198struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void);
199 199
200u64 kvm_call_hyp(void *hypfn, ...); 200u64 kvm_call_hyp(void *hypfn, ...);
201void force_vm_exit(const cpumask_t *mask);
201 202
202int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, 203int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
203 int exception_index); 204 int exception_index);