aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr_hcall.c
diff options
context:
space:
mode:
authorMichael Roth <mdroth@linux.vnet.ibm.com>2019-07-17 15:58:42 -0500
committerDavid Gibson <david@gibson.dropbear.id.au>2019-08-21 17:17:12 +1000
commit0fb6bd07323019dc8d3f2c124323f71e2ddfc9f4 (patch)
treeb58f56e89db22e181cbb27194767ffdd59fb3fb8 /hw/ppc/spapr_hcall.c
parent1daba4d1b296d23907b73735615b12588da670fb (diff)
spapr: initial implementation for H_TPM_COMM/spapr-tpm-proxy
This implements the H_TPM_COMM hypercall, which is used by an Ultravisor to pass TPM commands directly to the host's TPM device, or a TPM Resource Manager associated with the device. This also introduces a new virtual device, spapr-tpm-proxy, which is used to configure the host TPM path to be used to service requests sent by H_TPM_COMM hcalls, for example: -device spapr-tpm-proxy,id=tpmp0,host-path=/dev/tpmrm0 By default, no spapr-tpm-proxy will be created, and hcalls will return H_FUNCTION. The full specification for this hypercall can be found in docs/specs/ppc-spapr-uv-hcalls.txt Since SVM-related hcalls like H_TPM_COMM use a reserved range of 0xEF00-0xEF80, we introduce a separate hcall table here to handle them. Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com Message-Id: <20190717205842.17827-3-mdroth@linux.vnet.ibm.com> [dwg: Corrected #include for upstream change] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw/ppc/spapr_hcall.c')
-rw-r--r--hw/ppc/spapr_hcall.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 10c0b53339..e20a946b99 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1963,6 +1963,7 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr,
static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
+static spapr_hcall_fn svm_hypercall_table[(SVM_HCALL_MAX - SVM_HCALL_BASE) / 4 + 1];
void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
{
@@ -1972,6 +1973,11 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
assert((opcode & 0x3) == 0);
slot = &papr_hypercall_table[opcode / 4];
+ } else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) {
+ /* we only have SVM-related hcall numbers assigned in multiples of 4 */
+ assert((opcode & 0x3) == 0);
+
+ slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
} else {
assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
@@ -1994,6 +2000,13 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
if (fn) {
return fn(cpu, spapr, opcode, args);
}
+ } else if ((opcode >= SVM_HCALL_BASE) &&
+ (opcode <= SVM_HCALL_MAX)) {
+ spapr_hcall_fn fn = svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
+
+ if (fn) {
+ return fn(cpu, spapr, opcode, args);
+ }
} else if ((opcode >= KVMPPC_HCALL_BASE) &&
(opcode <= KVMPPC_HCALL_MAX)) {
spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];