@@ -853,6 +853,23 @@ static int prepare_payload(struct payload *payload,
#endif
}
+ sec = livepatch_elf_sec_by_name(elf, ".modinfo");
+ if ( sec )
+ {
+ if ( !section_ok(elf, sec, sizeof(*payload->metadata.data)) )
+ return -EINVAL;
+
+ payload->metadata.data = sec->load_addr;
+ payload->metadata.len = sec->sec->sh_size;
+
+ /* The metadata is required to consists of null terminated strings. */
+ if ( payload->metadata.data[payload->metadata.len - 1] != '\0' )
+ {
+ printk(XENLOG_ERR LIVEPATCH "%s: Incorrect metadata format detected\n", payload->name);
+ return -EINVAL;
+ }
+ }
+
return 0;
}
@@ -1201,6 +1218,19 @@ static int livepatch_list(struct xen_sysctl_livepatch_list *list)
* for XEN_SYSCTL_LIVEPATCH_ACTION operation (see livepatch_action).
*/
+static inline void livepatch_display_metadata(const struct livepatch_metadata *metadata)
+{
+ const char *str;
+
+ if ( metadata && metadata->data && metadata->len > 0 )
+ {
+ printk(XENLOG_INFO LIVEPATCH "module metadata:\n");
+ for ( str = metadata->data; str < (metadata->data + metadata->len); str += (strlen(str) + 1) )
+ printk(XENLOG_INFO LIVEPATCH " %s\n", str);
+ }
+
+}
+
static int apply_payload(struct payload *data)
{
unsigned int i;
@@ -1233,6 +1263,8 @@ static int apply_payload(struct payload *data)
arch_livepatch_revive();
+ livepatch_display_metadata(&data->metadata);
+
return 0;
}
@@ -2008,6 +2040,8 @@ static void livepatch_printall(unsigned char key)
data->name, state2str(data->state), data->state, data->text_addr,
data->rw_addr, data->ro_addr, data->pages);
+ livepatch_display_metadata(&data->metadata);
+
for ( i = 0; i < data->nfuncs; i++ )
{
struct livepatch_func *f = &(data->funcs[i]);
@@ -33,6 +33,11 @@ struct livepatch_hooks {
} apply, revert;
};
+struct livepatch_metadata {
+ const char *data; /* Ptr to .modinfo section with ASCII data. */
+ uint32_t len; /* Length of the metadata section. */
+};
+
struct payload {
uint32_t state; /* One of the LIVEPATCH_STATE_*. */
int32_t rc; /* 0 or -XEN_EXX. */
@@ -63,6 +68,7 @@ struct payload {
unsigned int n_load_funcs; /* Nr of the funcs to load and execute. */
unsigned int n_unload_funcs; /* Nr of funcs to call durung unload. */
char name[XEN_LIVEPATCH_NAME_SIZE]; /* Name of it. */
+ struct livepatch_metadata metadata; /* Module meta data record */
};
/*
@@ -79,9 +79,17 @@ config.h: xen_hello_world_func.o
xen_hello_world.o: config.h
.PHONY: $(LIVEPATCH)
-$(LIVEPATCH): xen_hello_world_func.o xen_hello_world.o note.o xen_note.o
+$(LIVEPATCH): xen_hello_world_func.o xen_hello_world.o note.o xen_note.o modinfo.o
$(LD) $(LDFLAGS) $(build_id_linker) -r -o $(LIVEPATCH) $^
+.PHONY: modinfo.o
+modinfo.o:
+ (set -e; \
+ printf "LIVEPATCH_RULEZ\0") > $@.bin
+ $(OBJCOPY) $(OBJCOPY_MAGIC) \
+ --rename-section=.data=.modinfo,alloc,load,readonly,data,contents -S $@.bin $@
+ #rm -f $@.bin
+
#
# This target is only accessible if CONFIG_LIVEPATCH is defined, which
# depends on $(build_id_linker) being available. Hence we do not