aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/virtual/kvm/api.txt11
-rw-r--r--arch/powerpc/include/asm/kvm.h20
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/kvm/book3s.c48
-rw-r--r--arch/powerpc/kvm/book3s_hv.c42
-rw-r--r--arch/powerpc/kvm/book3s_pr.c26
6 files changed, 149 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index af9b7a06bcae..71dc7e2ec8eb 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1759,6 +1759,17 @@ registers, find a list below:
1759 PPC | KVM_REG_PPC_PMC6 | 32 1759 PPC | KVM_REG_PPC_PMC6 | 32
1760 PPC | KVM_REG_PPC_PMC7 | 32 1760 PPC | KVM_REG_PPC_PMC7 | 32
1761 PPC | KVM_REG_PPC_PMC8 | 32 1761 PPC | KVM_REG_PPC_PMC8 | 32
1762 PPC | KVM_REG_PPC_FPR0 | 64
1763 ...
1764 PPC | KVM_REG_PPC_FPR31 | 64
1765 PPC | KVM_REG_PPC_VR0 | 128
1766 ...
1767 PPC | KVM_REG_PPC_VR31 | 128
1768 PPC | KVM_REG_PPC_VSR0 | 128
1769 ...
1770 PPC | KVM_REG_PPC_VSR31 | 128
1771 PPC | KVM_REG_PPC_FPSCR | 64
1772 PPC | KVM_REG_PPC_VSCR | 32
1762 1773
17634.69 KVM_GET_ONE_REG 17744.69 KVM_GET_ONE_REG
1764 1775
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 9557576a5325..1466975129c7 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -360,4 +360,24 @@ struct kvm_book3e_206_tlb_params {
360#define KVM_REG_PPC_PMC7 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e) 360#define KVM_REG_PPC_PMC7 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e)
361#define KVM_REG_PPC_PMC8 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f) 361#define KVM_REG_PPC_PMC8 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f)
362 362
363/* 32 floating-point registers */
364#define KVM_REG_PPC_FPR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20)
365#define KVM_REG_PPC_FPR(n) (KVM_REG_PPC_FPR0 + (n))
366#define KVM_REG_PPC_FPR31 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f)
367
368/* 32 VMX/Altivec vector registers */
369#define KVM_REG_PPC_VR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40)
370#define KVM_REG_PPC_VR(n) (KVM_REG_PPC_VR0 + (n))
371#define KVM_REG_PPC_VR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f)
372
373/* 32 double-width FP registers for VSX */
374/* High-order halves overlap with FP regs */
375#define KVM_REG_PPC_VSR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60)
376#define KVM_REG_PPC_VSR(n) (KVM_REG_PPC_VSR0 + (n))
377#define KVM_REG_PPC_VSR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f)
378
379/* FP and vector status/control registers */
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)
382
363#endif /* __LINUX_KVM_POWERPC_H */ 383#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 709f0ddae1f1..51604a16c8a5 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -200,6 +200,8 @@ static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value)
200union kvmppc_one_reg { 200union kvmppc_one_reg {
201 u32 wval; 201 u32 wval;
202 u64 dval; 202 u64 dval;
203 vector128 vval;
204 u64 vsxval[2];
203}; 205};
204 206
205#define one_reg_size(id) \ 207#define one_reg_size(id) \
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index a5af28fc3a8f..a4b645285240 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -490,6 +490,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
490 int r; 490 int r;
491 union kvmppc_one_reg val; 491 union kvmppc_one_reg val;
492 int size; 492 int size;
493 long int i;
493 494
494 size = one_reg_size(reg->id); 495 size = one_reg_size(reg->id);
495 if (size > sizeof(val)) 496 if (size > sizeof(val))
@@ -506,6 +507,29 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
506 case KVM_REG_PPC_DSISR: 507 case KVM_REG_PPC_DSISR:
507 val = get_reg_val(reg->id, vcpu->arch.shared->dsisr); 508 val = get_reg_val(reg->id, vcpu->arch.shared->dsisr);
508 break; 509 break;
510 case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
511 i = reg->id - KVM_REG_PPC_FPR0;
512 val = get_reg_val(reg->id, vcpu->arch.fpr[i]);
513 break;
514 case KVM_REG_PPC_FPSCR:
515 val = get_reg_val(reg->id, vcpu->arch.fpscr);
516 break;
517#ifdef CONFIG_ALTIVEC
518 case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
519 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
520 r = -ENXIO;
521 break;
522 }
523 val.vval = vcpu->arch.vr[reg->id - KVM_REG_PPC_VR0];
524 break;
525 case KVM_REG_PPC_VSCR:
526 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
527 r = -ENXIO;
528 break;
529 }
530 val = get_reg_val(reg->id, vcpu->arch.vscr.u[3]);
531 break;
532#endif /* CONFIG_ALTIVEC */
509 default: 533 default:
510 r = -EINVAL; 534 r = -EINVAL;
511 break; 535 break;
@@ -525,6 +549,7 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
525 int r; 549 int r;
526 union kvmppc_one_reg val; 550 union kvmppc_one_reg val;
527 int size; 551 int size;
552 long int i;
528 553
529 size = one_reg_size(reg->id); 554 size = one_reg_size(reg->id);
530 if (size > sizeof(val)) 555 if (size > sizeof(val))
@@ -544,6 +569,29 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
544 case KVM_REG_PPC_DSISR: 569 case KVM_REG_PPC_DSISR:
545 vcpu->arch.shared->dsisr = set_reg_val(reg->id, val); 570 vcpu->arch.shared->dsisr = set_reg_val(reg->id, val);
546 break; 571 break;
572 case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
573 i = reg->id - KVM_REG_PPC_FPR0;
574 vcpu->arch.fpr[i] = set_reg_val(reg->id, val);
575 break;
576 case KVM_REG_PPC_FPSCR:
577 vcpu->arch.fpscr = set_reg_val(reg->id, val);
578 break;
579#ifdef CONFIG_ALTIVEC
580 case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31:
581 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
582 r = -ENXIO;
583 break;
584 }
585 vcpu->arch.vr[reg->id - KVM_REG_PPC_VR0] = val.vval;
586 break;
587 case KVM_REG_PPC_VSCR:
588 if (!cpu_has_feature(CPU_FTR_ALTIVEC)) {
589 r = -ENXIO;
590 break;
591 }
592 vcpu->arch.vscr.u[3] = set_reg_val(reg->id, val);
593 break;
594#endif /* CONFIG_ALTIVEC */
547 default: 595 default:
548 r = -EINVAL; 596 r = -EINVAL;
549 break; 597 break;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 1cc6b77fa63d..94ec0e30969d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -579,6 +579,27 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
579 i = id - KVM_REG_PPC_PMC1; 579 i = id - KVM_REG_PPC_PMC1;
580 *val = get_reg_val(id, vcpu->arch.pmc[i]); 580 *val = get_reg_val(id, vcpu->arch.pmc[i]);
581 break; 581 break;
582#ifdef CONFIG_VSX
583 case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
584 if (cpu_has_feature(CPU_FTR_VSX)) {
585 /* VSX => FP reg i is stored in arch.vsr[2*i] */
586 long int i = id - KVM_REG_PPC_FPR0;
587 *val = get_reg_val(id, vcpu->arch.vsr[2 * i]);
588 } else {
589 /* let generic code handle it */
590 r = -EINVAL;
591 }
592 break;
593 case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
594 if (cpu_has_feature(CPU_FTR_VSX)) {
595 long int i = id - KVM_REG_PPC_VSR0;
596 val->vsxval[0] = vcpu->arch.vsr[2 * i];
597 val->vsxval[1] = vcpu->arch.vsr[2 * i + 1];
598 } else {
599 r = -ENXIO;
600 }
601 break;
602#endif /* CONFIG_VSX */
582 default: 603 default:
583 r = -EINVAL; 604 r = -EINVAL;
584 break; 605 break;
@@ -624,6 +645,27 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
624 i = id - KVM_REG_PPC_PMC1; 645 i = id - KVM_REG_PPC_PMC1;
625 vcpu->arch.pmc[i] = set_reg_val(id, *val); 646 vcpu->arch.pmc[i] = set_reg_val(id, *val);
626 break; 647 break;
648#ifdef CONFIG_VSX
649 case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
650 if (cpu_has_feature(CPU_FTR_VSX)) {
651 /* VSX => FP reg i is stored in arch.vsr[2*i] */
652 long int i = id - KVM_REG_PPC_FPR0;
653 vcpu->arch.vsr[2 * i] = set_reg_val(id, *val);
654 } else {
655 /* let generic code handle it */
656 r = -EINVAL;
657 }
658 break;
659 case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
660 if (cpu_has_feature(CPU_FTR_VSX)) {
661 long int i = id - KVM_REG_PPC_VSR0;
662 vcpu->arch.vsr[2 * i] = val->vsxval[0];
663 vcpu->arch.vsr[2 * i + 1] = val->vsxval[1];
664 } else {
665 r = -ENXIO;
666 }
667 break;
668#endif /* CONFIG_VSX */
627 default: 669 default:
628 r = -EINVAL; 670 r = -EINVAL;
629 break; 671 break;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index c81109f3a376..b853696b6d8e 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -953,6 +953,19 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
953 case KVM_REG_PPC_HIOR: 953 case KVM_REG_PPC_HIOR:
954 *val = get_reg_val(id, to_book3s(vcpu)->hior); 954 *val = get_reg_val(id, to_book3s(vcpu)->hior);
955 break; 955 break;
956#ifdef CONFIG_VSX
957 case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: {
958 long int i = id - KVM_REG_PPC_VSR0;
959
960 if (!cpu_has_feature(CPU_FTR_VSX)) {
961 r = -ENXIO;
962 break;
963 }
964 val->vsxval[0] = vcpu->arch.fpr[i];
965 val->vsxval[1] = vcpu->arch.vsr[i];
966 break;
967 }
968#endif /* CONFIG_VSX */
956 default: 969 default:
957 r = -EINVAL; 970 r = -EINVAL;
958 break; 971 break;
@@ -970,6 +983,19 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
970 to_book3s(vcpu)->hior = set_reg_val(id, *val); 983 to_book3s(vcpu)->hior = set_reg_val(id, *val);
971 to_book3s(vcpu)->hior_explicit = true; 984 to_book3s(vcpu)->hior_explicit = true;
972 break; 985 break;
986#ifdef CONFIG_VSX
987 case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: {
988 long int i = id - KVM_REG_PPC_VSR0;
989
990 if (!cpu_has_feature(CPU_FTR_VSX)) {
991 r = -ENXIO;
992 break;
993 }
994 vcpu->arch.fpr[i] = val->vsxval[0];
995 vcpu->arch.vsr[i] = val->vsxval[1];
996 break;
997 }
998#endif /* CONFIG_VSX */
973 default: 999 default:
974 r = -EINVAL; 1000 r = -EINVAL;
975 break; 1001 break;