From 72bf7c1f53be3d4152113e7e64148c1ac150d18a Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 5 Apr 2023 12:15:58 +0200 Subject: [PATCH] --- tools/include/xenctrl.h | 3 +++ tools/libs/ctrl/xc_misc.c | 15 +++++++++++++++ tools/misc/xen-livepatch.c | 25 +++++++++++++++++++++++++ xen/common/Makefile | 2 +- xen/common/livepatch-test.c | 20 ++++++++++++++++++++ xen/common/livepatch.c | 4 ++++ xen/include/public/sysctl.h | 7 +++++++ xen/include/xen/livepatch.h | 4 ++++ xen/test/livepatch/test.patch | 13 +++++++++++++ 9 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 xen/common/livepatch-test.c create mode 100644 xen/test/livepatch/test.patch diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 05967ecc92..d8aea225aa 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -2629,6 +2629,9 @@ int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout, uint32_ int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout, uint32_t flags); int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout, uint32_t flags); +/* Dummy hypercall to test livepatch functionality. */ +int xc_livepatch_test(xc_interface *xch, uint32_t *result); + /* * Ensure cache coherency after memory modifications. A call to this function * is only required on ARM as the x86 architecture provides cache coherency diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c index 265f15ec2d..b4c986584e 100644 --- a/tools/libs/ctrl/xc_misc.c +++ b/tools/libs/ctrl/xc_misc.c @@ -986,6 +986,21 @@ int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout, uint32 return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REPLACE, timeout, flags); } +int xc_livepatch_test(xc_interface *xch, uint32_t *result) +{ + int rc; + DECLARE_SYSCTL = { + .cmd = XEN_SYSCTL_livepatch_op, + .u.livepatch.cmd = XEN_SYSCTL_LIVEPATCH_TEST, + }; + + rc = do_sysctl(xch, &sysctl); + if ( !rc ) + *result = sysctl.u.livepatch.u.test.result; + + return rc; +} + /* * Local variables: * mode: C diff --git a/tools/misc/xen-livepatch.c b/tools/misc/xen-livepatch.c index 5bf9d9a32b..7c37965748 100644 --- a/tools/misc/xen-livepatch.c +++ b/tools/misc/xen-livepatch.c @@ -37,6 +37,7 @@ void show_help(void) " replace apply patch and revert all others.\n" " unload unload name patch.\n" " load [flags] upload and apply with name as the name\n" + " test print the result of the test hypercall (for testing purposes only)\n" " Supported flags:\n" " --nodeps Disable inter-module buildid dependency check.\n" " Check only against hypervisor buildid.\n", @@ -542,6 +543,29 @@ error: return rc; } +static int test_func(int argc, char *argv[]) +{ + int rc; + uint32_t result; + + if ( argc != 0 ) + { + show_help(); + return -1; + } + + rc = xc_livepatch_test(xch, &result); + if ( rc ) + { + fprintf(stderr, "test operation failed: %s\n", strerror(errno)); + return -1; + } + + printf("%u\n", result); + + return 0; +} + /* * These are also functions in action_options that are called in case * none of the ones in main_options match. @@ -554,6 +578,7 @@ struct { { "list", list_func }, { "upload", upload_func }, { "load", load_func }, + { "test", test_func }, }; int main(int argc, char *argv[]) diff --git a/xen/common/Makefile b/xen/common/Makefile index 46049eac35..ec04a8782c 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -22,7 +22,7 @@ obj-y += kernel.o obj-y += keyhandler.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_KEXEC) += kimage.o -obj-$(CONFIG_LIVEPATCH) += livepatch.o livepatch_elf.o +obj-$(CONFIG_LIVEPATCH) += livepatch.o livepatch_elf.o livepatch-test.o obj-$(CONFIG_MEM_ACCESS) += mem_access.o obj-y += memory.o obj-y += multicall.o diff --git a/xen/common/livepatch-test.c b/xen/common/livepatch-test.c new file mode 100644 index 0000000000..876173ab6f --- /dev/null +++ b/xen/common/livepatch-test.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Dummy file for testing livepatch functionality. */ +#include + +int livepatch_test(struct xen_sysctl_livepatch_test *test) +{ + test->result = 2; + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index d385f882c6..25fa1deedd 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -2050,6 +2050,10 @@ int livepatch_op(struct xen_sysctl_livepatch_op *livepatch) rc = livepatch_action(&livepatch->u.action); break; + case XEN_SYSCTL_LIVEPATCH_TEST: + rc = livepatch_test(&livepatch->u.test); + break; + default: rc = -EOPNOTSUPP; break; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 2b24d6bfd0..48c97a3362 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -1010,6 +1010,12 @@ struct xen_sysctl_livepatch_action { uint32_t pad; /* IN: Always zero. */ }; +/* Dummy hypercall used for testing the generation of live patches. */ +#define XEN_SYSCTL_LIVEPATCH_TEST 4 +struct xen_sysctl_livepatch_test { + uint32_t result; /* OUT: dummy result for testing. */ +}; + struct xen_sysctl_livepatch_op { uint32_t cmd; /* IN: XEN_SYSCTL_LIVEPATCH_*. */ uint32_t pad; /* IN: Always zero. */ @@ -1018,6 +1024,7 @@ struct xen_sysctl_livepatch_op { struct xen_sysctl_livepatch_list list; struct xen_sysctl_livepatch_get get; struct xen_sysctl_livepatch_action action; + struct xen_sysctl_livepatch_test test; } u; }; diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h index 9fdb29c382..c883413748 100644 --- a/xen/include/xen/livepatch.h +++ b/xen/include/xen/livepatch.h @@ -11,6 +11,8 @@ struct livepatch_elf_sec; struct livepatch_elf_sym; struct xen_sysctl_livepatch_op; +#include + #include #include /* For -ENOSYS or -EOVERFLOW */ #ifdef CONFIG_LIVEPATCH @@ -151,6 +153,8 @@ static inline void common_livepatch_revert(struct livepatch_func *func) arch_livepatch_revert(func); func->applied = LIVEPATCH_FUNC_NOT_APPLIED; } + +int livepatch_test(struct xen_sysctl_livepatch_test *test); #else /* diff --git a/xen/test/livepatch/test.patch b/xen/test/livepatch/test.patch new file mode 100644 index 0000000000..c07d697cc8 --- /dev/null +++ b/xen/test/livepatch/test.patch @@ -0,0 +1,13 @@ +diff --git a/xen/common/livepatch-test.c b/xen/common/livepatch-test.c +index 05b638b2ac..876173ab6f 100644 +--- a/xen/common/livepatch-test.c ++++ b/xen/common/livepatch-test.c +@@ -5,7 +5,7 @@ + + int livepatch_test(struct xen_sysctl_livepatch_test *test) + { +- test->result = 1; ++ test->result = 2; + return 0; + } + -- 2.39.5