diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-12-07 12:16:37 -0500 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2017-02-03 10:21:32 -0500 |
commit | 013044cc65f8661c5fa2b59da5e134b3453d975d (patch) | |
tree | 801ef5a0bad1220d2d1b6fc271e11dfaf5e7d9bd | |
parent | be67a0be94b65746dee63af5c184c78d00a707f6 (diff) |
KVM: MIPS/T&E: Expose CP0_EntryLo0/1 registers
Expose the CP0_EntryLo0 and CP0_EntryLo1 registers through the KVM
register access API. This is fairly straightforward for trap & emulate
since we don't support the RI and XI bits. For the sake of future
proofing (particularly for VZ) it is explicitly specified that the API
always exposes the 64-bit version of these registers (i.e. with the RI
and XI bits in bit positions 63 and 62 respectively), and they are
implemented in trap_emul.c rather than mips.c to allow them to be
implemented differently for VZ.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Cc: kvm@vger.kernel.org
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 8 | ||||
-rw-r--r-- | arch/mips/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/mips/kvm/trap_emul.c | 14 |
3 files changed, 24 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 8d52d0f990ae..df4a309ba56e 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -2061,6 +2061,8 @@ registers, find a list below: | |||
2061 | MIPS | KVM_REG_MIPS_LO | 64 | 2061 | MIPS | KVM_REG_MIPS_LO | 64 |
2062 | MIPS | KVM_REG_MIPS_PC | 64 | 2062 | MIPS | KVM_REG_MIPS_PC | 64 |
2063 | MIPS | KVM_REG_MIPS_CP0_INDEX | 32 | 2063 | MIPS | KVM_REG_MIPS_CP0_INDEX | 32 |
2064 | MIPS | KVM_REG_MIPS_CP0_ENTRYLO0 | 64 | ||
2065 | MIPS | KVM_REG_MIPS_CP0_ENTRYLO1 | 64 | ||
2064 | MIPS | KVM_REG_MIPS_CP0_CONTEXT | 64 | 2066 | MIPS | KVM_REG_MIPS_CP0_CONTEXT | 64 |
2065 | MIPS | KVM_REG_MIPS_CP0_USERLOCAL | 64 | 2067 | MIPS | KVM_REG_MIPS_CP0_USERLOCAL | 64 |
2066 | MIPS | KVM_REG_MIPS_CP0_PAGEMASK | 32 | 2068 | MIPS | KVM_REG_MIPS_CP0_PAGEMASK | 32 |
@@ -2149,6 +2151,12 @@ patterns depending on whether they're 32-bit or 64-bit registers: | |||
2149 | 0x7020 0000 0001 00 <reg:5> <sel:3> (32-bit) | 2151 | 0x7020 0000 0001 00 <reg:5> <sel:3> (32-bit) |
2150 | 0x7030 0000 0001 00 <reg:5> <sel:3> (64-bit) | 2152 | 0x7030 0000 0001 00 <reg:5> <sel:3> (64-bit) |
2151 | 2153 | ||
2154 | Note: KVM_REG_MIPS_CP0_ENTRYLO0 and KVM_REG_MIPS_CP0_ENTRYLO1 are the MIPS64 | ||
2155 | versions of the EntryLo registers regardless of the word size of the host | ||
2156 | hardware, host kernel, guest, and whether XPA is present in the guest, i.e. | ||
2157 | with the RI and XI bits (if they exist) in bits 63 and 62 respectively, and | ||
2158 | the PFNX field starting at bit 30. | ||
2159 | |||
2152 | MIPS KVM control registers (see above) have the following id bit patterns: | 2160 | MIPS KVM control registers (see above) have the following id bit patterns: |
2153 | 0x7030 0000 0002 <reg:16> | 2161 | 0x7030 0000 0002 <reg:16> |
2154 | 2162 | ||
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 420372fa5bbc..66459ca4af81 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -352,7 +352,9 @@ struct kvm_vcpu_arch { | |||
352 | #define kvm_read_c0_guest_index(cop0) (cop0->reg[MIPS_CP0_TLB_INDEX][0]) | 352 | #define kvm_read_c0_guest_index(cop0) (cop0->reg[MIPS_CP0_TLB_INDEX][0]) |
353 | #define kvm_write_c0_guest_index(cop0, val) (cop0->reg[MIPS_CP0_TLB_INDEX][0] = val) | 353 | #define kvm_write_c0_guest_index(cop0, val) (cop0->reg[MIPS_CP0_TLB_INDEX][0] = val) |
354 | #define kvm_read_c0_guest_entrylo0(cop0) (cop0->reg[MIPS_CP0_TLB_LO0][0]) | 354 | #define kvm_read_c0_guest_entrylo0(cop0) (cop0->reg[MIPS_CP0_TLB_LO0][0]) |
355 | #define kvm_write_c0_guest_entrylo0(cop0, val) (cop0->reg[MIPS_CP0_TLB_LO0][0] = (val)) | ||
355 | #define kvm_read_c0_guest_entrylo1(cop0) (cop0->reg[MIPS_CP0_TLB_LO1][0]) | 356 | #define kvm_read_c0_guest_entrylo1(cop0) (cop0->reg[MIPS_CP0_TLB_LO1][0]) |
357 | #define kvm_write_c0_guest_entrylo1(cop0, val) (cop0->reg[MIPS_CP0_TLB_LO1][0] = (val)) | ||
356 | #define kvm_read_c0_guest_context(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0]) | 358 | #define kvm_read_c0_guest_context(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0]) |
357 | #define kvm_write_c0_guest_context(cop0, val) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0] = (val)) | 359 | #define kvm_write_c0_guest_context(cop0, val) (cop0->reg[MIPS_CP0_TLB_CONTEXT][0] = (val)) |
358 | #define kvm_read_c0_guest_userlocal(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][2]) | 360 | #define kvm_read_c0_guest_userlocal(cop0) (cop0->reg[MIPS_CP0_TLB_CONTEXT][2]) |
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index ce44f91c653a..2f9e44b0f177 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
@@ -646,6 +646,8 @@ static void kvm_trap_emul_flush_shadow_memslot(struct kvm *kvm, | |||
646 | 646 | ||
647 | static u64 kvm_trap_emul_get_one_regs[] = { | 647 | static u64 kvm_trap_emul_get_one_regs[] = { |
648 | KVM_REG_MIPS_CP0_INDEX, | 648 | KVM_REG_MIPS_CP0_INDEX, |
649 | KVM_REG_MIPS_CP0_ENTRYLO0, | ||
650 | KVM_REG_MIPS_CP0_ENTRYLO1, | ||
649 | KVM_REG_MIPS_CP0_CONTEXT, | 651 | KVM_REG_MIPS_CP0_CONTEXT, |
650 | KVM_REG_MIPS_CP0_USERLOCAL, | 652 | KVM_REG_MIPS_CP0_USERLOCAL, |
651 | KVM_REG_MIPS_CP0_PAGEMASK, | 653 | KVM_REG_MIPS_CP0_PAGEMASK, |
@@ -706,6 +708,12 @@ static int kvm_trap_emul_get_one_reg(struct kvm_vcpu *vcpu, | |||
706 | case KVM_REG_MIPS_CP0_INDEX: | 708 | case KVM_REG_MIPS_CP0_INDEX: |
707 | *v = (long)kvm_read_c0_guest_index(cop0); | 709 | *v = (long)kvm_read_c0_guest_index(cop0); |
708 | break; | 710 | break; |
711 | case KVM_REG_MIPS_CP0_ENTRYLO0: | ||
712 | *v = kvm_read_c0_guest_entrylo0(cop0); | ||
713 | break; | ||
714 | case KVM_REG_MIPS_CP0_ENTRYLO1: | ||
715 | *v = kvm_read_c0_guest_entrylo1(cop0); | ||
716 | break; | ||
709 | case KVM_REG_MIPS_CP0_CONTEXT: | 717 | case KVM_REG_MIPS_CP0_CONTEXT: |
710 | *v = (long)kvm_read_c0_guest_context(cop0); | 718 | *v = (long)kvm_read_c0_guest_context(cop0); |
711 | break; | 719 | break; |
@@ -817,6 +825,12 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu, | |||
817 | case KVM_REG_MIPS_CP0_INDEX: | 825 | case KVM_REG_MIPS_CP0_INDEX: |
818 | kvm_write_c0_guest_index(cop0, v); | 826 | kvm_write_c0_guest_index(cop0, v); |
819 | break; | 827 | break; |
828 | case KVM_REG_MIPS_CP0_ENTRYLO0: | ||
829 | kvm_write_c0_guest_entrylo0(cop0, v); | ||
830 | break; | ||
831 | case KVM_REG_MIPS_CP0_ENTRYLO1: | ||
832 | kvm_write_c0_guest_entrylo1(cop0, v); | ||
833 | break; | ||
820 | case KVM_REG_MIPS_CP0_CONTEXT: | 834 | case KVM_REG_MIPS_CP0_CONTEXT: |
821 | kvm_write_c0_guest_context(cop0, v); | 835 | kvm_write_c0_guest_context(cop0, v); |
822 | break; | 836 | break; |