From 06484a82beb6e712f4ae3b28dd4adbba3b301c69 Mon Sep 17 00:00:00 2001 From: maxv Date: Tue, 8 Jan 2019 07:34:22 +0000 Subject: [PATCH] Handle REPN. FreeBSD has a "repn movs", which is a bit unusual, but doesn't seem illegal as far as I can tell from the AMD SDM. With that, I can boot FreeBSD on Qemu+NVMM. --- lib/libnvmm/libnvmm_x86.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/libnvmm/libnvmm_x86.c b/lib/libnvmm/libnvmm_x86.c index f22a4b75ed57..5d466d88d697 100644 --- a/lib/libnvmm/libnvmm_x86.c +++ b/lib/libnvmm/libnvmm_x86.c @@ -1,4 +1,4 @@ -/* $NetBSD: libnvmm_x86.c,v 1.13 2019/01/07 18:13:34 maxv Exp $ */ +/* $NetBSD: libnvmm_x86.c,v 1.14 2019/01/08 07:34:22 maxv Exp $ */ /* * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -2902,11 +2902,6 @@ nvmm_assist_mem(struct nvmm_machine *mach, nvmm_cpuid_t cpuid, return -1; } - if (__predict_false(instr.legpref.repn)) { - errno = ENODEV; - return -1; - } - if (instr.opcode->movs) { ret = assist_mem_double(mach, &state, &instr); } else { @@ -2917,10 +2912,14 @@ nvmm_assist_mem(struct nvmm_machine *mach, nvmm_cpuid_t cpuid, return -1; } - if (instr.legpref.rep) { + if (instr.legpref.rep || instr.legpref.repn) { cnt = rep_dec_apply(&state, instr.address_size); if (cnt == 0) { state.gprs[NVMM_X64_GPR_RIP] += instr.len; + } else if (__predict_false(instr.legpref.repn)) { + if (state.gprs[NVMM_X64_GPR_RFLAGS] & PSL_Z) { + state.gprs[NVMM_X64_GPR_RIP] += instr.len; + } } } else { state.gprs[NVMM_X64_GPR_RIP] += instr.len;