Loading Documentation/virtual/kvm/api.txt +40 −3 Original line number Diff line number Diff line Loading @@ -345,7 +345,7 @@ struct kvm_sregs { __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; }; /* ppc -- see arch/powerpc/include/asm/kvm.h */ /* ppc -- see arch/powerpc/include/uapi/asm/kvm.h */ interrupt_bitmap is a bitmap of pending external interrupts. At most one bit may be set. This interrupt has been acknowledged by the APIC Loading Loading @@ -1774,6 +1774,7 @@ registers, find a list below: PPC | KVM_REG_PPC_VPA_SLB | 128 PPC | KVM_REG_PPC_VPA_DTL | 128 PPC | KVM_REG_PPC_EPCR | 32 PPC | KVM_REG_PPC_EPR | 32 4.69 KVM_GET_ONE_REG Loading Loading @@ -2246,8 +2247,8 @@ executed a memory-mapped I/O instruction which could not be satisfied by kvm. The 'data' member contains the written data if 'is_write' is true, and should be filled by application code otherwise. NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_DCR and KVM_EXIT_PAPR the corresponding NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_DCR, KVM_EXIT_PAPR and KVM_EXIT_EPR the corresponding operations are complete (and guest state is consistent) only after userspace has re-entered the kernel with KVM_RUN. The kernel side will first finish incomplete operations and then check for pending signals. Userspace Loading Loading @@ -2366,6 +2367,25 @@ interrupt for the target subchannel has been dequeued and subchannel_id, subchannel_nr, io_int_parm and io_int_word contain the parameters for that interrupt. ipb is needed for instruction parameter decoding. /* KVM_EXIT_EPR */ struct { __u32 epr; } epr; On FSL BookE PowerPC chips, the interrupt controller has a fast patch interrupt acknowledge path to the core. When the core successfully delivers an interrupt, it automatically populates the EPR register with the interrupt vector number and acknowledges the interrupt inside the interrupt controller. In case the interrupt controller lives in user space, we need to do the interrupt acknowledge cycle through it to fetch the next to be delivered interrupt vector using this exit. It gets triggered whenever both KVM_CAP_PPC_EPR are enabled and an external interrupt has just been delivered into the guest. User space should put the acknowledged interrupt vector into the 'epr' field. /* Fix the size of the union. */ char padding[256]; }; Loading Loading @@ -2501,3 +2521,20 @@ handled in-kernel, while the other I/O instructions are passed to userspace. When this capability is enabled, KVM_EXIT_S390_TSCH will occur on TEST SUBCHANNEL intercepts. 6.5 KVM_CAP_PPC_EPR Architectures: ppc Parameters: args[0] defines whether the proxy facility is active Returns: 0 on success; -1 on error This capability enables or disables the delivery of interrupts through the external proxy facility. When enabled (args[0] != 0), every time the guest gets an external interrupt delivered, it automatically exits into user space with a KVM_EXIT_EPR exit to receive the topmost interrupt vector. When disabled (args[0] == 0), behavior is as if this facility is unsupported. When this capability is enabled, KVM_EXIT_EPR can occur. arch/powerpc/include/asm/kvm_host.h +2 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,8 @@ struct kvm_vcpu_arch { u8 sane; u8 cpu_type; u8 hcall_needed; u8 epr_enabled; u8 epr_needed; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ Loading arch/powerpc/include/asm/kvm_ppc.h +10 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ enum emulation_result { EMULATE_DO_DCR, /* kvm_run filled with DCR request */ EMULATE_FAIL, /* can't emulate this instruction */ EMULATE_AGAIN, /* something went wrong. go again */ EMULATE_DO_PAPR, /* kvm_run filled with PAPR request */ }; extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); Loading Loading @@ -263,6 +264,15 @@ static inline void kvm_linear_init(void) {} #endif static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) { #ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_GEPR, epr); #elif defined(CONFIG_BOOKE) vcpu->arch.epr = epr; #endif } int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, struct kvm_config_tlb *cfg); int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, Loading arch/powerpc/include/uapi/asm/kvm.h +5 −1 Original line number Diff line number Diff line Loading @@ -114,7 +114,10 @@ struct kvm_regs { /* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */ #define KVM_SREGS_E_SPE (1 << 9) /* External Proxy (EXP) -- EPR */ /* * DEPRECATED! USE ONE_REG FOR THIS ONE! * External Proxy (EXP) -- EPR */ #define KVM_SREGS_EXP (1 << 10) /* External PID (E.PD) -- EPSC/EPLC */ Loading Loading @@ -412,5 +415,6 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84) #define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85) #define KVM_REG_PPC_EPR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86) #endif /* __LINUX_KVM_POWERPC_H */ arch/powerpc/kvm/book3s_emulate.c +30 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #define OP_31_XOP_MTSRIN 242 #define OP_31_XOP_TLBIEL 274 #define OP_31_XOP_TLBIE 306 /* Opcode is officially reserved, reuse it as sc 1 when sc 1 doesn't trap */ #define OP_31_XOP_FAKE_SC1 308 #define OP_31_XOP_SLBMTE 402 #define OP_31_XOP_SLBIE 434 #define OP_31_XOP_SLBIA 498 Loading Loading @@ -170,6 +172,32 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->arch.mmu.tlbie(vcpu, addr, large); break; } #ifdef CONFIG_KVM_BOOK3S_64_PR case OP_31_XOP_FAKE_SC1: { /* SC 1 papr hypercalls */ ulong cmd = kvmppc_get_gpr(vcpu, 3); int i; if ((vcpu->arch.shared->msr & MSR_PR) || !vcpu->arch.papr_enabled) { emulated = EMULATE_FAIL; break; } if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE) break; run->papr_hcall.nr = cmd; for (i = 0; i < 9; ++i) { ulong gpr = kvmppc_get_gpr(vcpu, 4 + i); run->papr_hcall.args[i] = gpr; } emulated = EMULATE_DO_PAPR; break; } #endif case OP_31_XOP_EIOIO: break; case OP_31_XOP_SLBMTE: Loading Loading @@ -427,6 +455,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_PMC3_GEKKO: case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: break; unprivileged: default: Loading Loading @@ -523,6 +552,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_PMC3_GEKKO: case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: *spr_val = 0; break; default: Loading Loading
Documentation/virtual/kvm/api.txt +40 −3 Original line number Diff line number Diff line Loading @@ -345,7 +345,7 @@ struct kvm_sregs { __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; }; /* ppc -- see arch/powerpc/include/asm/kvm.h */ /* ppc -- see arch/powerpc/include/uapi/asm/kvm.h */ interrupt_bitmap is a bitmap of pending external interrupts. At most one bit may be set. This interrupt has been acknowledged by the APIC Loading Loading @@ -1774,6 +1774,7 @@ registers, find a list below: PPC | KVM_REG_PPC_VPA_SLB | 128 PPC | KVM_REG_PPC_VPA_DTL | 128 PPC | KVM_REG_PPC_EPCR | 32 PPC | KVM_REG_PPC_EPR | 32 4.69 KVM_GET_ONE_REG Loading Loading @@ -2246,8 +2247,8 @@ executed a memory-mapped I/O instruction which could not be satisfied by kvm. The 'data' member contains the written data if 'is_write' is true, and should be filled by application code otherwise. NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_DCR and KVM_EXIT_PAPR the corresponding NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO, KVM_EXIT_OSI, KVM_EXIT_DCR, KVM_EXIT_PAPR and KVM_EXIT_EPR the corresponding operations are complete (and guest state is consistent) only after userspace has re-entered the kernel with KVM_RUN. The kernel side will first finish incomplete operations and then check for pending signals. Userspace Loading Loading @@ -2366,6 +2367,25 @@ interrupt for the target subchannel has been dequeued and subchannel_id, subchannel_nr, io_int_parm and io_int_word contain the parameters for that interrupt. ipb is needed for instruction parameter decoding. /* KVM_EXIT_EPR */ struct { __u32 epr; } epr; On FSL BookE PowerPC chips, the interrupt controller has a fast patch interrupt acknowledge path to the core. When the core successfully delivers an interrupt, it automatically populates the EPR register with the interrupt vector number and acknowledges the interrupt inside the interrupt controller. In case the interrupt controller lives in user space, we need to do the interrupt acknowledge cycle through it to fetch the next to be delivered interrupt vector using this exit. It gets triggered whenever both KVM_CAP_PPC_EPR are enabled and an external interrupt has just been delivered into the guest. User space should put the acknowledged interrupt vector into the 'epr' field. /* Fix the size of the union. */ char padding[256]; }; Loading Loading @@ -2501,3 +2521,20 @@ handled in-kernel, while the other I/O instructions are passed to userspace. When this capability is enabled, KVM_EXIT_S390_TSCH will occur on TEST SUBCHANNEL intercepts. 6.5 KVM_CAP_PPC_EPR Architectures: ppc Parameters: args[0] defines whether the proxy facility is active Returns: 0 on success; -1 on error This capability enables or disables the delivery of interrupts through the external proxy facility. When enabled (args[0] != 0), every time the guest gets an external interrupt delivered, it automatically exits into user space with a KVM_EXIT_EPR exit to receive the topmost interrupt vector. When disabled (args[0] == 0), behavior is as if this facility is unsupported. When this capability is enabled, KVM_EXIT_EPR can occur.
arch/powerpc/include/asm/kvm_host.h +2 −0 Original line number Diff line number Diff line Loading @@ -520,6 +520,8 @@ struct kvm_vcpu_arch { u8 sane; u8 cpu_type; u8 hcall_needed; u8 epr_enabled; u8 epr_needed; u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ Loading
arch/powerpc/include/asm/kvm_ppc.h +10 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ enum emulation_result { EMULATE_DO_DCR, /* kvm_run filled with DCR request */ EMULATE_FAIL, /* can't emulate this instruction */ EMULATE_AGAIN, /* something went wrong. go again */ EMULATE_DO_PAPR, /* kvm_run filled with PAPR request */ }; extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); Loading Loading @@ -263,6 +264,15 @@ static inline void kvm_linear_init(void) {} #endif static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) { #ifdef CONFIG_KVM_BOOKE_HV mtspr(SPRN_GEPR, epr); #elif defined(CONFIG_BOOKE) vcpu->arch.epr = epr; #endif } int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, struct kvm_config_tlb *cfg); int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, Loading
arch/powerpc/include/uapi/asm/kvm.h +5 −1 Original line number Diff line number Diff line Loading @@ -114,7 +114,10 @@ struct kvm_regs { /* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */ #define KVM_SREGS_E_SPE (1 << 9) /* External Proxy (EXP) -- EPR */ /* * DEPRECATED! USE ONE_REG FOR THIS ONE! * External Proxy (EXP) -- EPR */ #define KVM_SREGS_EXP (1 << 10) /* External PID (E.PD) -- EPSC/EPLC */ Loading Loading @@ -412,5 +415,6 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84) #define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85) #define KVM_REG_PPC_EPR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86) #endif /* __LINUX_KVM_POWERPC_H */
arch/powerpc/kvm/book3s_emulate.c +30 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ #define OP_31_XOP_MTSRIN 242 #define OP_31_XOP_TLBIEL 274 #define OP_31_XOP_TLBIE 306 /* Opcode is officially reserved, reuse it as sc 1 when sc 1 doesn't trap */ #define OP_31_XOP_FAKE_SC1 308 #define OP_31_XOP_SLBMTE 402 #define OP_31_XOP_SLBIE 434 #define OP_31_XOP_SLBIA 498 Loading Loading @@ -170,6 +172,32 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, vcpu->arch.mmu.tlbie(vcpu, addr, large); break; } #ifdef CONFIG_KVM_BOOK3S_64_PR case OP_31_XOP_FAKE_SC1: { /* SC 1 papr hypercalls */ ulong cmd = kvmppc_get_gpr(vcpu, 3); int i; if ((vcpu->arch.shared->msr & MSR_PR) || !vcpu->arch.papr_enabled) { emulated = EMULATE_FAIL; break; } if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE) break; run->papr_hcall.nr = cmd; for (i = 0; i < 9; ++i) { ulong gpr = kvmppc_get_gpr(vcpu, 4 + i); run->papr_hcall.args[i] = gpr; } emulated = EMULATE_DO_PAPR; break; } #endif case OP_31_XOP_EIOIO: break; case OP_31_XOP_SLBMTE: Loading Loading @@ -427,6 +455,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_PMC3_GEKKO: case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: break; unprivileged: default: Loading Loading @@ -523,6 +552,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) case SPRN_PMC3_GEKKO: case SPRN_PMC4_GEKKO: case SPRN_WPAR_GEKKO: case SPRN_MSSSR0: *spr_val = 0; break; default: Loading