Browse Source

KVM: PPC: Add support for ePAPR idle hcall in host kernel

And add a new flag definition in kvm_ppc_pvinfo to indicate
whether the host supports the EV_IDLE hcall.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[stuart.yoder@freescale.com: cleanup,fixes for conditions allowing idle]
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
[agraf: fix typo]
Signed-off-by: Alexander Graf <agraf@suse.de>
Liu Yu-B13201 13 years ago
parent
commit
9202e07636

+ 5 - 2
Documentation/virtual/kvm/api.txt

@@ -1194,12 +1194,15 @@ struct kvm_ppc_pvinfo {
 This ioctl fetches PV specific information that need to be passed to the guest
 This ioctl fetches PV specific information that need to be passed to the guest
 using the device tree or other means from vm context.
 using the device tree or other means from vm context.
 
 
-For now the only implemented piece of information distributed here is an array
-of 4 instructions that make up a hypercall.
+The hcall array defines 4 instructions that make up a hypercall.
 
 
 If any additional field gets added to this structure later on, a bit for that
 If any additional field gets added to this structure later on, a bit for that
 additional piece of information will be set in the flags bitmap.
 additional piece of information will be set in the flags bitmap.
 
 
+The flags bitmap is defined as:
+
+   /* the host supports the ePAPR idle hcall
+   #define KVM_PPC_PVINFO_FLAGS_EV_IDLE   (1<<0)
 
 
 4.48 KVM_ASSIGN_PCI_DEVICE
 4.48 KVM_ASSIGN_PCI_DEVICE
 
 

+ 1 - 0
arch/powerpc/include/asm/Kbuild

@@ -34,5 +34,6 @@ header-y += termios.h
 header-y += types.h
 header-y += types.h
 header-y += ucontext.h
 header-y += ucontext.h
 header-y += unistd.h
 header-y += unistd.h
+header-y += epapr_hcalls.h
 
 
 generic-y += rwsem.h
 generic-y += rwsem.h

+ 8 - 2
arch/powerpc/kvm/powerpc.c

@@ -38,8 +38,7 @@
 
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
 {
-	return !(v->arch.shared->msr & MSR_WE) ||
-	       !!(v->arch.pending_exceptions) ||
+	return !!(v->arch.pending_exceptions) ||
 	       v->requests;
 	       v->requests;
 }
 }
 
 
@@ -86,6 +85,11 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
 
 
 		/* Second return value is in r4 */
 		/* Second return value is in r4 */
 		break;
 		break;
+	case EV_HCALL_TOKEN(EV_IDLE):
+		r = EV_SUCCESS;
+		kvm_vcpu_block(vcpu);
+		clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
+		break;
 	default:
 	default:
 		r = EV_UNIMPLEMENTED;
 		r = EV_UNIMPLEMENTED;
 		break;
 		break;
@@ -779,6 +783,8 @@ static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
 	pvinfo->hcall[3] = inst_nop;
 	pvinfo->hcall[3] = inst_nop;
 #endif
 #endif
 
 
+	pvinfo->flags = KVM_PPC_PVINFO_FLAGS_EV_IDLE;
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 0
include/linux/kvm.h

@@ -477,6 +477,8 @@ struct kvm_ppc_smmu_info {
 	struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
 	struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
 };
 };
 
 
+#define KVM_PPC_PVINFO_FLAGS_EV_IDLE   (1<<0)
+
 #define KVMIO 0xAE
 #define KVMIO 0xAE
 
 
 /* machine type bits, to be used as argument to KVM_CREATE_VM */
 /* machine type bits, to be used as argument to KVM_CREATE_VM */