mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
xm: New command 'debug-keys' to inject debug-key events into Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
f064d42ef8
commit
e1bc13a960
9 files changed
+88
-3
No files matched your search
@@ -33,6 +33,25 @@ int xc_readconsolering(int xc_handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_send_debug_keys(int xc_handle, char *keys)
|
||||
{
|
||||
int ret, len = strlen(keys);
|
||||
DECLARE_SYSCTL;
|
||||
|
||||
sysctl.cmd = XEN_SYSCTL_debug_keys;
|
||||
set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
|
||||
sysctl.u.debug_keys.nr_keys = len;
|
||||
|
||||
if ( (ret = lock_pages(keys, len)) != 0 )
|
||||
return ret;
|
||||
|
||||
ret = do_sysctl(xc_handle, &sysctl);
|
||||
|
||||
unlock_pages(keys, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_physinfo(int xc_handle,
|
||||
xc_physinfo_t *put_info)
|
||||
{
|
||||
|
||||
@@ -467,6 +467,8 @@ int xc_readconsolering(int xc_handle,
|
||||
unsigned int *pnr_chars,
|
||||
int clear);
|
||||
|
||||
int xc_send_debug_keys(int xc_handle, char *keys);
|
||||
|
||||
typedef xen_sysctl_physinfo_t xc_physinfo_t;
|
||||
int xc_physinfo(int xc_handle,
|
||||
xc_physinfo_t *info);
|
||||
|
||||
@@ -1007,6 +1007,24 @@ static PyObject *pyxc_domain_send_trigger(XcObject *self,
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_send_debug_keys(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
char *keys;
|
||||
|
||||
static char *kwd_list[] = { "keys", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *dom_op(XcObject *self, PyObject *args,
|
||||
int (*fn)(int, uint32_t))
|
||||
{
|
||||
@@ -1420,6 +1438,12 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" vcpu [int]: VCPU to be sent trigger.\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "send_debug_keys",
|
||||
(PyCFunction)pyxc_send_debug_keys,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Inject debug keys into Xen.\n"
|
||||
" keys [str]: String of keys to inject.\n" },
|
||||
|
||||
#ifdef __powerpc__
|
||||
{ "arch_alloc_real_mode_area",
|
||||
(PyCFunction)pyxc_alloc_real_mode_area,
|
||||
|
||||
@@ -453,6 +453,12 @@ class XendNode:
|
||||
return pif.network
|
||||
raise Exception('Bridge %s is not connected to a network' % bridge)
|
||||
|
||||
#
|
||||
# Debug keys.
|
||||
#
|
||||
|
||||
def send_debug_keys(self, keys):
|
||||
return self.xc.send_debug_keys(keys)
|
||||
|
||||
#
|
||||
# Getting host information.
|
||||
|
||||
@@ -157,7 +157,7 @@ class XMLRPCServer:
|
||||
self.server.register_function(fn, "xend.domain.%s" % name[7:])
|
||||
|
||||
# Functions in XendNode and XendDmesg
|
||||
for type, lst, n in [(XendNode, ['info'], 'node'),
|
||||
for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'),
|
||||
(XendDmesg, ['info', 'clear'], 'node.dmesg')]:
|
||||
inst = type.instance()
|
||||
for name in lst:
|
||||
|
||||
@@ -133,6 +133,7 @@ SUBCOMMAND_HELP = {
|
||||
'sched-credit': ('[-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]',
|
||||
'Get/set credit scheduler parameters.'),
|
||||
'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
|
||||
'debug-keys' : ('<Keys>', 'Send debug keys to Xen.'),
|
||||
'trigger' : ('<Domain> <nmi|reset|init> [<VCPU>]',
|
||||
'Send a trigger to a domain.'),
|
||||
'vcpu-list' : ('[<Domain>]',
|
||||
@@ -260,7 +261,6 @@ common_commands = [
|
||||
"shutdown",
|
||||
"start",
|
||||
"suspend",
|
||||
"trigger",
|
||||
"top",
|
||||
"unpause",
|
||||
"uptime",
|
||||
@@ -300,6 +300,7 @@ domain_commands = [
|
||||
]
|
||||
|
||||
host_commands = [
|
||||
"debug-keys",
|
||||
"dmesg",
|
||||
"info",
|
||||
"log",
|
||||
@@ -1395,6 +1396,10 @@ def xm_trigger(args):
|
||||
|
||||
server.xend.domain.send_trigger(dom, trigger, vcpu)
|
||||
|
||||
def xm_debug_keys(args):
|
||||
arg_check(args, "debug-keys", 1)
|
||||
server.xend.node.send_debug_keys(str(args[0]))
|
||||
|
||||
def xm_top(args):
|
||||
arg_check(args, "top", 0)
|
||||
|
||||
@@ -1738,6 +1743,7 @@ commands = {
|
||||
"pause": xm_pause,
|
||||
"unpause": xm_unpause,
|
||||
# host commands
|
||||
"debug-keys": xm_debug_keys,
|
||||
"dmesg": xm_dmesg,
|
||||
"info": xm_info,
|
||||
"log": xm_log,
|
||||
|
||||
@@ -47,7 +47,7 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
|
||||
{
|
||||
irq_keyhandler_t *h;
|
||||
|
||||
if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
|
||||
if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
|
||||
{
|
||||
console_start_log_everything();
|
||||
if ( (h = key_table[key].u.irq_handler) != NULL )
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <xen/console.h>
|
||||
#include <xen/iocap.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/keyhandler.h>
|
||||
#include <asm/current.h>
|
||||
#include <public/sysctl.h>
|
||||
|
||||
@@ -121,6 +122,20 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case XEN_SYSCTL_debug_keys:
|
||||
{
|
||||
char c;
|
||||
uint32_t i;
|
||||
|
||||
for ( i = 0; i < op->u.debug_keys.nr_keys; i++ )
|
||||
{
|
||||
if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) )
|
||||
return -EFAULT;
|
||||
handle_keypress(c, guest_cpu_user_regs());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = arch_do_sysctl(op, u_sysctl);
|
||||
break;
|
||||
|
||||
@@ -140,6 +140,18 @@ struct xen_sysctl_getdomaininfolist {
|
||||
typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
|
||||
|
||||
/*
|
||||
* Inject debug keys into Xen.
|
||||
*/
|
||||
#define XEN_SYSCTL_debug_keys 7
|
||||
struct xen_sysctl_debug_keys {
|
||||
/* IN variables. */
|
||||
XEN_GUEST_HANDLE_64(char) keys;
|
||||
uint32_t nr_keys;
|
||||
};
|
||||
typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t);
|
||||
|
||||
struct xen_sysctl {
|
||||
uint32_t cmd;
|
||||
uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
|
||||
@@ -150,6 +162,7 @@ struct xen_sysctl {
|
||||
struct xen_sysctl_sched_id sched_id;
|
||||
struct xen_sysctl_perfc_op perfc_op;
|
||||
struct xen_sysctl_getdomaininfolist getdomaininfolist;
|
||||
struct xen_sysctl_debug_keys debug_keys;
|
||||
uint8_t pad[128];
|
||||
} u;
|
||||
};
|
||||
|
||||