Skip to content

Commit

Permalink
Add QMP callback stub
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewFasano committed Dec 1, 2023
1 parent 6cc2d30 commit ac62025
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 7 deletions.
37 changes: 37 additions & 0 deletions panda/include/panda/callbacks/cb-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef enum panda_cb_type {
PANDA_CB_HD_WRITE, // Each HDD write
PANDA_CB_GUEST_HYPERCALL, // Hypercall from the guest (e.g. CPUID)
PANDA_CB_MONITOR, // Monitor callback
PANDA_CB_QMP, // QMP callback
PANDA_CB_CPU_RESTORE_STATE, // In cpu_restore_state() (fault/exception)
PANDA_CB_BEFORE_LOADVM, // at start of replay, before loadvm
PANDA_CB_ASID_CHANGED, // When CPU asid (address space identifier) changes
Expand Down Expand Up @@ -592,6 +593,24 @@ typedef union panda_cb {
*/
int (*monitor)(Monitor *mon, const char *cmd);

/* Callback ID: PANDA_CB_QMP
qmp:
Called when someone sends an unhandled QMP command
Arguments:
QmpCommand *command: a pointer to the QMP command
QDict *dict: a pointer to the QDict containing the command
QObject **ret: a pointer to the return value
Error **errp: a pointer to the error value
Helper call location: TBA
Return value:
bool: true IFF the command was handled by the plugin
*/
bool (*qmp)(const char *command, QDict *dict, QObject **ret, Error **errp);


/* Callback ID: PANDA_CB_CPU_RESTORE_STATE
Expand Down Expand Up @@ -1544,6 +1563,24 @@ typedef union panda_cb_with_context {
*/
int (*monitor)(void* context, Monitor *mon, const char *cmd);

/* Callback ID: PANDA_CB_QMP
qmp:
Called when someone sends an unhandled QMP command
Arguments:
QmpCommand *command: a pointer to the QMP command
QDict *dict: a pointer to the QDict containing the command
QObject **ret: a pointer to the return value
Error **errp: a pointer to the error value
Helper call location: TBA
Return value:
bool: true IFF the command was handled by the plugin
*/
bool (*qmp)(void* context, const char *command, QDict *dict, QObject **ret, Error **errp);


/* Callback ID: PANDA_CB_CPU_RESTORE_STATE
Expand Down
1 change: 1 addition & 0 deletions panda/include/panda/callbacks/cb-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool panda_callbacks_after_find_fast(CPUState *cpu, TranslationBlock *tb, bool b
int panda_callbacks_insn_exec(CPUState *env, target_ptr_t pc);
int panda_callbacks_after_insn_exec(CPUState *env, target_ptr_t pc);
int panda_callbacks_monitor(Monitor *mon, const char *cmd);
bool panda_callbacks_qmp(const char *command, QDict *dict, QObject **ret, Error **errp);
int panda_callbacks_before_loadvm(void);
void panda_callbacks_replay_hd_transfer(CPUState *env, uint32_t type, target_ptr_t src_addr, target_ptr_t dest_addr, size_t num_bytes);
void panda_callbacks_after_machine_init(CPUState *env);
Expand Down
1 change: 1 addition & 0 deletions panda/include/panda/callbacks/cb-trampolines.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void panda_cb_trampoline_phys_mem_after_write(void* context, CPUState *env, targ
int panda_cb_trampoline_insn_exec(void* context, CPUState *env, target_ptr_t pc);
int panda_cb_trampoline_after_insn_exec(void* context, CPUState *env, target_ptr_t pc);
int panda_cb_trampoline_monitor(void* context, Monitor *mon, const char *cmd);
bool panda_cb_trampoline_qmp(void* context, const char *command, QDict *dict, QObject **ret, Error **errp);
//int panda_cb_trampoline_before_loadvm(void* context);
void panda_cb_trampoline_replay_hd_transfer(void* context, CPUState *env, uint32_t type, target_ptr_t src_addr, target_ptr_t dest_addr, size_t num_bytes);
void panda_cb_trampoline_after_machine_init(void* context, CPUState *env);
Expand Down
1 change: 1 addition & 0 deletions panda/src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ panda_cb_with_context panda_get_cb_trampoline(panda_cb_type type) {
CASE_CB_TRAMPOLINE(HD_WRITE,hd_write)
CASE_CB_TRAMPOLINE(GUEST_HYPERCALL,guest_hypercall)
CASE_CB_TRAMPOLINE(MONITOR,monitor)
CASE_CB_TRAMPOLINE(QMP,qmp)
CASE_CB_TRAMPOLINE(CPU_RESTORE_STATE,cpu_restore_state)

//CASE_CB_TRAMPOLINE(BEFORE_LOADVM,before_loadvm)
Expand Down
5 changes: 5 additions & 0 deletions panda/src/cb-support.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include "exec/cpu-common.h"
#include "exec/ram_addr.h"

// For QDict
#include "qapi/qmp/qdict.h"

// For each callback, use MAKE_CALLBACK or MAKE_REPLAY_ONLY_CALLBACK as defined in
#include "panda/callbacks/cb-macros.h"
#include "panda/callbacks/cb-trampolines.h"
Expand Down Expand Up @@ -101,7 +104,9 @@ void panda_cb_trampoline_start_block_exec(void* context, CPUState *cpu, Translat
// these aren't used
MAKE_CALLBACK(void, HD_READ, hd_read, CPUState*, env);
MAKE_CALLBACK(void, HD_WRITE, hd_write, CPUState*, env);

MAKE_CALLBACK(int, MONITOR, monitor, Monitor*, mon, const char*, cmd);
MAKE_CALLBACK(bool, QMP, qmp, const char*, cmd, QDict*, dict, QObject**, ret, Error**, errp);

// Helper - get a physical address
static inline hwaddr get_paddr(CPUState *cpu, target_ptr_t addr, void *ram_ptr) {
Expand Down
24 changes: 17 additions & 7 deletions qapi/qmp-dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "qapi/qmp/qjson.h"
#include "qapi-types.h"
#include "qapi/qmp/qerror.h"
//#include "panda/callbacks/cb-support.h"
extern bool panda_callbacks_qmp(const char *command, QDict *dict, QObject **ret, Error **errp);

static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
{
Expand Down Expand Up @@ -83,24 +85,32 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,

command = qdict_get_str(dict, "execute");
cmd = qmp_find_command(cmds, command);

if (!qdict_haskey(dict, "arguments")) {
args = qdict_new();
} else {
args = qdict_get_qdict(dict, "arguments");
QINCREF(args);
}

if (cmd == NULL) {
// Check if this is a PANDA supported command and dispatch if so we're done
if (panda_callbacks_qmp(command, dict, &ret, errp)) {
// XXX callback needs to populate ret, might be hard
return ret;
}

error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has not been found", command);
return NULL;
}

if (!cmd->enabled) {
error_setg(errp, "The command %s has been disabled for this instance",
command);
return NULL;
}

if (!qdict_haskey(dict, "arguments")) {
args = qdict_new();
} else {
args = qdict_get_qdict(dict, "arguments");
QINCREF(args);
}

cmd->fn(args, &ret, &local_err);
if (local_err) {
error_propagate(errp, local_err);
Expand Down

0 comments on commit ac62025

Please sign in to comment.