diff options
author | Mihai Caraman <mihai.caraman@freescale.com> | 2013-04-10 20:03:08 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-04-26 14:27:06 -0400 |
commit | a85d2aa23e51a9460e034e283da2513930b4f183 (patch) | |
tree | 51f61cd107326edbd835c9ec24efea0d7ca3025a | |
parent | 35b299e279eb5bc4622ec883b5f388c3224cbd61 (diff) |
KVM: PPC: e500: Expose MMU registers via ONE_REG
MMU registers were exposed to user-space using sregs interface. Add them
to ONE_REG interface using kvmppc_get_one_reg/kvmppc_set_one_reg delegation
mechanism.
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 11 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/kvm.h | 17 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_mmu.c | 94 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500mc.c | 6 |
6 files changed, 134 insertions, 4 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 976eb650e7ef..1a766637ac21 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1792,6 +1792,17 @@ registers, find a list below: | |||
1792 | PPC | KVM_REG_PPC_TSR | 32 | 1792 | PPC | KVM_REG_PPC_TSR | 32 |
1793 | PPC | KVM_REG_PPC_OR_TSR | 32 | 1793 | PPC | KVM_REG_PPC_OR_TSR | 32 |
1794 | PPC | KVM_REG_PPC_CLEAR_TSR | 32 | 1794 | PPC | KVM_REG_PPC_CLEAR_TSR | 32 |
1795 | PPC | KVM_REG_PPC_MAS0 | 32 | ||
1796 | PPC | KVM_REG_PPC_MAS1 | 32 | ||
1797 | PPC | KVM_REG_PPC_MAS2 | 64 | ||
1798 | PPC | KVM_REG_PPC_MAS7_3 | 64 | ||
1799 | PPC | KVM_REG_PPC_MAS4 | 32 | ||
1800 | PPC | KVM_REG_PPC_MAS6 | 32 | ||
1801 | PPC | KVM_REG_PPC_MMUCFG | 32 | ||
1802 | PPC | KVM_REG_PPC_TLB0CFG | 32 | ||
1803 | PPC | KVM_REG_PPC_TLB1CFG | 32 | ||
1804 | PPC | KVM_REG_PPC_TLB2CFG | 32 | ||
1805 | PPC | KVM_REG_PPC_TLB3CFG | 32 | ||
1795 | 1806 | ||
1796 | ARM registers are mapped using the lower 32 bits. The upper 16 of that | 1807 | ARM registers are mapped using the lower 32 bits. The upper 16 of that |
1797 | is the register group type, or coprocessor number: | 1808 | is the register group type, or coprocessor number: |
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index c0c38ed9c97d..0c5cffb6a58e 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h | |||
@@ -449,4 +449,21 @@ struct kvm_get_htab_header { | |||
449 | /* Debugging: Special instruction for software breakpoint */ | 449 | /* Debugging: Special instruction for software breakpoint */ |
450 | #define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b) | 450 | #define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b) |
451 | 451 | ||
452 | /* MMU registers */ | ||
453 | #define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c) | ||
454 | #define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d) | ||
455 | #define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e) | ||
456 | #define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f) | ||
457 | #define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90) | ||
458 | #define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91) | ||
459 | #define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92) | ||
460 | /* | ||
461 | * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using | ||
462 | * KVM_CAP_SW_TLB ioctl | ||
463 | */ | ||
464 | #define KVM_REG_PPC_TLB0CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93) | ||
465 | #define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94) | ||
466 | #define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95) | ||
467 | #define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96) | ||
468 | |||
452 | #endif /* __LINUX_KVM_POWERPC_H */ | 469 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 576010f6c27d..ce6b73c29612 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c | |||
@@ -428,13 +428,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) | |||
428 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, | 428 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, |
429 | union kvmppc_one_reg *val) | 429 | union kvmppc_one_reg *val) |
430 | { | 430 | { |
431 | return -EINVAL; | 431 | int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); |
432 | return r; | ||
432 | } | 433 | } |
433 | 434 | ||
434 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, | 435 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, |
435 | union kvmppc_one_reg *val) | 436 | union kvmppc_one_reg *val) |
436 | { | 437 | { |
437 | return -EINVAL; | 438 | int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); |
439 | return r; | ||
438 | } | 440 | } |
439 | 441 | ||
440 | struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | 442 | struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) |
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index 33db48a8ce24..b73ca7a1c09f 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h | |||
@@ -131,6 +131,10 @@ void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500); | |||
131 | void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); | 131 | void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); |
132 | int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); | 132 | int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); |
133 | 133 | ||
134 | int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | ||
135 | union kvmppc_one_reg *val); | ||
136 | int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | ||
137 | union kvmppc_one_reg *val); | ||
134 | 138 | ||
135 | #ifdef CONFIG_KVM_E500V2 | 139 | #ifdef CONFIG_KVM_E500V2 |
136 | unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, | 140 | unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500, |
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 5c4475983f78..44f7762694ba 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c | |||
@@ -596,6 +596,100 @@ int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) | |||
596 | return 0; | 596 | return 0; |
597 | } | 597 | } |
598 | 598 | ||
599 | int kvmppc_get_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | ||
600 | union kvmppc_one_reg *val) | ||
601 | { | ||
602 | int r = 0; | ||
603 | long int i; | ||
604 | |||
605 | switch (id) { | ||
606 | case KVM_REG_PPC_MAS0: | ||
607 | *val = get_reg_val(id, vcpu->arch.shared->mas0); | ||
608 | break; | ||
609 | case KVM_REG_PPC_MAS1: | ||
610 | *val = get_reg_val(id, vcpu->arch.shared->mas1); | ||
611 | break; | ||
612 | case KVM_REG_PPC_MAS2: | ||
613 | *val = get_reg_val(id, vcpu->arch.shared->mas2); | ||
614 | break; | ||
615 | case KVM_REG_PPC_MAS7_3: | ||
616 | *val = get_reg_val(id, vcpu->arch.shared->mas7_3); | ||
617 | break; | ||
618 | case KVM_REG_PPC_MAS4: | ||
619 | *val = get_reg_val(id, vcpu->arch.shared->mas4); | ||
620 | break; | ||
621 | case KVM_REG_PPC_MAS6: | ||
622 | *val = get_reg_val(id, vcpu->arch.shared->mas6); | ||
623 | break; | ||
624 | case KVM_REG_PPC_MMUCFG: | ||
625 | *val = get_reg_val(id, vcpu->arch.mmucfg); | ||
626 | break; | ||
627 | case KVM_REG_PPC_TLB0CFG: | ||
628 | case KVM_REG_PPC_TLB1CFG: | ||
629 | case KVM_REG_PPC_TLB2CFG: | ||
630 | case KVM_REG_PPC_TLB3CFG: | ||
631 | i = id - KVM_REG_PPC_TLB0CFG; | ||
632 | *val = get_reg_val(id, vcpu->arch.tlbcfg[i]); | ||
633 | break; | ||
634 | default: | ||
635 | r = -EINVAL; | ||
636 | break; | ||
637 | } | ||
638 | |||
639 | return r; | ||
640 | } | ||
641 | |||
642 | int kvmppc_set_one_reg_e500_tlb(struct kvm_vcpu *vcpu, u64 id, | ||
643 | union kvmppc_one_reg *val) | ||
644 | { | ||
645 | int r = 0; | ||
646 | long int i; | ||
647 | |||
648 | switch (id) { | ||
649 | case KVM_REG_PPC_MAS0: | ||
650 | vcpu->arch.shared->mas0 = set_reg_val(id, *val); | ||
651 | break; | ||
652 | case KVM_REG_PPC_MAS1: | ||
653 | vcpu->arch.shared->mas1 = set_reg_val(id, *val); | ||
654 | break; | ||
655 | case KVM_REG_PPC_MAS2: | ||
656 | vcpu->arch.shared->mas2 = set_reg_val(id, *val); | ||
657 | break; | ||
658 | case KVM_REG_PPC_MAS7_3: | ||
659 | vcpu->arch.shared->mas7_3 = set_reg_val(id, *val); | ||
660 | break; | ||
661 | case KVM_REG_PPC_MAS4: | ||
662 | vcpu->arch.shared->mas4 = set_reg_val(id, *val); | ||
663 | break; | ||
664 | case KVM_REG_PPC_MAS6: | ||
665 | vcpu->arch.shared->mas6 = set_reg_val(id, *val); | ||
666 | break; | ||
667 | /* Only allow MMU registers to be set to the config supported by KVM */ | ||
668 | case KVM_REG_PPC_MMUCFG: { | ||
669 | u32 reg = set_reg_val(id, *val); | ||
670 | if (reg != vcpu->arch.mmucfg) | ||
671 | r = -EINVAL; | ||
672 | break; | ||
673 | } | ||
674 | case KVM_REG_PPC_TLB0CFG: | ||
675 | case KVM_REG_PPC_TLB1CFG: | ||
676 | case KVM_REG_PPC_TLB2CFG: | ||
677 | case KVM_REG_PPC_TLB3CFG: { | ||
678 | /* MMU geometry (N_ENTRY/ASSOC) can be set only using SW_TLB */ | ||
679 | u32 reg = set_reg_val(id, *val); | ||
680 | i = id - KVM_REG_PPC_TLB0CFG; | ||
681 | if (reg != vcpu->arch.tlbcfg[i]) | ||
682 | r = -EINVAL; | ||
683 | break; | ||
684 | } | ||
685 | default: | ||
686 | r = -EINVAL; | ||
687 | break; | ||
688 | } | ||
689 | |||
690 | return r; | ||
691 | } | ||
692 | |||
599 | int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, | 693 | int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, |
600 | struct kvm_config_tlb *cfg) | 694 | struct kvm_config_tlb *cfg) |
601 | { | 695 | { |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index b071bdcbe37d..ab073a80cd45 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -258,13 +258,15 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) | |||
258 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, | 258 | int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, |
259 | union kvmppc_one_reg *val) | 259 | union kvmppc_one_reg *val) |
260 | { | 260 | { |
261 | return -EINVAL; | 261 | int r = kvmppc_get_one_reg_e500_tlb(vcpu, id, val); |
262 | return r; | ||
262 | } | 263 | } |
263 | 264 | ||
264 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, | 265 | int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, |
265 | union kvmppc_one_reg *val) | 266 | union kvmppc_one_reg *val) |
266 | { | 267 | { |
267 | return -EINVAL; | 268 | int r = kvmppc_set_one_reg_e500_tlb(vcpu, id, val); |
269 | return r; | ||
268 | } | 270 | } |
269 | 271 | ||
270 | struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | 272 | struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) |