diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/cpu-dump.c | 127 | ||||
-rw-r--r-- | target/i386/cpu.h | 13 | ||||
-rw-r--r-- | target/i386/sev.c | 71 | ||||
-rw-r--r-- | target/i386/tcg/cc_helper.c | 2 | ||||
-rw-r--r-- | target/i386/tcg/emit.c.inc | 4 | ||||
-rw-r--r-- | target/i386/tcg/translate.c | 21 | ||||
-rw-r--r-- | target/i386/trace-events | 2 |
7 files changed, 121 insertions, 119 deletions
diff --git a/target/i386/cpu-dump.c b/target/i386/cpu-dump.c index 40697064d9..3bb8e44091 100644 --- a/target/i386/cpu-dump.c +++ b/target/i386/cpu-dump.c @@ -28,69 +28,70 @@ /* x86 debug */ static const char *cc_op_str[CC_OP_NB] = { - "DYNAMIC", - "EFLAGS", - - "MULB", - "MULW", - "MULL", - "MULQ", - - "ADDB", - "ADDW", - "ADDL", - "ADDQ", - - "ADCB", - "ADCW", - "ADCL", - "ADCQ", - - "SUBB", - "SUBW", - "SUBL", - "SUBQ", - - "SBBB", - "SBBW", - "SBBL", - "SBBQ", - - "LOGICB", - "LOGICW", - "LOGICL", - "LOGICQ", - - "INCB", - "INCW", - "INCL", - "INCQ", - - "DECB", - "DECW", - "DECL", - "DECQ", - - "SHLB", - "SHLW", - "SHLL", - "SHLQ", - - "SARB", - "SARW", - "SARL", - "SARQ", - - "BMILGB", - "BMILGW", - "BMILGL", - "BMILGQ", - - "ADCX", - "ADOX", - "ADCOX", - - "CLR", + [CC_OP_DYNAMIC] = "DYNAMIC", + + [CC_OP_EFLAGS] = "EFLAGS", + [CC_OP_ADCX] = "ADCX", + [CC_OP_ADOX] = "ADOX", + [CC_OP_ADCOX] = "ADCOX", + + [CC_OP_MULB] = "MULB", + [CC_OP_MULW] = "MULW", + [CC_OP_MULL] = "MULL", + [CC_OP_MULQ] = "MULQ", + + [CC_OP_ADDB] = "ADDB", + [CC_OP_ADDW] = "ADDW", + [CC_OP_ADDL] = "ADDL", + [CC_OP_ADDQ] = "ADDQ", + + [CC_OP_ADCB] = "ADCB", + [CC_OP_ADCW] = "ADCW", + [CC_OP_ADCL] = "ADCL", + [CC_OP_ADCQ] = "ADCQ", + + [CC_OP_SUBB] = "SUBB", + [CC_OP_SUBW] = "SUBW", + [CC_OP_SUBL] = "SUBL", + [CC_OP_SUBQ] = "SUBQ", + + [CC_OP_SBBB] = "SBBB", + [CC_OP_SBBW] = "SBBW", + [CC_OP_SBBL] = "SBBL", + [CC_OP_SBBQ] = "SBBQ", + + [CC_OP_LOGICB] = "LOGICB", + [CC_OP_LOGICW] = "LOGICW", + [CC_OP_LOGICL] = "LOGICL", + [CC_OP_LOGICQ] = "LOGICQ", + + [CC_OP_INCB] = "INCB", + [CC_OP_INCW] = "INCW", + [CC_OP_INCL] = "INCL", + [CC_OP_INCQ] = "INCQ", + + [CC_OP_DECB] = "DECB", + [CC_OP_DECW] = "DECW", + [CC_OP_DECL] = "DECL", + [CC_OP_DECQ] = "DECQ", + + [CC_OP_SHLB] = "SHLB", + [CC_OP_SHLW] = "SHLW", + [CC_OP_SHLL] = "SHLL", + [CC_OP_SHLQ] = "SHLQ", + + [CC_OP_SARB] = "SARB", + [CC_OP_SARW] = "SARW", + [CC_OP_SARL] = "SARL", + [CC_OP_SARQ] = "SARQ", + + [CC_OP_BMILGB] = "BMILGB", + [CC_OP_BMILGW] = "BMILGW", + [CC_OP_BMILGL] = "BMILGL", + [CC_OP_BMILGQ] = "BMILGQ", + + [CC_OP_POPCNT] = "POPCNT", + [CC_OP_CLR] = "CLR", }; static void diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 52571ababe..29daf37048 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1275,6 +1275,7 @@ typedef enum { CC_OP_ADCX, /* CC_DST = C, CC_SRC = rest. */ CC_OP_ADOX, /* CC_SRC2 = O, CC_SRC = rest. */ CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest. */ + CC_OP_CLR, /* Z and P set, all other flags clear. */ CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */ CC_OP_MULW, @@ -1331,8 +1332,16 @@ typedef enum { CC_OP_BMILGL, CC_OP_BMILGQ, - CC_OP_CLR, /* Z set, all other flags clear. */ - CC_OP_POPCNT, /* Z via CC_SRC, all other flags clear. */ + /* + * Note that only CC_OP_POPCNT (i.e. the one with MO_TL size) + * is used or implemented, because the translation needs + * to zero-extend CC_DST anyway. + */ + CC_OP_POPCNTB__, /* Z via CC_DST, all other flags clear. */ + CC_OP_POPCNTW__, + CC_OP_POPCNTL__, + CC_OP_POPCNTQ__, + CC_OP_POPCNT = sizeof(target_ulong) == 8 ? CC_OP_POPCNTQ__ : CC_OP_POPCNTL__, CC_OP_NB, } CCOp; diff --git a/target/i386/sev.c b/target/i386/sev.c index 30b83f1d77..3ab8b3c28b 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -121,7 +121,7 @@ struct SevCommonStateClass { Error **errp); int (*launch_start)(SevCommonState *sev_common); void (*launch_finish)(SevCommonState *sev_common); - int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len); + int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, size_t len); int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp); }; @@ -152,8 +152,10 @@ struct SevSnpGuestState { /* configuration parameters */ char *guest_visible_workarounds; - char *id_block; - char *id_auth; + char *id_block_base64; + uint8_t *id_block; + char *id_auth_base64; + uint8_t *id_auth; char *host_data; struct kvm_sev_snp_launch_start kvm_start_conf; @@ -171,7 +173,7 @@ typedef struct SevLaunchUpdateData { QTAILQ_ENTRY(SevLaunchUpdateData) next; hwaddr gpa; void *hva; - uint64_t len; + size_t len; int type; } SevLaunchUpdateData; @@ -884,7 +886,7 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, if (!data->hva || !data->len) { error_report("SNP_LAUNCH_UPDATE called with invalid address" - "/ length: %p / %lx", + "/ length: %p / %zx", data->hva, data->len); return 1; } @@ -932,8 +934,9 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, out: if (!ret && update.gfn_start << TARGET_PAGE_BITS != data->gpa + data->len) { - error_report("SEV-SNP: expected update of GPA range %lx-%lx," - "got GPA range %lx-%llx", + error_report("SEV-SNP: expected update of GPA range %" + HWADDR_PRIx "-%" HWADDR_PRIx "," + "got GPA range %" HWADDR_PRIx "-%llx", data->gpa, data->gpa + data->len, data->gpa, update.gfn_start << TARGET_PAGE_BITS); ret = -EIO; @@ -943,7 +946,8 @@ out: } static int -sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, uint8_t *addr, uint64_t len) +sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, + uint8_t *addr, size_t len) { int ret, fw_error; struct kvm_sev_launch_update_data update; @@ -1088,8 +1092,7 @@ sev_launch_finish(SevCommonState *sev_common) } static int -snp_launch_update_data(uint64_t gpa, void *hva, - uint32_t len, int type) +snp_launch_update_data(uint64_t gpa, void *hva, size_t len, int type) { SevLaunchUpdateData *data; @@ -1106,7 +1109,7 @@ snp_launch_update_data(uint64_t gpa, void *hva, static int sev_snp_launch_update_data(SevCommonState *sev_common, hwaddr gpa, - uint8_t *ptr, uint64_t len) + uint8_t *ptr, size_t len) { int ret = snp_launch_update_data(gpa, ptr, len, KVM_SEV_SNP_PAGE_TYPE_NORMAL); @@ -1163,7 +1166,7 @@ sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info, } static int -snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len) +snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, size_t cpuid_len) { KvmCpuidInfo kvm_cpuid_info = {0}; SnpCpuidInfo snp_cpuid_info; @@ -1296,7 +1299,7 @@ sev_snp_launch_finish(SevCommonState *sev_common) } } - trace_kvm_sev_snp_launch_finish(sev_snp->id_block, sev_snp->id_auth, + trace_kvm_sev_snp_launch_finish(sev_snp->id_block_base64, sev_snp->id_auth_base64, sev_snp->host_data); ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_FINISH, finish, &error); @@ -2146,7 +2149,8 @@ sev_snp_guest_set_guest_visible_workarounds(Object *obj, const char *value, } if (len != sizeof(start->gosvw)) { - error_setg(errp, "parameter length of %lu exceeds max of %lu", + error_setg(errp, "parameter length of %" G_GSIZE_FORMAT + " exceeds max of %zu", len, sizeof(start->gosvw)); return; } @@ -2159,7 +2163,7 @@ sev_snp_guest_get_id_block(Object *obj, Error **errp) { SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); - return g_strdup(sev_snp_guest->id_block); + return g_strdup(sev_snp_guest->id_block_base64); } static void @@ -2171,25 +2175,26 @@ sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp) finish->id_block_en = 0; g_free(sev_snp_guest->id_block); - g_free((guchar *)finish->id_block_uaddr); + g_free(sev_snp_guest->id_block_base64); /* store the base64 str so we don't need to re-encode in getter */ - sev_snp_guest->id_block = g_strdup(value); + sev_snp_guest->id_block_base64 = g_strdup(value); + sev_snp_guest->id_block = + qbase64_decode(sev_snp_guest->id_block_base64, -1, &len, errp); - finish->id_block_uaddr = - (uint64_t)qbase64_decode(sev_snp_guest->id_block, -1, &len, errp); - - if (!finish->id_block_uaddr) { + if (!sev_snp_guest->id_block) { return; } if (len != KVM_SEV_SNP_ID_BLOCK_SIZE) { - error_setg(errp, "parameter length of %lu not equal to %u", + error_setg(errp, "parameter length of %" G_GSIZE_FORMAT + " not equal to %u", len, KVM_SEV_SNP_ID_BLOCK_SIZE); return; } finish->id_block_en = 1; + finish->id_block_uaddr = (uintptr_t)sev_snp_guest->id_block; } static char * @@ -2197,7 +2202,7 @@ sev_snp_guest_get_id_auth(Object *obj, Error **errp) { SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); - return g_strdup(sev_snp_guest->id_auth); + return g_strdup(sev_snp_guest->id_auth_base64); } static void @@ -2207,24 +2212,27 @@ sev_snp_guest_set_id_auth(Object *obj, const char *value, Error **errp) struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf; gsize len; + finish->id_auth_uaddr = 0; g_free(sev_snp_guest->id_auth); - g_free((guchar *)finish->id_auth_uaddr); + g_free(sev_snp_guest->id_auth_base64); /* store the base64 str so we don't need to re-encode in getter */ - sev_snp_guest->id_auth = g_strdup(value); - - finish->id_auth_uaddr = - (uint64_t)qbase64_decode(sev_snp_guest->id_auth, -1, &len, errp); + sev_snp_guest->id_auth_base64 = g_strdup(value); + sev_snp_guest->id_auth = + qbase64_decode(sev_snp_guest->id_auth_base64, -1, &len, errp); - if (!finish->id_auth_uaddr) { + if (!sev_snp_guest->id_auth) { return; } if (len > KVM_SEV_SNP_ID_AUTH_SIZE) { - error_setg(errp, "parameter length:ID_AUTH %lu exceeds max of %u", + error_setg(errp, "parameter length:ID_AUTH %" G_GSIZE_FORMAT + " exceeds max of %u", len, KVM_SEV_SNP_ID_AUTH_SIZE); return; } + + finish->id_auth_uaddr = (uintptr_t)sev_snp_guest->id_auth; } static bool @@ -2287,7 +2295,8 @@ sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp) } if (len != sizeof(finish->host_data)) { - error_setg(errp, "parameter length of %lu not equal to %lu", + error_setg(errp, "parameter length of %" G_GSIZE_FORMAT + " not equal to %zu", len, sizeof(finish->host_data)); return; } diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c index f76e9cb8cf..301ed95406 100644 --- a/target/i386/tcg/cc_helper.c +++ b/target/i386/tcg/cc_helper.c @@ -107,7 +107,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, case CC_OP_CLR: return CC_Z | CC_P; case CC_OP_POPCNT: - return src1 ? 0 : CC_Z; + return dst ? 0 : CC_Z; case CC_OP_MULB: return compute_all_mulb(dst, src1); diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 11faa70b5e..fc7477833b 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -2804,10 +2804,10 @@ static void gen_POPA(DisasContext *s, X86DecodedInsn *decode) static void gen_POPCNT(DisasContext *s, X86DecodedInsn *decode) { - decode->cc_src = tcg_temp_new(); + decode->cc_dst = tcg_temp_new(); decode->cc_op = CC_OP_POPCNT; - tcg_gen_mov_tl(decode->cc_src, s->T0); + tcg_gen_mov_tl(decode->cc_dst, s->T0); tcg_gen_ctpop_tl(s->T0, s->T0); } diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index ad1819815a..95bad55bf4 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -283,22 +283,6 @@ enum { }; enum { - /* I386 int registers */ - OR_EAX, /* MUST be even numbered */ - OR_ECX, - OR_EDX, - OR_EBX, - OR_ESP, - OR_EBP, - OR_ESI, - OR_EDI, - - OR_TMP0 = 16, /* temporary operand register */ - OR_TMP1, - OR_A0, /* temporary register used when doing address evaluation */ -}; - -enum { USES_CC_DST = 1, USES_CC_SRC = 2, USES_CC_SRC2 = 4, @@ -324,7 +308,7 @@ static const uint8_t cc_op_live[CC_OP_NB] = { [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2, [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2, [CC_OP_CLR] = 0, - [CC_OP_POPCNT] = USES_CC_SRC, + [CC_OP_POPCNT] = USES_CC_DST, }; static void set_cc_op_1(DisasContext *s, CCOp op, bool dirty) @@ -1019,8 +1003,6 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) .imm = CC_Z }; case CC_OP_CLR: return (CCPrepare) { .cond = TCG_COND_ALWAYS }; - case CC_OP_POPCNT: - return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src }; default: { MemOp size = (s->cc_op - CC_OP_ADDB) & 3; @@ -3177,6 +3159,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b) case CC_OP_SHLB ... CC_OP_SHLQ: case CC_OP_SARB ... CC_OP_SARQ: case CC_OP_BMILGB ... CC_OP_BMILGQ: + case CC_OP_POPCNT: /* Z was going to be computed from the non-zero status of CC_DST. We can get that same Z value (and the new C value) by leaving CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the diff --git a/target/i386/trace-events b/target/i386/trace-events index 06b44ead2e..51301673f0 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -6,7 +6,7 @@ kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%zx" kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%zx" kvm_sev_change_state(const char *old, const char *new) "%s -> %s" kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" -kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIx64 +kvm_sev_launch_update_data(void *addr, size_t len) "addr %p len 0x%zx" kvm_sev_launch_measurement(const char *value) "data %s" kvm_sev_launch_finish(void) "" kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" |