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 \
--- /dev/null
+/*
+ * DebugFS interface
+ * (c) Patrick Bridges and Philip Soltero, 2011
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <interfaces/vmm_mcheck.h>
+
+#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);
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
--- /dev/null
+/*
+ * V3 ECC DRAM Scrubber MCE
+ * (c) Philip Soltero, 2010
+ */
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#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 <vm_device> <cpu> <hex address>\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;
+}
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,