From: Jack Lange Date: Fri, 6 Feb 2009 23:03:00 +0000 (-0600) Subject: added 64 bit emulated instruction forms X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=c9dc7207b3bd4ccfcc185798415eddfdd09ae641;p=palacios.git added 64 bit emulated instruction forms --- diff --git a/palacios/include/palacios/vmm_instr_emulator.h b/palacios/include/palacios/vmm_instr_emulator.h index 6e382c6..ebe5ac6 100644 --- a/palacios/include/palacios/vmm_instr_emulator.h +++ b/palacios/include/palacios/vmm_instr_emulator.h @@ -21,7 +21,7 @@ -#define MAKE_1OP_8FLAGS_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \ +#define MAKE_1OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * flags) { \ uchar_t tmp_dst = *dst; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -43,7 +43,7 @@ \ } -#define MAKE_1OP_16FLAGS_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \ +#define MAKE_1OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * flags) { \ ushort_t tmp_dst = *dst; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -65,7 +65,7 @@ \ } -#define MAKE_1OP_32FLAGS_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \ +#define MAKE_1OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * flags) { \ uint_t tmp_dst = *dst; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -87,7 +87,7 @@ \ } -#define MAKE_1OP_64FLAGS_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \ +#define MAKE_1OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * flags) { \ ullong_t tmp_dst = *dst; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -111,7 +111,7 @@ -#define MAKE_1OP_8_WINST(iname) static inline void iname##8(addr_t * dst) { \ +#define MAKE_1OP_8_INST(iname) static inline void iname##8(addr_t * dst) { \ uchar_t tmp_dst = *dst; \ \ asm volatile ( \ @@ -122,7 +122,7 @@ *dst = tmp_dst; \ } -#define MAKE_1OP_16_WINST(iname) static inline void iname##16(addr_t * dst) { \ +#define MAKE_1OP_16_INST(iname) static inline void iname##16(addr_t * dst) { \ ushort_t tmp_dst = *dst; \ \ asm volatile ( \ @@ -133,7 +133,7 @@ *dst = tmp_dst; \ } -#define MAKE_1OP_32_WINST(iname) static inline void iname##32(addr_t * dst) { \ +#define MAKE_1OP_32_INST(iname) static inline void iname##32(addr_t * dst) { \ uint_t tmp_dst = *dst; \ \ asm volatile ( \ @@ -144,7 +144,7 @@ *dst = tmp_dst; \ } -#define MAKE_1OP_64_WINST(iname) static inline void iname##64(addr_t * dst) { \ +#define MAKE_1OP_64_INST(iname) static inline void iname##64(addr_t * dst) { \ ullong_t tmp_dst = *dst; \ \ asm volatile ( \ @@ -156,7 +156,7 @@ } -#define MAKE_2OP_64FLAGS_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \ +#define MAKE_2OP_64FLAGS_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src, addr_t * flags) { \ uint64_t tmp_dst = *dst, tmp_src = *src; \ addr_t tmp_flags = *flags; \ \ @@ -184,7 +184,7 @@ -#define MAKE_2OP_32FLAGS_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \ +#define MAKE_2OP_32FLAGS_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src, addr_t * flags) { \ uint32_t tmp_dst = *dst, tmp_src = *src; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -207,7 +207,7 @@ } -#define MAKE_2OP_16FLAGS_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \ +#define MAKE_2OP_16FLAGS_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src, addr_t * flags) { \ ushort_t tmp_dst = *dst, tmp_src = *src; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -229,7 +229,7 @@ \ } -#define MAKE_2OP_8FLAGS_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \ +#define MAKE_2OP_8FLAGS_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src, addr_t * flags) { \ uchar_t tmp_dst = *dst, tmp_src = *src; \ \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -255,7 +255,7 @@ -#define MAKE_2OP_64STR_WINST(iname) static inline void iname##64(addr_t * dst, \ +#define MAKE_2OP_64STR_INST(iname) static inline void iname##64(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -279,7 +279,7 @@ } -#define MAKE_2OP_32STR_WINST(iname) static inline void iname##32(addr_t * dst, \ +#define MAKE_2OP_32STR_INST(iname) static inline void iname##32(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -302,7 +302,7 @@ *flags |= flags_rsvd; \ } -#define MAKE_2OP_16STR_WINST(iname) static inline void iname##16(addr_t * dst, \ +#define MAKE_2OP_16STR_INST(iname) static inline void iname##16(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -325,7 +325,7 @@ -#define MAKE_2OP_8STR_WINST(iname) static inline void iname##8(addr_t * dst, \ +#define MAKE_2OP_8STR_INST(iname) static inline void iname##8(addr_t * dst, \ addr_t * src, \ addr_t * ecx, addr_t * flags) { \ /* Some of the flags values are not copied out in a pushf, we save them here */ \ @@ -349,7 +349,7 @@ -#define MAKE_2OP_64_WINST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ +#define MAKE_2OP_64_INST(iname) static inline void iname##64(addr_t * dst, addr_t * src) { \ uint32_t tmp_dst = *dst, tmp_src = *src; \ \ asm volatile ( \ @@ -360,7 +360,7 @@ *dst = tmp_dst; \ } -#define MAKE_2OP_32_WINST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ +#define MAKE_2OP_32_INST(iname) static inline void iname##32(addr_t * dst, addr_t * src) { \ uint32_t tmp_dst = *dst, tmp_src = *src; \ \ asm volatile ( \ @@ -371,7 +371,7 @@ *dst = tmp_dst; \ } -#define MAKE_2OP_16_WINST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ +#define MAKE_2OP_16_INST(iname) static inline void iname##16(addr_t * dst, addr_t * src) { \ ushort_t tmp_dst = *dst, tmp_src = *src; \ \ asm volatile ( \ @@ -382,7 +382,7 @@ *dst = tmp_dst; \ } -#define MAKE_2OP_8_WINST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ +#define MAKE_2OP_8_INST(iname) static inline void iname##8(addr_t * dst, addr_t * src) { \ uchar_t tmp_dst = *dst, tmp_src = *src; \ \ asm volatile ( \ @@ -397,82 +397,115 @@ +/****************************/ +/* 8 Bit instruction forms */ +/****************************/ +MAKE_2OP_8FLAGS_INST(adc); +MAKE_2OP_8FLAGS_INST(add); +MAKE_2OP_8FLAGS_INST(and); +MAKE_2OP_8FLAGS_INST(or); +MAKE_2OP_8FLAGS_INST(xor); +MAKE_2OP_8FLAGS_INST(sub); -MAKE_2OP_8FLAGS_WINST(adc); -MAKE_2OP_8FLAGS_WINST(add); -MAKE_2OP_8FLAGS_WINST(and); -MAKE_2OP_8FLAGS_WINST(or); -MAKE_2OP_8FLAGS_WINST(xor); -MAKE_2OP_8FLAGS_WINST(sub); +MAKE_1OP_8FLAGS_INST(inc); +MAKE_1OP_8FLAGS_INST(dec); +MAKE_1OP_8FLAGS_INST(neg); +MAKE_1OP_8FLAGS_INST(setb); +MAKE_1OP_8FLAGS_INST(setbe); +MAKE_1OP_8FLAGS_INST(setl); +MAKE_1OP_8FLAGS_INST(setle); +MAKE_1OP_8FLAGS_INST(setnb); +MAKE_1OP_8FLAGS_INST(setnbe); +MAKE_1OP_8FLAGS_INST(setnl); +MAKE_1OP_8FLAGS_INST(setnle); +MAKE_1OP_8FLAGS_INST(setno); +MAKE_1OP_8FLAGS_INST(setnp); +MAKE_1OP_8FLAGS_INST(setns); +MAKE_1OP_8FLAGS_INST(setnz); +MAKE_1OP_8FLAGS_INST(seto); +MAKE_1OP_8FLAGS_INST(setp); +MAKE_1OP_8FLAGS_INST(sets); +MAKE_1OP_8FLAGS_INST(setz); -MAKE_1OP_8FLAGS_WINST(inc); -MAKE_1OP_8FLAGS_WINST(dec); -MAKE_1OP_8FLAGS_WINST(neg); -MAKE_1OP_8FLAGS_WINST(setb); -MAKE_1OP_8FLAGS_WINST(setbe); -MAKE_1OP_8FLAGS_WINST(setl); -MAKE_1OP_8FLAGS_WINST(setle); -MAKE_1OP_8FLAGS_WINST(setnb); -MAKE_1OP_8FLAGS_WINST(setnbe); -MAKE_1OP_8FLAGS_WINST(setnl); -MAKE_1OP_8FLAGS_WINST(setnle); -MAKE_1OP_8FLAGS_WINST(setno); -MAKE_1OP_8FLAGS_WINST(setnp); -MAKE_1OP_8FLAGS_WINST(setns); -MAKE_1OP_8FLAGS_WINST(setnz); -MAKE_1OP_8FLAGS_WINST(seto); -MAKE_1OP_8FLAGS_WINST(setp); -MAKE_1OP_8FLAGS_WINST(sets); -MAKE_1OP_8FLAGS_WINST(setz); +MAKE_1OP_8_INST(not); -MAKE_1OP_8_WINST(not); +MAKE_2OP_8_INST(mov); +MAKE_2OP_8_INST(xchg); -MAKE_2OP_8_WINST(mov); -MAKE_2OP_8_WINST(xchg); +MAKE_2OP_8STR_INST(movs); +/****************************/ +/* 16 Bit instruction forms */ +/****************************/ +MAKE_2OP_16FLAGS_INST(adc); +MAKE_2OP_16FLAGS_INST(add); +MAKE_2OP_16FLAGS_INST(and); +MAKE_2OP_16FLAGS_INST(or); +MAKE_2OP_16FLAGS_INST(xor); +MAKE_2OP_16FLAGS_INST(sub); -MAKE_2OP_16FLAGS_WINST(adc); -MAKE_2OP_16FLAGS_WINST(add); -MAKE_2OP_16FLAGS_WINST(and); -MAKE_2OP_16FLAGS_WINST(or); -MAKE_2OP_16FLAGS_WINST(xor); -MAKE_2OP_16FLAGS_WINST(sub); +MAKE_1OP_16FLAGS_INST(inc); +MAKE_1OP_16FLAGS_INST(dec); +MAKE_1OP_16FLAGS_INST(neg); -MAKE_1OP_16FLAGS_WINST(inc); -MAKE_1OP_16FLAGS_WINST(dec); -MAKE_1OP_16FLAGS_WINST(neg); +MAKE_1OP_16_INST(not); -MAKE_1OP_16_WINST(not); +MAKE_2OP_16_INST(mov); +MAKE_2OP_16_INST(xchg); -MAKE_2OP_16_WINST(mov); -MAKE_2OP_16_WINST(xchg); +MAKE_2OP_16STR_INST(movs); +/****************************/ +/* 32 Bit instruction forms */ +/****************************/ +MAKE_2OP_32FLAGS_INST(adc); +MAKE_2OP_32FLAGS_INST(add); +MAKE_2OP_32FLAGS_INST(and); +MAKE_2OP_32FLAGS_INST(or); +MAKE_2OP_32FLAGS_INST(xor); +MAKE_2OP_32FLAGS_INST(sub); +MAKE_1OP_32FLAGS_INST(inc); +MAKE_1OP_32FLAGS_INST(dec); +MAKE_1OP_32FLAGS_INST(neg); +MAKE_1OP_32_INST(not); -MAKE_2OP_32FLAGS_WINST(adc); -MAKE_2OP_32FLAGS_WINST(add); -MAKE_2OP_32FLAGS_WINST(and); -MAKE_2OP_32FLAGS_WINST(or); -MAKE_2OP_32FLAGS_WINST(xor); -MAKE_2OP_32FLAGS_WINST(sub); +MAKE_2OP_32_INST(mov); +MAKE_2OP_32_INST(xchg); -MAKE_1OP_32FLAGS_WINST(inc); -MAKE_1OP_32FLAGS_WINST(dec); -MAKE_1OP_32FLAGS_WINST(neg); -MAKE_1OP_32_WINST(not); +MAKE_2OP_32STR_INST(movs); -MAKE_2OP_32_WINST(mov); -MAKE_2OP_32_WINST(xchg); +#ifdef __V3_64BIT__ -MAKE_2OP_8STR_WINST(movs); -MAKE_2OP_16STR_WINST(movs); -MAKE_2OP_32STR_WINST(movs); +/****************************/ +/* 64 Bit instruction forms */ +/****************************/ +MAKE_2OP_64FLAGS_INST(adc); +MAKE_2OP_64FLAGS_INST(add); +MAKE_2OP_64FLAGS_INST(and); +MAKE_2OP_64FLAGS_INST(or); +MAKE_2OP_64FLAGS_INST(xor); +MAKE_2OP_64FLAGS_INST(sub); + +MAKE_1OP_64FLAGS_INST(inc); +MAKE_1OP_64FLAGS_INST(dec); +MAKE_1OP_64FLAGS_INST(neg); + +MAKE_1OP_64_INST(not); + + +MAKE_2OP_64_INST(mov); + +MAKE_2OP_64_INST(xchg); + + +#endif diff --git a/palacios/src/palacios/vmm_emulator.c b/palacios/src/palacios/vmm_emulator.c index 9c91ec5..2870ba0 100644 --- a/palacios/src/palacios/vmm_emulator.c +++ b/palacios/src/palacios/vmm_emulator.c @@ -32,8 +32,6 @@ - - static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int op_size); // We emulate up to the next 4KB page boundry @@ -502,9 +500,56 @@ static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_add return -1; } +#ifdef __V3_64BIT__ } else if (op_size == 8) { - PrintError("64 bit instructions not handled\n"); - return -1; + + + switch (op_type) { + case V3_OP_ADC: + adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_ADD: + add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_AND: + and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_OR: + or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_XOR: + xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_SUB: + sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + + case V3_OP_INC: + inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_DEC: + dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + case V3_OP_NEG: + neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags)); + break; + + case V3_OP_MOV: + mov64((addr_t *)dst_addr, (addr_t *)src_addr); + break; + case V3_OP_NOT: + not64((addr_t *)dst_addr); + break; + case V3_OP_XCHG: + xchg64((addr_t *)dst_addr, (addr_t *)src_addr); + break; + + default: + PrintError("Unknown 64 bit instruction\n"); + return -1; + } +#endif + } else { PrintError("Invalid Operation Size\n"); return -1;