Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* i386: fix issue with cache topology passthrough
* scsi-disk: migrate emulated requests
* i386/sev: fix Coverity issues
* i386/tcg: more conversions to new decoder

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmZv6kMUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroOn4Af/evnpsae1fm8may1NQmmezKiks/4X
# cR0GaQ7w75Oas05jKsG7Xnrq3Vn6p5wllf3Wf00p7F1iJX18azY9rQgIsUVUgVem
# /EIZk1eM6+mDxuIG0taPxc5Aw3cfIBWAjUmzsXrSr55e/wyiIxZCeUo2zk8Il+iL
# Z4ceNzY5PZzc2Fl10D3cGs/+ynfiDM53ucwe3ve2T6NrxEVfKQPp5jkIUkBUba6z
# zM5O4Q5KTEZYVth1gbDTB/uUJLUFjQ12kCQfRCNX+bEPDHwARr0UWr/Oxtz0jZSd
# FvXohz7tI+v+ph0xHyE4tEFqryvLCII1td2ohTAYZZXNGkjK6XZildngBw==
# =m4BE
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 17 Jun 2024 12:48:19 AM PDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (25 commits)
  target/i386: SEV: do not assume machine->cgs is SEV
  target/i386: convert CMPXCHG to new decoder
  target/i386: convert XADD to new decoder
  target/i386: convert LZCNT/TZCNT/BSF/BSR/POPCNT to new decoder
  target/i386: convert SHLD/SHRD to new decoder
  target/i386: adapt gen_shift_count for SHLD/SHRD
  target/i386: pull load/writeback out of gen_shiftd_rm_T1
  target/i386: convert non-grouped, helper-based 2-byte opcodes
  target/i386: split X86_CHECK_prot into PE and VM86 checks
  target/i386: finish converting 0F AE to the new decoder
  target/i386: fix bad sorting of entries in the 0F table
  target/i386: replace read_crN helper with read_cr8
  target/i386: convert MOV from/to CR and DR to new decoder
  target/i386: fix processing of intercept 0 (read CR0)
  target/i386: replace NoSeg special with NoLoadEA
  target/i386: change X86_ENTRYwr to use T0, use it for moves
  target/i386: change X86_ENTRYr to use T0
  target/i386: put BLS* input in T1, use generic flag writeback
  target/i386: rewrite flags writeback for ADCX/ADOX
  target/i386: remove CPUX86State argument from generator functions
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2024-06-17 11:38:44 -07:00
12 changed files with 1173 additions and 1219 deletions
+1
View File
@@ -36,6 +36,7 @@
GlobalProperty hw_compat_9_0[] = {
{"arm-cpu", "backcompat-cntfrq", "true" },
{"scsi-disk-base", "migrate-emulated-scsi-request", "false" },
{"vfio-pci", "skip-vsc-check", "false" },
};
const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
+23 -1
View File
@@ -114,6 +114,7 @@ struct SCSIDiskState {
* 0xffff - reserved
*/
uint16_t rotation_rate;
bool migrate_emulated_scsi_request;
};
static void scsi_free_request(SCSIRequest *req)
@@ -162,6 +163,15 @@ static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req)
}
}
static void scsi_disk_emulate_save_request(QEMUFile *f, SCSIRequest *req)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
if (s->migrate_emulated_scsi_request) {
scsi_disk_save_request(f, req);
}
}
static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
{
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
@@ -185,6 +195,15 @@ static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
}
static void scsi_disk_emulate_load_request(QEMUFile *f, SCSIRequest *req)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
if (s->migrate_emulated_scsi_request) {
scsi_disk_load_request(f, req);
}
}
/*
* scsi_handle_rw_error has two return values. False means that the error
* must be ignored, true means that the error has been processed and the
@@ -2606,6 +2625,8 @@ static const SCSIReqOps scsi_disk_emulate_reqops = {
.read_data = scsi_disk_emulate_read_data,
.write_data = scsi_disk_emulate_write_data,
.get_buf = scsi_get_buf,
.load_request = scsi_disk_emulate_load_request,
.save_request = scsi_disk_emulate_save_request,
};
static const SCSIReqOps scsi_disk_dma_reqops = {
@@ -3114,7 +3135,8 @@ static const TypeInfo scsi_disk_base_info = {
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
DEFINE_PROP_STRING("product", SCSIDiskState, product), \
DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id), \
DEFINE_PROP_BOOL("migrate-emulated-scsi-request", SCSIDiskState, migrate_emulated_scsi_request, true)
static Property scsi_hd_properties[] = {
+2 -4
View File
@@ -6455,10 +6455,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
if (*eax & 31) {
int host_vcpus_per_cache = 1 + ((*eax & 0x3FFC000) >> 14);
if (cores_per_pkg > 1) {
*eax &= ~0xFC000000;
*eax |= max_core_ids_in_package(&topo_info) << 26;
}
*eax &= ~0xFC000000;
*eax |= max_core_ids_in_package(&topo_info) << 26;
if (host_vcpus_per_cache > threads_per_pkg) {
*eax &= ~0x3FFC000;
+5 -4
View File
@@ -1260,6 +1260,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
/* Use a clearer name for this. */
#define CPU_INTERRUPT_INIT CPU_INTERRUPT_RESET
#define CC_OP_HAS_EFLAGS(op) ((op) >= CC_OP_EFLAGS && (op) <= CC_OP_ADCOX)
/* Instead of computing the condition codes after each x86 instruction,
* QEMU just stores one operand (called CC_SRC), the result
* (called CC_DST) and the type of operation (called CC_OP). When the
@@ -1270,6 +1272,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
typedef enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
CC_OP_EFLAGS, /* all cc are explicitly computed, CC_SRC = flags */
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_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
CC_OP_MULW,
@@ -1326,10 +1331,6 @@ typedef enum {
CC_OP_BMILGL,
CC_OP_BMILGQ,
CC_OP_ADCX, /* CC_DST = C, CC_SRC = rest. */
CC_OP_ADOX, /* CC_DST = O, CC_SRC = rest. */
CC_OP_ADCOX, /* CC_DST = C, CC_SRC2 = O, CC_SRC = rest. */
CC_OP_CLR, /* Z set, all other flags clear. */
CC_OP_POPCNT, /* Z via CC_SRC, all other flags clear. */
+1 -1
View File
@@ -95,7 +95,7 @@ DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
DEF_HELPER_1(rdmsr, void, env)
DEF_HELPER_1(wrmsr, void, env)
DEF_HELPER_FLAGS_2(read_crN, TCG_CALL_NO_RWG, tl, env, int)
DEF_HELPER_FLAGS_1(read_cr8, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_3(write_crN, TCG_CALL_NO_RWG, void, env, int, tl)
#endif /* !CONFIG_USER_ONLY */
+8 -3
View File
@@ -587,6 +587,7 @@ static SevCapability *sev_get_capabilities(Error **errp)
sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
if (!sev_common) {
error_setg(errp, "SEV is not configured");
return NULL;
}
sev_device = object_property_get_str(OBJECT(sev_common), "sev-device",
@@ -1529,11 +1530,12 @@ int
sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common);
SevCommonStateClass *klass;
if (!sev_common) {
return 0;
}
klass = SEV_COMMON_GET_CLASS(sev_common);
/* if SEV is in update state then encrypt the data else do nothing */
if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
@@ -1710,7 +1712,9 @@ void sev_es_set_reset_vector(CPUState *cpu)
{
X86CPU *x86;
CPUX86State *env;
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
SevCommonState *sev_common = SEV_COMMON(
object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON));
/* Only update if we have valid reset information */
if (!sev_common || !sev_common->reset_data_valid) {
@@ -2165,6 +2169,7 @@ sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp)
struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
gsize len;
finish->id_block_en = 0;
g_free(sev_snp_guest->id_block);
g_free((guchar *)finish->id_block_uaddr);
@@ -2184,7 +2189,7 @@ sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp)
return;
}
finish->id_block_en = (len) ? 1 : 0;
finish->id_block_en = 1;
}
static char *
File diff suppressed because it is too large Load Diff
+27 -5
View File
@@ -90,6 +90,7 @@ typedef enum X86OpSize {
X86_SIZE_w, /* 16-bit */
X86_SIZE_x, /* 128/256-bit, based on operand size */
X86_SIZE_y, /* 32/64-bit, based on operand size */
X86_SIZE_y_d64, /* 32/64-bit, based on 64-bit mode */
X86_SIZE_z, /* 16-bit for 16-bit operand size, else 32-bit */
X86_SIZE_z_f64, /* 32-bit for 32-bit operand size or 64-bit mode, else 16-bit */
@@ -108,12 +109,18 @@ typedef enum X86CPUIDFeature {
X86_FEAT_AVX2,
X86_FEAT_BMI1,
X86_FEAT_BMI2,
X86_FEAT_CLFLUSH,
X86_FEAT_CLFLUSHOPT,
X86_FEAT_CLWB,
X86_FEAT_CMOV,
X86_FEAT_CMPCCXADD,
X86_FEAT_F16C,
X86_FEAT_FMA,
X86_FEAT_FSGSBASE,
X86_FEAT_FXSR,
X86_FEAT_MOVBE,
X86_FEAT_PCLMULQDQ,
X86_FEAT_POPCNT,
X86_FEAT_SHA_NI,
X86_FEAT_SSE,
X86_FEAT_SSE2,
@@ -122,6 +129,8 @@ typedef enum X86CPUIDFeature {
X86_FEAT_SSE41,
X86_FEAT_SSE42,
X86_FEAT_SSE4A,
X86_FEAT_XSAVE,
X86_FEAT_XSAVEOPT,
} X86CPUIDFeature;
/* Execution flags */
@@ -142,8 +151,8 @@ typedef enum X86InsnCheck {
X86_CHECK_i64 = 1,
X86_CHECK_o64 = 2,
/* Fault outside protected mode */
X86_CHECK_prot = 4,
/* Fault in vm86 mode */
X86_CHECK_no_vm86 = 4,
/* Privileged instruction checks */
X86_CHECK_cpl0 = 8,
@@ -159,6 +168,17 @@ typedef enum X86InsnCheck {
/* Fault if VEX.W=0 */
X86_CHECK_W1 = 256,
/* Fault outside protected mode, possibly including vm86 mode */
X86_CHECK_prot_or_vm86 = 512,
X86_CHECK_prot = X86_CHECK_prot_or_vm86 | X86_CHECK_no_vm86,
/* Fault outside SMM */
X86_CHECK_smm = 1024,
/* Vendor-specific checks for Intel/AMD differences */
X86_CHECK_i64_amd = 2048,
X86_CHECK_o64_intel = 4096,
} X86InsnCheck;
typedef enum X86InsnSpecial {
@@ -170,8 +190,9 @@ typedef enum X86InsnSpecial {
/* Always locked if it has a memory operand (XCHG) */
X86_SPECIAL_Locked,
/* Do not apply segment base to effective address */
X86_SPECIAL_NoSeg,
/* Do not load effective address in s->A0 */
X86_SPECIAL_NoLoadEA,
/*
* Rd/Mb or Rd/Mw in the manual: register operand 0 is treated as 32 bits
* (and writeback zero-extends it to 64 bits if applicable). PREFIX_DATA
@@ -245,7 +266,7 @@ typedef struct X86DecodedInsn X86DecodedInsn;
typedef void (*X86DecodeFunc)(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b);
/* Code generation function. */
typedef void (*X86GenFunc)(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode);
typedef void (*X86GenFunc)(DisasContext *s, X86DecodedInsn *decode);
struct X86OpEntry {
/* Based on the is_decode flags. */
@@ -271,6 +292,7 @@ struct X86OpEntry {
unsigned valid_prefix:16;
unsigned check:16;
unsigned intercept:8;
bool has_intercept:1;
bool is_decode:1;
};
+811 -355
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -2265,11 +2265,11 @@ void helper_sysexit(CPUX86State *env, int dflag)
target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
{
unsigned int limit;
uint32_t e1, e2, eflags, selector;
uint32_t e1, e2, selector;
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
eflags = cpu_cc_compute_all(env);
assert(CC_OP == CC_OP_EFLAGS);
if ((selector & 0xfffc) == 0) {
goto fail;
}
@@ -2301,22 +2301,22 @@ target_ulong helper_lsl(CPUX86State *env, target_ulong selector1)
}
if (dpl < cpl || dpl < rpl) {
fail:
CC_SRC = eflags & ~CC_Z;
CC_SRC &= ~CC_Z;
return 0;
}
}
limit = get_seg_limit(e1, e2);
CC_SRC = eflags | CC_Z;
CC_SRC |= CC_Z;
return limit;
}
target_ulong helper_lar(CPUX86State *env, target_ulong selector1)
{
uint32_t e1, e2, eflags, selector;
uint32_t e1, e2, selector;
int rpl, dpl, cpl, type;
selector = selector1 & 0xffff;
eflags = cpu_cc_compute_all(env);
assert(CC_OP == CC_OP_EFLAGS);
if ((selector & 0xfffc) == 0) {
goto fail;
}
@@ -2351,11 +2351,11 @@ target_ulong helper_lar(CPUX86State *env, target_ulong selector1)
}
if (dpl < cpl || dpl < rpl) {
fail:
CC_SRC = eflags & ~CC_Z;
CC_SRC &= ~CC_Z;
return 0;
}
}
CC_SRC = eflags | CC_Z;
CC_SRC |= CC_Z;
return e2 & 0x00f0ff00;
}
+5 -15
View File
@@ -63,23 +63,13 @@ target_ulong helper_inl(CPUX86State *env, uint32_t port)
cpu_get_mem_attrs(env), NULL);
}
target_ulong helper_read_crN(CPUX86State *env, int reg)
target_ulong helper_read_cr8(CPUX86State *env)
{
target_ulong val;
switch (reg) {
default:
val = env->cr[reg];
break;
case 8:
if (!(env->hflags2 & HF2_VINTR_MASK)) {
val = cpu_get_apic_tpr(env_archcpu(env)->apic_state);
} else {
val = env->int_ctl & V_TPR_MASK;
}
break;
if (!(env->hflags2 & HF2_VINTR_MASK)) {
return cpu_get_apic_tpr(env_archcpu(env)->apic_state);
} else {
return env->int_ctl & V_TPR_MASK;
}
return val;
}
void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
File diff suppressed because it is too large Load Diff