aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/i386/cpu-dump.c127
-rw-r--r--target/i386/cpu.h13
-rw-r--r--target/i386/sev.c71
-rw-r--r--target/i386/tcg/cc_helper.c2
-rw-r--r--target/i386/tcg/emit.c.inc4
-rw-r--r--target/i386/tcg/translate.c21
-rw-r--r--target/i386/trace-events2
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"