aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2012-09-25 16:33:06 -0400
committerAlexander Graf <agraf@suse.de>2012-10-05 17:38:55 -0400
commit55b665b0263ae88a776071306ef1eee4b769016b (patch)
treec83b5a0f8961ecac8a708cbdeb01f41d5b685d9e /arch/powerpc
parenta8bd19ef4dd49f0eef86a4a8eb43d60f967236b8 (diff)
KVM: PPC: Book3S HV: Provide a way for userspace to get/set per-vCPU areas
The PAPR paravirtualization interface lets guests register three different types of per-vCPU buffer areas in its memory for communication with the hypervisor. These are called virtual processor areas (VPAs). Currently the hypercalls to register and unregister VPAs are handled by KVM in the kernel, and userspace has no way to know about or save and restore these registrations across a migration. This adds "register" codes for these three areas that userspace can use with the KVM_GET/SET_ONE_REG ioctls to see what addresses have been registered, and to register or unregister them. This will be needed for guest hibernation and migration, and is also needed so that userspace can unregister them on reset (otherwise we corrupt guest memory after reboot by writing to the VPAs registered by the previous kernel). The "register" for the VPA is a 64-bit value containing the address, since the length of the VPA is fixed. The "registers" for the SLB shadow buffer and dispatch trace log (DTL) are 128 bits long, consisting of the guest physical address in the high (first) 64 bits and the length in the low 64 bits. This also fixes a bug where we were calling init_vpa unconditionally, leading to an oops when unregistering the VPA. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm.h6
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h4
-rw-r--r--arch/powerpc/kvm/book3s_hv.c64
3 files changed, 73 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 1466975129c7..b89ae4db45ce 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -380,4 +380,10 @@ struct kvm_book3e_206_tlb_params {
380#define KVM_REG_PPC_FPSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80) 380#define KVM_REG_PPC_FPSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
381#define KVM_REG_PPC_VSCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81) 381#define KVM_REG_PPC_VSCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
382 382
383/* Virtual processor areas */
384/* For SLB & DTL, address in high (first) half, length in low half */
385#define KVM_REG_PPC_VPA_ADDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82)
386#define KVM_REG_PPC_VPA_SLB (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83)
387#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
388
383#endif /* __LINUX_KVM_POWERPC_H */ 389#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 51604a16c8a5..609cca3e9426 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -202,6 +202,10 @@ union kvmppc_one_reg {
202 u64 dval; 202 u64 dval;
203 vector128 vval; 203 vector128 vval;
204 u64 vsxval[2]; 204 u64 vsxval[2];
205 struct {
206 u64 addr;
207 u64 length;
208 } vpaval;
205}; 209};
206 210
207#define one_reg_size(id) \ 211#define one_reg_size(id) \
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 94ec0e30969d..9a15da76e56b 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -143,6 +143,22 @@ static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa)
143 vpa->yield_count = 1; 143 vpa->yield_count = 1;
144} 144}
145 145
146static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v,
147 unsigned long addr, unsigned long len)
148{
149 /* check address is cacheline aligned */
150 if (addr & (L1_CACHE_BYTES - 1))
151 return -EINVAL;
152 spin_lock(&vcpu->arch.vpa_update_lock);
153 if (v->next_gpa != addr || v->len != len) {
154 v->next_gpa = addr;
155 v->len = addr ? len : 0;
156 v->update_pending = 1;
157 }
158 spin_unlock(&vcpu->arch.vpa_update_lock);
159 return 0;
160}
161
146/* Length for a per-processor buffer is passed in at offset 4 in the buffer */ 162/* Length for a per-processor buffer is passed in at offset 4 in the buffer */
147struct reg_vpa { 163struct reg_vpa {
148 u32 dummy; 164 u32 dummy;
@@ -321,7 +337,8 @@ static void kvmppc_update_vpas(struct kvm_vcpu *vcpu)
321 spin_lock(&vcpu->arch.vpa_update_lock); 337 spin_lock(&vcpu->arch.vpa_update_lock);
322 if (vcpu->arch.vpa.update_pending) { 338 if (vcpu->arch.vpa.update_pending) {
323 kvmppc_update_vpa(vcpu, &vcpu->arch.vpa); 339 kvmppc_update_vpa(vcpu, &vcpu->arch.vpa);
324 init_vpa(vcpu, vcpu->arch.vpa.pinned_addr); 340 if (vcpu->arch.vpa.pinned_addr)
341 init_vpa(vcpu, vcpu->arch.vpa.pinned_addr);
325 } 342 }
326 if (vcpu->arch.dtl.update_pending) { 343 if (vcpu->arch.dtl.update_pending) {
327 kvmppc_update_vpa(vcpu, &vcpu->arch.dtl); 344 kvmppc_update_vpa(vcpu, &vcpu->arch.dtl);
@@ -600,6 +617,23 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
600 } 617 }
601 break; 618 break;
602#endif /* CONFIG_VSX */ 619#endif /* CONFIG_VSX */
620 case KVM_REG_PPC_VPA_ADDR:
621 spin_lock(&vcpu->arch.vpa_update_lock);
622 *val = get_reg_val(id, vcpu->arch.vpa.next_gpa);
623 spin_unlock(&vcpu->arch.vpa_update_lock);
624 break;
625 case KVM_REG_PPC_VPA_SLB:
626 spin_lock(&vcpu->arch.vpa_update_lock);
627 val->vpaval.addr = vcpu->arch.slb_shadow.next_gpa;
628 val->vpaval.length = vcpu->arch.slb_shadow.len;
629 spin_unlock(&vcpu->arch.vpa_update_lock);
630 break;
631 case KVM_REG_PPC_VPA_DTL:
632 spin_lock(&vcpu->arch.vpa_update_lock);
633 val->vpaval.addr = vcpu->arch.dtl.next_gpa;
634 val->vpaval.length = vcpu->arch.dtl.len;
635 spin_unlock(&vcpu->arch.vpa_update_lock);
636 break;
603 default: 637 default:
604 r = -EINVAL; 638 r = -EINVAL;
605 break; 639 break;
@@ -612,6 +646,7 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
612{ 646{
613 int r = 0; 647 int r = 0;
614 long int i; 648 long int i;
649 unsigned long addr, len;
615 650
616 switch (id) { 651 switch (id) {
617 case KVM_REG_PPC_HIOR: 652 case KVM_REG_PPC_HIOR:
@@ -666,6 +701,33 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
666 } 701 }
667 break; 702 break;
668#endif /* CONFIG_VSX */ 703#endif /* CONFIG_VSX */
704 case KVM_REG_PPC_VPA_ADDR:
705 addr = set_reg_val(id, *val);
706 r = -EINVAL;
707 if (!addr && (vcpu->arch.slb_shadow.next_gpa ||
708 vcpu->arch.dtl.next_gpa))
709 break;
710 r = set_vpa(vcpu, &vcpu->arch.vpa, addr, sizeof(struct lppaca));
711 break;
712 case KVM_REG_PPC_VPA_SLB:
713 addr = val->vpaval.addr;
714 len = val->vpaval.length;
715 r = -EINVAL;
716 if (addr && !vcpu->arch.vpa.next_gpa)
717 break;
718 r = set_vpa(vcpu, &vcpu->arch.slb_shadow, addr, len);
719 break;
720 case KVM_REG_PPC_VPA_DTL:
721 addr = val->vpaval.addr;
722 len = val->vpaval.length;
723 r = -EINVAL;
724 if (len < sizeof(struct dtl_entry))
725 break;
726 if (addr && !vcpu->arch.vpa.next_gpa)
727 break;
728 len -= len % sizeof(struct dtl_entry);
729 r = set_vpa(vcpu, &vcpu->arch.dtl, addr, len);
730 break;
669 default: 731 default:
670 r = -EINVAL; 732 r = -EINVAL;
671 break; 733 break;