From: Patrick G. Bridges Date: Fri, 26 Aug 2011 00:49:34 +0000 (-0600) Subject: First cut at changes to enhance/fix machine check injection extension X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=2ee5d1ec27731b41027c42003608ad9c06d748e8 First cut at changes to enhance/fix machine check injection extension --- diff --git a/linux_module/Makefile b/linux_module/Makefile index 137674c..d028d2e 100644 --- a/linux_module/Makefile +++ b/linux_module/Makefile @@ -27,6 +27,7 @@ v3vee-$(V3_CONFIG_SOCKET) += iface-socket.o v3vee-$(V3_CONFIG_KEYED_STREAMS) += iface-keyed-stream.o v3vee-$(V3_CONFIG_HOST_DEVICE) += iface-host-dev.o v3vee-$(V3_CONFIG_GRAPHICS_CONSOLE) += iface-graphics-console.o +v3vee-$(V3_CONFIG_EXT_MACH_CHECK) += mcheck.o v3vee-$(V3_CONFIG_VNET) += palacios-vnet.o \ palacios-vnet-ctrl.o \ diff --git a/linux_module/mcheck.c b/linux_module/mcheck.c new file mode 100644 index 0000000..e357e94 --- /dev/null +++ b/linux_module/mcheck.c @@ -0,0 +1,57 @@ +/* + * DebugFS interface + * (c) Patrick Bridges and Philip Soltero, 2011 + */ + +#include +#include +#include +#include + +#include + +#include "palacios.h" +#include "vm.h" +#include "linux-exts.h" + +#define SCRUBBER_MCE 0x1 +#define V3_VM_INJECT_SCRUBBER_MCE (10224+20) + +static int inject_mce(struct v3_guest * guest, unsigned int cmd, unsigned long arg, + void * priv_data) +{ + unsigned long type = (unsigned long)priv_data; + switch ( type ) { + case SCRUBBER_MCE: + return v3_mcheck_inject_scrubber_mce((struct v3_vm_info *)guest->v3_ctx, 0, arg); + break; + default: + // TODO: How to print an error in the host OS? + //PrintError("Injection of unknown machine check type %lu requested.\n", type); + return -1; + break; + } +} + +static int guest_init(struct v3_guest * guest, void ** vm_data) { + + add_guest_ctrl(guest, V3_VM_INJECT_SCRUBBER_MCE, inject_mce, (void *)SCRUBBER_MCE); + return 0; +} + +static int guest_deinit(struct v3_guest * guest, void * vm_data) { + + return 0; +} + + +struct linux_ext mcheck_ext = { + .name = "MACHINE CHECK", + .init = NULL, + .deinit = NULL, + .guest_init = guest_init, + .guest_deinit = guest_deinit +}; + + +register_extension(&mcheck_ext); diff --git a/linux_usr/Makefile b/linux_usr/Makefile index 3f4aedd..a1e9bb4 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -34,8 +34,8 @@ v3_user_keyed_stream_example: v3_user_keyed_stream_example.c v3_user_keyed_strea v3_user_keyed_stream_file: v3_user_keyed_stream_file.c v3_user_keyed_stream.h v3_user_keyed_stream.c gcc -static -I../linux_module v3_user_keyed_stream_file.c v3_user_keyed_stream.c -o v3_user_keyed_stream_file - - +v3_inject_ecc_scrubber_mce: v3_inject_ecc_scrubber_mce.c + gcc -static -I../linux_module v3_inject_ecc_scrubber_mce.c -o v3_inject_ecc_scrubber_mce clean: rm -f v3_ctrl v3_cons v3_mem v3_monitor v3_stream v3_user_host_dev_example v3_os_debug v3_user_keyed_stream_example v3_user_keyed_stream_file diff --git a/linux_usr/v3_inject_ecc_scrubber_mce.c b/linux_usr/v3_inject_ecc_scrubber_mce.c new file mode 100644 index 0000000..ec98ba8 --- /dev/null +++ b/linux_usr/v3_inject_ecc_scrubber_mce.c @@ -0,0 +1,51 @@ +/* + * V3 ECC DRAM Scrubber MCE + * (c) Philip Soltero, 2010 + */ + +#include +#include +#include + +#define V3_VM_INJECT_SCRUBBER_MCE (10224+20) + +int main(int argc, char * argv[]) { + char * end_ptr; + char * vm_device; + unsigned int cpu; + uint64_t address; + int v3_fd = 0; + + if (argc <= 3) { + fprintf(stderr, "Usage: v3_inject_ecc_scrubber_mce \n"); + return -1; + } + + vm_device = argv[1]; + + cpu = strtol(argv[2], &end_ptr, 10); + if (strcmp(end_ptr, "\0") != 0) { + fprintf(stderr, "The specified cpu is not a valid integer '%s', in particular '%s'.\n", argv[2], end_ptr); + return -1; + } + + address = strtoll(argv[3], &end_ptr, 16); + if (strcmp(end_ptr, "\0") != 0) { + fprintf(stderr, "The specified address is not a valid integer '%s', in particular '%s'.\n", argv[3], end_ptr); + return -1; + } + + v3_fd = open(vm_device, O_RDONLY); + + if (v3_fd == -1) { + fprintf(stderr, "Error opening V3Vee control device.\n"); + return -1; + } + + ioctl(v3_fd, V3_VM_INJECT_SCRUBBER_MCE, address); + + /* Close the file descriptor. */ + close(v3_fd); + + return 0; +} diff --git a/palacios/src/extensions/ext_mcheck.c b/palacios/src/extensions/ext_mcheck.c index 51605ae..2ab04ca 100644 --- a/palacios/src/extensions/ext_mcheck.c +++ b/palacios/src/extensions/ext_mcheck.c @@ -545,6 +545,25 @@ int v3_mcheck_inject_nb_mce(struct v3_vm_info * const vm, const uint32_t cpu, return 0; } +int v3_mcheck_inject_scrubber_mce(struct v3_vm_info *info, int cpu, uint64_t dst) +{ + struct mc4_stat_msr stat; + struct mc4_addr_msr addr; + + stat.value = 0; + stat.error_code = 0x810; + stat.error_code_ext = 0x8; + stat.uecc = 1; + stat.addr_v = 1; + stat.en = 1; + stat.uc = 1; + stat.val = 1; + + addr.addr64 = dst; + + return v3_mcheck_inject_nb_mce(info, cpu, stat, addr); +} + static struct v3_extension_impl mcheck_impl = { .name = MCHECK, .init = init_mcheck,