mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
powerpc/kvm/book3s: Add support for H_IPOLL and H_XIRR_X in XICS emulation
This adds the remaining two hypercalls defined by PAPR for manipulating the XICS interrupt controller, H_IPOLL and H_XIRR_X. H_IPOLL returns information about the priority and pending interrupts for a virtual cpu, without changing any state. H_XIRR_X is like H_XIRR in that it reads and acknowledges the highest-priority pending interrupt, but it also returns the timestamp (timebase register value) from when the interrupt was first received by the hypervisor. Currently we just return the current time, since we don't do any software queueing of virtual interrupts inside the XICS emulation code. These hcalls are not currently used by Linux guests, but may be in future. Signed-off-by: Paul Mackerras <paulus@samba.org> Acked-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
f7b3367774
commit
8e44ddc3f3
@ -264,6 +264,7 @@
|
||||
#define H_GET_MPP 0x2D4
|
||||
#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
|
||||
#define H_BEST_ENERGY 0x2F4
|
||||
#define H_XIRR_X 0x2FC
|
||||
#define H_RANDOM 0x300
|
||||
#define H_COP 0x304
|
||||
#define H_GET_MPP_X 0x314
|
||||
|
@ -562,6 +562,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
|
||||
case H_CPPR:
|
||||
case H_EOI:
|
||||
case H_IPI:
|
||||
case H_IPOLL:
|
||||
case H_XIRR_X:
|
||||
if (kvmppc_xics_enabled(vcpu)) {
|
||||
ret = kvmppc_xics_hcall(vcpu, req);
|
||||
break;
|
||||
|
@ -257,6 +257,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
|
||||
case H_CPPR:
|
||||
case H_EOI:
|
||||
case H_IPI:
|
||||
case H_IPOLL:
|
||||
case H_XIRR_X:
|
||||
if (kvmppc_xics_enabled(vcpu))
|
||||
return kvmppc_h_pr_xics_hcall(vcpu, cmd);
|
||||
break;
|
||||
|
@ -650,6 +650,23 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static int kvmppc_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server)
|
||||
{
|
||||
union kvmppc_icp_state state;
|
||||
struct kvmppc_icp *icp;
|
||||
|
||||
icp = vcpu->arch.icp;
|
||||
if (icp->server_num != server) {
|
||||
icp = kvmppc_xics_find_server(vcpu->kvm, server);
|
||||
if (!icp)
|
||||
return H_PARAMETER;
|
||||
}
|
||||
state = ACCESS_ONCE(icp->state);
|
||||
kvmppc_set_gpr(vcpu, 4, ((u32)state.cppr << 24) | state.xisr);
|
||||
kvmppc_set_gpr(vcpu, 5, state.mfrr);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
|
||||
{
|
||||
union kvmppc_icp_state old_state, new_state;
|
||||
@ -787,6 +804,18 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
|
||||
if (!xics || !vcpu->arch.icp)
|
||||
return H_HARDWARE;
|
||||
|
||||
/* These requests don't have real-mode implementations at present */
|
||||
switch (req) {
|
||||
case H_XIRR_X:
|
||||
res = kvmppc_h_xirr(vcpu);
|
||||
kvmppc_set_gpr(vcpu, 4, res);
|
||||
kvmppc_set_gpr(vcpu, 5, get_tb());
|
||||
return rc;
|
||||
case H_IPOLL:
|
||||
rc = kvmppc_h_ipoll(vcpu, kvmppc_get_gpr(vcpu, 4));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check for real mode returning too hard */
|
||||
if (xics->real_mode)
|
||||
return kvmppc_xics_rm_complete(vcpu, req);
|
||||
|
Loading…
Reference in New Issue
Block a user