diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2012-10-08 18:17:36 +0000 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2012-10-29 11:45:54 +0100 |
commit | c89d52997cf4849a9ee16b5d2cf462d0cd137634 (patch) | |
tree | f7df605ebd1f171f584cec1ffa71c674d69dc2f1 | |
parent | 094b287f0b3b79d1e68df8f3a63cb144ec9cdfb6 (diff) |
pseries: Don't allow duplicate registration of hcalls or RTAS calls
Currently the pseries machine code allows a callback to be registered
for a hypercall number twice, as long as it's the same callback the second
time. We don't test for duplicate registrations of RTAS callbacks at all
so it will effectively be last registratiojn wins.
This was originally done because it was awkward to ensure that the
registration happened exactly once, but the code has since been
restructured so that's no longer the case.
Duplicate registration of a hypercall or RTAS call could well suggest
a duplicate initialization which could cause other problems, so this patch
makes duplicate registrations a bug, to prevent the old behaviour from
hiding other bugs.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | hw/spapr_hcall.c | 3 | ||||
-rw-r--r-- | hw/spapr_rtas.c | 9 |
2 files changed, 10 insertions, 2 deletions
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c index 194d9c24b5..762493a0f7 100644 --- a/hw/spapr_hcall.c +++ b/hw/spapr_hcall.c @@ -670,11 +670,10 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) } else { assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)); - slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; } - assert(!(*slot) || (fn == *slot)); + assert(!(*slot)); *slot = fn; } diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c index 67da27ba51..ce76c5856a 100644 --- a/hw/spapr_rtas.c +++ b/hw/spapr_rtas.c @@ -241,6 +241,15 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr, void spapr_rtas_register(const char *name, spapr_rtas_fn fn) { + int i; + + for (i = 0; i < (rtas_next - rtas_table); i++) { + if (strcmp(name, rtas_table[i].name) == 0) { + fprintf(stderr, "RTAS call \"%s\" registered twice\n", name); + exit(1); + } + } + assert(rtas_next < (rtas_table + TOKEN_MAX)); rtas_next->name = name; |