* kvm: reuse per-vcpu stats fd to avoid vcpu interruption

* Validate cluster and NUMA node boundary on ARM and RISC-V
 * various small TCG features from newer processors
 * Remove dubious 'event_notifier-posix.c' include
 * fix git-submodule.sh in releases
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmSZS0IUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroN+tgf/axJdG9NXKCyXgc0vzjKVhSR4Y+tC
 EPxkg7Rq7uOMgbph9oTS/2Kzh9LnP6kLt2qnS4igRHGuEBd58yD6fFNDv0LJsK/l
 B/d0WGHMKV0KMYOX24rkyfohVu37GhVRsiVSIlIiQVTC9JtYer7WxdnyoDaPKvY8
 dpbKgDrd59vAlsHrpj7ZubVQPcL3lXrLryimpDohMH6Ba+4wZq+7dKPpal97QOP2
 3i7isUBTQiMOcVjW6GEiNcDLSJqj5DSgylhdFnaBsq/ThpC2PxWoXcCbV28QELzf
 5+J+RXQavmeWKZMR0q98iBzWbrsVtaSxAkHHiwbUMMqQvkfY6Dpo5dMHWw==
 =WHE2
 -----END PGP SIGNATURE-----

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

* kvm: reuse per-vcpu stats fd to avoid vcpu interruption
* Validate cluster and NUMA node boundary on ARM and RISC-V
* various small TCG features from newer processors
* Remove dubious 'event_notifier-posix.c' include
* fix git-submodule.sh in releases

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmSZS0IUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroN+tgf/axJdG9NXKCyXgc0vzjKVhSR4Y+tC
# EPxkg7Rq7uOMgbph9oTS/2Kzh9LnP6kLt2qnS4igRHGuEBd58yD6fFNDv0LJsK/l
# B/d0WGHMKV0KMYOX24rkyfohVu37GhVRsiVSIlIiQVTC9JtYer7WxdnyoDaPKvY8
# dpbKgDrd59vAlsHrpj7ZubVQPcL3lXrLryimpDohMH6Ba+4wZq+7dKPpal97QOP2
# 3i7isUBTQiMOcVjW6GEiNcDLSJqj5DSgylhdFnaBsq/ThpC2PxWoXcCbV28QELzf
# 5+J+RXQavmeWKZMR0q98iBzWbrsVtaSxAkHHiwbUMMqQvkfY6Dpo5dMHWw==
# =WHE2
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 26 Jun 2023 10:24:34 AM CEST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  git-submodule.sh: allow running in validate mode without previous update
  target/i386: implement SYSCALL/SYSRET in 32-bit emulators
  target/i386: implement RDPID in TCG
  target/i386: sysret and sysexit are privileged
  target/i386: AMD only supports SYSENTER/SYSEXIT in 32-bit mode
  target/i386: Intel only supports SYSCALL/SYSRET in long mode
  target/i386: TCG supports WBNOINVD
  target/i386: TCG supports XSAVEERPTR
  target/i386: do not accept RDSEED if CPUID bit absent
  target/i386: TCG supports RDSEED
  target/i386: TCG supports 3DNow! prefetch(w)
  target/i386: fix INVD vmexit
  kvm: reuse per-vcpu stats fd to avoid vcpu interruption
  hw/riscv: Validate cluster and NUMA node boundary
  hw/arm: Validate cluster and NUMA node boundary
  numa: Validate cluster and NUMA node boundary if required
  hw/remote/proxy: Remove dubious 'event_notifier-posix.c' include
  build: further refine build.ninja rules

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-06-26 13:44:16 +02:00
commit cd041ddbc0
22 changed files with 224 additions and 94 deletions

View File

@ -83,16 +83,17 @@ config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/scripts/meson-buildoptions.sh
@if test -f meson-private/coredata.dat; then \ @if test -f meson-private/coredata.dat; then \
./config.status --skip-meson; \ ./config.status --skip-meson; \
else \ else \
./config.status && touch build.ninja.stamp; \ ./config.status; \
fi fi
# 2. meson.stamp exists if meson has run at least once (so ninja reconfigure # 2. meson.stamp exists if meson has run at least once (so ninja reconfigure
# works), but otherwise never needs to be updated # works), but otherwise never needs to be updated
meson-private/coredata.dat: meson.stamp meson-private/coredata.dat: meson.stamp
meson.stamp: config-host.mak meson.stamp: config-host.mak
@touch meson.stamp @touch meson.stamp
# 3. ensure generated build files are up-to-date # 3. ensure meson-generated build files are up-to-date
ifneq ($(NINJA),) ifneq ($(NINJA),)
Makefile.ninja: build.ninja Makefile.ninja: build.ninja
@ -106,11 +107,19 @@ Makefile.ninja: build.ninja
endif endif
ifneq ($(MESON),) ifneq ($(MESON),)
# A separate rule is needed for Makefile dependencies to avoid -n # The path to meson always points to pyvenv/bin/meson, but the absolute
# paths could change. In that case, force a regeneration of build.ninja.
# Note that this invocation of $(NINJA), just like when Make rebuilds
# Makefiles, does not include -n.
build.ninja: build.ninja.stamp build.ninja: build.ninja.stamp
$(build-files): $(build-files):
build.ninja.stamp: meson.stamp $(build-files) build.ninja.stamp: meson.stamp $(build-files)
$(MESON) setup --reconfigure $(SRC_PATH) && touch $@ @if test "$$(cat build.ninja.stamp)" = "$(MESON)" && test -n "$(NINJA)"; then \
$(NINJA) build.ninja; \
else \
echo "$(MESON) setup --reconfigure $(SRC_PATH)"; \
$(MESON) setup --reconfigure $(SRC_PATH); \
fi && echo "$(MESON)" > $@
Makefile.mtest: build.ninja scripts/mtest2make.py Makefile.mtest: build.ninja scripts/mtest2make.py
$(MESON) introspect --targets --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@ $(MESON) introspect --targets --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@

View File

@ -450,6 +450,8 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
"kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)", "kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
kvm_arch_vcpu_id(cpu)); kvm_arch_vcpu_id(cpu));
} }
cpu->kvm_vcpu_stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
err: err:
return ret; return ret;
} }
@ -4007,7 +4009,7 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd
/* Read stats header */ /* Read stats header */
kvm_stats_header = &descriptors->kvm_stats_header; kvm_stats_header = &descriptors->kvm_stats_header;
ret = read(stats_fd, kvm_stats_header, sizeof(*kvm_stats_header)); ret = pread(stats_fd, kvm_stats_header, sizeof(*kvm_stats_header), 0);
if (ret != sizeof(*kvm_stats_header)) { if (ret != sizeof(*kvm_stats_header)) {
error_setg(errp, "KVM stats: failed to read stats header: " error_setg(errp, "KVM stats: failed to read stats header: "
"expected %zu actual %zu", "expected %zu actual %zu",
@ -4038,7 +4040,8 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd
} }
static void query_stats(StatsResultList **result, StatsTarget target, static void query_stats(StatsResultList **result, StatsTarget target,
strList *names, int stats_fd, Error **errp) strList *names, int stats_fd, CPUState *cpu,
Error **errp)
{ {
struct kvm_stats_desc *kvm_stats_desc; struct kvm_stats_desc *kvm_stats_desc;
struct kvm_stats_header *kvm_stats_header; struct kvm_stats_header *kvm_stats_header;
@ -4096,7 +4099,7 @@ static void query_stats(StatsResultList **result, StatsTarget target,
break; break;
case STATS_TARGET_VCPU: case STATS_TARGET_VCPU:
add_stats_entry(result, STATS_PROVIDER_KVM, add_stats_entry(result, STATS_PROVIDER_KVM,
current_cpu->parent_obj.canonical_path, cpu->parent_obj.canonical_path,
stats_list); stats_list);
break; break;
default: default:
@ -4133,10 +4136,9 @@ static void query_stats_schema(StatsSchemaList **result, StatsTarget target,
add_stats_schema(result, STATS_PROVIDER_KVM, target, stats_list); add_stats_schema(result, STATS_PROVIDER_KVM, target, stats_list);
} }
static void query_stats_vcpu(CPUState *cpu, run_on_cpu_data data) static void query_stats_vcpu(CPUState *cpu, StatsArgs *kvm_stats_args)
{ {
StatsArgs *kvm_stats_args = (StatsArgs *) data.host_ptr; int stats_fd = cpu->kvm_vcpu_stats_fd;
int stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
Error *local_err = NULL; Error *local_err = NULL;
if (stats_fd == -1) { if (stats_fd == -1) {
@ -4145,14 +4147,13 @@ static void query_stats_vcpu(CPUState *cpu, run_on_cpu_data data)
return; return;
} }
query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU, query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU,
kvm_stats_args->names, stats_fd, kvm_stats_args->errp); kvm_stats_args->names, stats_fd, cpu,
close(stats_fd); kvm_stats_args->errp);
} }
static void query_stats_schema_vcpu(CPUState *cpu, run_on_cpu_data data) static void query_stats_schema_vcpu(CPUState *cpu, StatsArgs *kvm_stats_args)
{ {
StatsArgs *kvm_stats_args = (StatsArgs *) data.host_ptr; int stats_fd = cpu->kvm_vcpu_stats_fd;
int stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
Error *local_err = NULL; Error *local_err = NULL;
if (stats_fd == -1) { if (stats_fd == -1) {
@ -4162,7 +4163,6 @@ static void query_stats_schema_vcpu(CPUState *cpu, run_on_cpu_data data)
} }
query_stats_schema(kvm_stats_args->result.schema, STATS_TARGET_VCPU, stats_fd, query_stats_schema(kvm_stats_args->result.schema, STATS_TARGET_VCPU, stats_fd,
kvm_stats_args->errp); kvm_stats_args->errp);
close(stats_fd);
} }
static void query_stats_cb(StatsResultList **result, StatsTarget target, static void query_stats_cb(StatsResultList **result, StatsTarget target,
@ -4180,7 +4180,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target,
error_setg_errno(errp, errno, "KVM stats: ioctl failed"); error_setg_errno(errp, errno, "KVM stats: ioctl failed");
return; return;
} }
query_stats(result, target, names, stats_fd, errp); query_stats(result, target, names, stats_fd, NULL, errp);
close(stats_fd); close(stats_fd);
break; break;
} }
@ -4194,7 +4194,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target,
if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) { if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) {
continue; continue;
} }
run_on_cpu(cpu, query_stats_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args)); query_stats_vcpu(cpu, &stats_args);
} }
break; break;
} }
@ -4220,6 +4220,6 @@ void query_stats_schemas_cb(StatsSchemaList **result, Error **errp)
if (first_cpu) { if (first_cpu) {
stats_args.result.schema = result; stats_args.result.schema = result;
stats_args.errp = errp; stats_args.errp = errp;
run_on_cpu(first_cpu, query_stats_schema_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args)); query_stats_schema_vcpu(first_cpu, &stats_args);
} }
} }

View File

@ -164,6 +164,10 @@ static inline void target_cpu_loop(CPUX86State *env)
} }
break; break;
case EXCP_SYSCALL:
/* doesn't do anything */
break;
case EXCP_INTERRUPT: case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */ /* just indicate that signals should be handled asap */
break; break;

3
configure vendored
View File

@ -758,7 +758,7 @@ done
if ! test -e "$source_path/.git" if ! test -e "$source_path/.git"
then then
git_submodules_action="ignore" git_submodules_action="validate"
fi fi
# test for any invalid configuration combinations # test for any invalid configuration combinations
@ -1895,6 +1895,7 @@ if test "$skip_meson" = no; then
if test "$?" -ne 0 ; then if test "$?" -ne 0 ; then
error_exit "meson setup failed" error_exit "meson setup failed"
fi fi
echo "$meson" > build.ninja.stamp
else else
if test -f meson-private/cmd_line.txt; then if test -f meson-private/cmd_line.txt; then
# Adjust old command line options that were removed # Adjust old command line options that were removed

View File

@ -910,6 +910,8 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids; mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids;
mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props; mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props;
mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id; mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id;
/* platform instead of architectural choice */
mc->cpu_cluster_has_numa_boundary = true;
} }
static const TypeInfo sbsa_ref_info = { static const TypeInfo sbsa_ref_info = {

View File

@ -3033,6 +3033,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->smp_props.clusters_supported = true; mc->smp_props.clusters_supported = true;
mc->auto_enable_numa_with_memhp = true; mc->auto_enable_numa_with_memhp = true;
mc->auto_enable_numa_with_memdev = true; mc->auto_enable_numa_with_memdev = true;
/* platform instead of architectural choice */
mc->cpu_cluster_has_numa_boundary = true;
mc->default_ram_id = "mach-virt.ram"; mc->default_ram_id = "mach-virt.ram";
mc->default_nic = "virtio-net-pci"; mc->default_nic = "virtio-net-pci";

View File

@ -1262,6 +1262,45 @@ static void machine_numa_finish_cpu_init(MachineState *machine)
g_string_free(s, true); g_string_free(s, true);
} }
static void validate_cpu_cluster_to_numa_boundary(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
NumaState *state = ms->numa_state;
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
const CPUArchId *cpus = possible_cpus->cpus;
int i, j;
if (state->num_nodes <= 1 || possible_cpus->len <= 1) {
return;
}
/*
* The Linux scheduling domain can't be parsed when the multiple CPUs
* in one cluster have been associated with different NUMA nodes. However,
* it's fine to associate one NUMA node with CPUs in different clusters.
*/
for (i = 0; i < possible_cpus->len; i++) {
for (j = i + 1; j < possible_cpus->len; j++) {
if (cpus[i].props.has_socket_id &&
cpus[i].props.has_cluster_id &&
cpus[i].props.has_node_id &&
cpus[j].props.has_socket_id &&
cpus[j].props.has_cluster_id &&
cpus[j].props.has_node_id &&
cpus[i].props.socket_id == cpus[j].props.socket_id &&
cpus[i].props.cluster_id == cpus[j].props.cluster_id &&
cpus[i].props.node_id != cpus[j].props.node_id) {
warn_report("CPU-%d and CPU-%d in socket-%" PRId64 "-cluster-%" PRId64
" have been associated with node-%" PRId64 " and node-%" PRId64
" respectively. It can cause OSes like Linux to"
" misbehave", i, j, cpus[i].props.socket_id,
cpus[i].props.cluster_id, cpus[i].props.node_id,
cpus[j].props.node_id);
}
}
}
}
MemoryRegion *machine_consume_memdev(MachineState *machine, MemoryRegion *machine_consume_memdev(MachineState *machine,
HostMemoryBackend *backend) HostMemoryBackend *backend)
{ {
@ -1355,6 +1394,9 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error *
numa_complete_configuration(machine); numa_complete_configuration(machine);
if (machine->numa_state->num_nodes) { if (machine->numa_state->num_nodes) {
machine_numa_finish_cpu_init(machine); machine_numa_finish_cpu_init(machine);
if (machine_class->cpu_cluster_has_numa_boundary) {
validate_cpu_cluster_to_numa_boundary(machine);
}
} }
} }

View File

@ -22,7 +22,6 @@
#include "qom/object.h" #include "qom/object.h"
#include "qemu/event_notifier.h" #include "qemu/event_notifier.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "util/event_notifier-posix.c"
static void probe_pci_info(PCIDevice *dev, Error **errp); static void probe_pci_info(PCIDevice *dev, Error **errp);
static void proxy_device_reset(DeviceState *dev); static void proxy_device_reset(DeviceState *dev);

View File

@ -354,6 +354,8 @@ static void spike_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props; mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id; mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
mc->numa_mem_supported = true; mc->numa_mem_supported = true;
/* platform instead of architectural choice */
mc->cpu_cluster_has_numa_boundary = true;
mc->default_ram_id = "riscv.spike.ram"; mc->default_ram_id = "riscv.spike.ram";
object_class_property_add_str(oc, "signature", NULL, spike_set_signature); object_class_property_add_str(oc, "signature", NULL, spike_set_signature);
object_class_property_set_description(oc, "signature", object_class_property_set_description(oc, "signature",

View File

@ -1669,6 +1669,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props; mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id; mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
mc->numa_mem_supported = true; mc->numa_mem_supported = true;
/* platform instead of architectural choice */
mc->cpu_cluster_has_numa_boundary = true;
mc->default_ram_id = "riscv_virt_board.ram"; mc->default_ram_id = "riscv_virt_board.ram";
assert(!mc->get_hotplug_handler); assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler; mc->get_hotplug_handler = virt_machine_get_hotplug_handler;

View File

@ -274,6 +274,7 @@ struct MachineClass {
bool nvdimm_supported; bool nvdimm_supported;
bool numa_mem_supported; bool numa_mem_supported;
bool auto_enable_numa; bool auto_enable_numa;
bool cpu_cluster_has_numa_boundary;
SMPCompatProps smp_props; SMPCompatProps smp_props;
const char *default_ram_id; const char *default_ram_id;

View File

@ -402,6 +402,7 @@ struct CPUState {
struct kvm_dirty_gfn *kvm_dirty_gfns; struct kvm_dirty_gfn *kvm_dirty_gfns;
uint32_t kvm_fetch_index; uint32_t kvm_fetch_index;
uint64_t dirty_pages; uint64_t dirty_pages;
int kvm_vcpu_stats_fd;
/* Use by accel-block: CPU is executing an ioctl() */ /* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock; QemuLockCnt in_ioctl_lock;

View File

@ -211,6 +211,9 @@ void cpu_loop(CPUX86State *env)
switch(trapnr) { switch(trapnr) {
case 0x80: case 0x80:
#ifndef TARGET_X86_64
case EXCP_SYSCALL:
#endif
/* linux syscall from int $0x80 */ /* linux syscall from int $0x80 */
ret = do_syscall(env, ret = do_syscall(env,
env->regs[R_EAX], env->regs[R_EAX],
@ -227,9 +230,9 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EAX] = ret; env->regs[R_EAX] = ret;
} }
break; break;
#ifndef TARGET_ABI32 #ifdef TARGET_X86_64
case EXCP_SYSCALL: case EXCP_SYSCALL:
/* linux syscall from syscall instruction */ /* linux syscall from syscall instruction. */
ret = do_syscall(env, ret = do_syscall(env,
env->regs[R_EAX], env->regs[R_EAX],
env->regs[R_EDI], env->regs[R_EDI],
@ -245,8 +248,6 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EAX] = ret; env->regs[R_EAX] = ret;
} }
break; break;
#endif
#ifdef TARGET_X86_64
case EXCP_VSYSCALL: case EXCP_VSYSCALL:
emulate_vsyscall(env); emulate_vsyscall(env);
break; break;

View File

@ -2232,6 +2232,8 @@ config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
# Note that we need to specify prefix: here to avoid incorrectly # Note that we need to specify prefix: here to avoid incorrectly
# thinking that Windows has posix_memalign() # thinking that Windows has posix_memalign()
config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))

View File

@ -9,13 +9,22 @@ command=$1
shift shift
maybe_modules="$@" maybe_modules="$@"
# if not running in a git checkout, do nothing test -z "$maybe_modules" && exit 0
test "$command" = "ignore" && exit 0
test -z "$GIT" && GIT=$(command -v git) test -z "$GIT" && GIT=$(command -v git)
cd "$(dirname "$0")/.." cd "$(dirname "$0")/.."
no_git_error=
if ! test -e ".git"; then
no_git_error='no git checkout exists'
elif test -z "$GIT"; then
no_git_error='git binary not found'
fi
is_git() {
test -z "$no_git_error"
}
update_error() { update_error() {
echo "$0: $*" echo "$0: $*"
echo echo
@ -34,7 +43,7 @@ update_error() {
} }
validate_error() { validate_error() {
if test "$1" = "validate"; then if is_git && test "$1" = "validate"; then
echo "GIT submodules checkout is out of date, and submodules" echo "GIT submodules checkout is out of date, and submodules"
echo "configured for validate only. Please run" echo "configured for validate only. Please run"
echo " scripts/git-submodule.sh update $maybe_modules" echo " scripts/git-submodule.sh update $maybe_modules"
@ -51,18 +60,8 @@ check_updated() {
test "$CURSTATUS" = "$OLDSTATUS" test "$CURSTATUS" = "$OLDSTATUS"
} }
if test -n "$maybe_modules" && ! test -e ".git" if is_git; then
then test -e $substat || touch $substat
echo "$0: unexpectedly called with submodules but no git checkout exists"
exit 1
fi
if test -n "$maybe_modules" && test -z "$GIT"
then
echo "$0: unexpectedly called with submodules but git binary not found"
exit 1
fi
modules="" modules=""
for m in $maybe_modules for m in $maybe_modules
do do
@ -70,23 +69,33 @@ do
if test $? = 0 if test $? = 0
then then
modules="$modules $m" modules="$modules $m"
grep $m $substat > /dev/null 2>&1 || $GIT submodule status $module >> $substat
else else
echo "warn: ignoring non-existent submodule $m" echo "warn: ignoring non-existent submodule $m"
fi fi
done done
else
modules=$maybe_modules
fi
case "$command" in case "$command" in
status|validate) status|validate)
test -f "$substat" || validate_error "$command"
test -z "$maybe_modules" && exit 0
for module in $modules; do for module in $modules; do
if is_git; then
check_updated $module || validate_error "$command" check_updated $module || validate_error "$command"
elif ! (set xyz "$module"/* && test -e "$2"); then
# The directory does not exist or it contains no files
echo "$0: sources not available for $module and $no_git_error"
validate_error "$command"
fi
done done
exit 0
;; ;;
update) update)
test -e $substat || touch $substat is_git || {
test -z "$maybe_modules" && exit 0 echo "$0: unexpectedly called with submodules but $no_git_error"
exit 1
}
$GIT submodule update --init $modules 1>/dev/null $GIT submodule update --init $modules 1>/dev/null
test $? -ne 0 && update_error "failed to update modules" test $? -ne 0 && update_error "failed to update modules"

View File

@ -637,7 +637,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER */ CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER */
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM) #define TCG_EXT2_X86_64_FEATURES CPUID_EXT2_LM
#else #else
#define TCG_EXT2_X86_64_FEATURES 0 #define TCG_EXT2_X86_64_FEATURES 0
#endif #endif
@ -645,9 +645,10 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \ #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \ CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \ CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
TCG_EXT2_X86_64_FEATURES) CPUID_EXT2_SYSCALL | TCG_EXT2_X86_64_FEATURES)
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \ #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A) CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | \
CPUID_EXT3_3DNOWPREFETCH)
#define TCG_EXT4_FEATURES 0 #define TCG_EXT4_FEATURES 0
#define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \ #define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
CPUID_SVM_SVME_ADDR_CHK) CPUID_SVM_SVME_ADDR_CHK)
@ -656,14 +657,21 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \ CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \ CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_AVX2) CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_RDSEED)
/* missing: /* missing:
CPUID_7_0_EBX_HLE CPUID_7_0_EBX_HLE
CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM */
CPUID_7_0_EBX_RDSEED */
#if defined CONFIG_SOFTMMU || defined CONFIG_LINUX
#define TCG_7_0_ECX_RDPID CPUID_7_0_ECX_RDPID
#else
#define TCG_7_0_ECX_RDPID 0
#endif
#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | \ #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | \
/* CPUID_7_0_ECX_OSPKE is dynamic */ \ /* CPUID_7_0_ECX_OSPKE is dynamic */ \
CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS | CPUID_7_0_ECX_VAES) CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS | CPUID_7_0_ECX_VAES | \
TCG_7_0_ECX_RDPID)
#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM
#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
CPUID_7_1_EAX_FSRC) CPUID_7_1_EAX_FSRC)
@ -678,6 +686,9 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_SGX_12_0_EBX_FEATURES 0 #define TCG_SGX_12_0_EBX_FEATURES 0
#define TCG_SGX_12_1_EAX_FEATURES 0 #define TCG_SGX_12_1_EAX_FEATURES 0
#define TCG_8000_0008_EBX (CPUID_8000_0008_EBX_XSAVEERPTR | \
CPUID_8000_0008_EBX_WBNOINVD)
FeatureWordInfo feature_word_info[FEATURE_WORDS] = { FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_1_EDX] = { [FEAT_1_EDX] = {
.type = CPUID_FEATURE_WORD, .type = CPUID_FEATURE_WORD,
@ -939,7 +950,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"amd-psfd", NULL, NULL, NULL, "amd-psfd", NULL, NULL, NULL,
}, },
.cpuid = { .eax = 0x80000008, .reg = R_EBX, }, .cpuid = { .eax = 0x80000008, .reg = R_EBX, },
.tcg_features = 0, .tcg_features = TCG_8000_0008_EBX,
.unmigratable_flags = 0, .unmigratable_flags = 0,
}, },
[FEAT_8000_0021_EAX] = { [FEAT_8000_0021_EAX] = {
@ -6235,6 +6246,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx |= 1 << 1; /* CmpLegacy bit */ *ecx |= 1 << 1; /* CmpLegacy bit */
} }
} }
if (tcg_enabled() && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 &&
!(env->hflags & HF_LMA_MASK)) {
*edx &= ~CPUID_EXT2_SYSCALL;
}
break; break;
case 0x80000002: case 0x80000002:
case 0x80000003: case 0x80000003:

View File

@ -51,10 +51,8 @@ DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int)
DEF_HELPER_1(sysenter, void, env) DEF_HELPER_1(sysenter, void, env)
DEF_HELPER_2(sysexit, void, env, int) DEF_HELPER_2(sysexit, void, env, int)
#ifdef TARGET_X86_64
DEF_HELPER_2(syscall, void, env, int) DEF_HELPER_2(syscall, void, env, int)
DEF_HELPER_2(sysret, void, env, int) DEF_HELPER_2(sysret, void, env, int)
#endif
DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int) DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int) DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int) DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
@ -69,8 +67,8 @@ DEF_HELPER_2(into, void, env, int)
DEF_HELPER_FLAGS_1(single_step, TCG_CALL_NO_WG, noreturn, env) DEF_HELPER_FLAGS_1(single_step, TCG_CALL_NO_WG, noreturn, env)
DEF_HELPER_1(rechecking_single_step, void, env) DEF_HELPER_1(rechecking_single_step, void, env)
DEF_HELPER_1(cpuid, void, env) DEF_HELPER_1(cpuid, void, env)
DEF_HELPER_FLAGS_1(rdpid, TCG_CALL_NO_WG, tl, env)
DEF_HELPER_1(rdtsc, void, env) DEF_HELPER_1(rdtsc, void, env)
DEF_HELPER_1(rdtscp, void, env)
DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env) DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY

View File

@ -75,12 +75,6 @@ void helper_rdtsc(CPUX86State *env)
env->regs[R_EDX] = (uint32_t)(val >> 32); env->regs[R_EDX] = (uint32_t)(val >> 32);
} }
void helper_rdtscp(CPUX86State *env)
{
helper_rdtsc(env);
env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
}
G_NORETURN void helper_rdpmc(CPUX86State *env) G_NORETURN void helper_rdpmc(CPUX86State *env)
{ {
if (((env->cr[4] & CR4_PCE_MASK) == 0 ) && if (((env->cr[4] & CR4_PCE_MASK) == 0 ) &&
@ -137,3 +131,18 @@ void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val)
env->pkru = val; env->pkru = val;
tlb_flush(cs); tlb_flush(cs);
} }
target_ulong HELPER(rdpid)(CPUX86State *env)
{
#if defined CONFIG_SOFTMMU
return env->tsc_aux;
#elif defined CONFIG_LINUX && defined CONFIG_GETCPU
unsigned cpu, node;
getcpu(&cpu, &node);
return (node << 12) | (cpu & 0xfff);
#elif defined CONFIG_SCHED_GETCPU
return sched_getcpu();
#else
return 0;
#endif
}

View File

@ -977,6 +977,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
e2); e2);
env->eip = offset; env->eip = offset;
} }
#endif /* TARGET_X86_64 */
void helper_sysret(CPUX86State *env, int dflag) void helper_sysret(CPUX86State *env, int dflag)
{ {
@ -990,6 +991,7 @@ void helper_sysret(CPUX86State *env, int dflag)
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
} }
selector = (env->star >> 48) & 0xffff; selector = (env->star >> 48) & 0xffff;
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) { if (env->hflags & HF_LMA_MASK) {
cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK
| ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK |
@ -1015,7 +1017,9 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK); DESC_W_MASK | DESC_A_MASK);
} else { } else
#endif
{
env->eflags |= IF_MASK; env->eflags |= IF_MASK;
cpu_x86_load_seg_cache(env, R_CS, selector | 3, cpu_x86_load_seg_cache(env, R_CS, selector | 3,
0, 0xffffffff, 0, 0xffffffff,
@ -1030,7 +1034,6 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_W_MASK | DESC_A_MASK); DESC_W_MASK | DESC_A_MASK);
} }
} }
#endif /* TARGET_X86_64 */
/* real mode interrupt */ /* real mode interrupt */
static void do_interrupt_real(CPUX86State *env, int intno, int is_int, static void do_interrupt_real(CPUX86State *env, int intno, int is_int,

View File

@ -26,7 +26,6 @@
#include "tcg/helper-tcg.h" #include "tcg/helper-tcg.h"
#include "../seg_helper.h" #include "../seg_helper.h"
#ifdef TARGET_X86_64
void helper_syscall(CPUX86State *env, int next_eip_addend) void helper_syscall(CPUX86State *env, int next_eip_addend)
{ {
int selector; int selector;
@ -35,6 +34,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
} }
selector = (env->star >> 32) & 0xffff; selector = (env->star >> 32) & 0xffff;
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) { if (env->hflags & HF_LMA_MASK) {
int code64; int code64;
@ -61,7 +61,9 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
} else { } else {
env->eip = env->cstar; env->eip = env->cstar;
} }
} else { } else
#endif
{
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend); env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK); env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
@ -78,7 +80,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
env->eip = (uint32_t)env->star; env->eip = (uint32_t)env->star;
} }
} }
#endif /* TARGET_X86_64 */
void handle_even_inj(CPUX86State *env, int intno, int is_int, void handle_even_inj(CPUX86State *env, int intno, int is_int,
int error_code, int is_hw, int rm) int error_code, int is_hw, int rm)

View File

@ -3924,13 +3924,33 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_cmpxchg8b(s, env, modrm); gen_cmpxchg8b(s, env, modrm);
break; break;
case 7: /* RDSEED */ case 7: /* RDSEED, RDPID with f3 prefix */
if (mod != 3 ||
(s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) {
goto illegal_op;
}
if (s->prefix & PREFIX_REPZ) {
if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) {
goto illegal_op;
}
gen_helper_rdpid(s->T0, cpu_env);
rm = (modrm & 7) | REX_B(s);
gen_op_mov_reg_v(s, dflag, rm, s->T0);
break;
} else {
if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) {
goto illegal_op;
}
goto do_rdrand;
}
case 6: /* RDRAND */ case 6: /* RDRAND */
if (mod != 3 || if (mod != 3 ||
(s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
!(s->cpuid_ext_features & CPUID_EXT_RDRAND)) { !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
goto illegal_op; goto illegal_op;
} }
do_rdrand:
translator_io_start(&s->base); translator_io_start(&s->base);
gen_helper_rdrand(s->T0, cpu_env); gen_helper_rdrand(s->T0, cpu_env);
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -5661,9 +5681,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
s->base.is_jmp = DISAS_NORETURN; s->base.is_jmp = DISAS_NORETURN;
break; break;
case 0x134: /* sysenter */ case 0x134: /* sysenter */
/* For Intel SYSENTER is valid on 64-bit */ /* For AMD SYSENTER is not valid in long mode */
if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
goto illegal_op; goto illegal_op;
}
if (!PE(s)) { if (!PE(s)) {
gen_exception_gpf(s); gen_exception_gpf(s);
} else { } else {
@ -5672,19 +5693,22 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x135: /* sysexit */ case 0x135: /* sysexit */
/* For Intel SYSEXIT is valid on 64-bit */ /* For AMD SYSEXIT is not valid in long mode */
if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
goto illegal_op; goto illegal_op;
if (!PE(s)) { }
if (!PE(s) || CPL(s) != 0) {
gen_exception_gpf(s); gen_exception_gpf(s);
} else { } else {
gen_helper_sysexit(cpu_env, tcg_constant_i32(dflag - 1)); gen_helper_sysexit(cpu_env, tcg_constant_i32(dflag - 1));
s->base.is_jmp = DISAS_EOB_ONLY; s->base.is_jmp = DISAS_EOB_ONLY;
} }
break; break;
#ifdef TARGET_X86_64
case 0x105: /* syscall */ case 0x105: /* syscall */
/* XXX: is it usable in real mode ? */ /* For Intel SYSCALL is only valid in long mode */
if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
goto illegal_op;
}
gen_update_cc_op(s); gen_update_cc_op(s);
gen_update_eip_cur(s); gen_update_eip_cur(s);
gen_helper_syscall(cpu_env, cur_insn_len_i32(s)); gen_helper_syscall(cpu_env, cur_insn_len_i32(s));
@ -5694,7 +5718,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_eob_worker(s, false, true); gen_eob_worker(s, false, true);
break; break;
case 0x107: /* sysret */ case 0x107: /* sysret */
if (!PE(s)) { /* For Intel SYSRET is only valid in long mode */
if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
goto illegal_op;
}
if (!PE(s) || CPL(s) != 0) {
gen_exception_gpf(s); gen_exception_gpf(s);
} else { } else {
gen_helper_sysret(cpu_env, tcg_constant_i32(dflag - 1)); gen_helper_sysret(cpu_env, tcg_constant_i32(dflag - 1));
@ -5709,7 +5737,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_eob_worker(s, false, true); gen_eob_worker(s, false, true);
} }
break; break;
#endif
case 0x1a2: /* cpuid */ case 0x1a2: /* cpuid */
gen_update_cc_op(s); gen_update_cc_op(s);
gen_update_eip_cur(s); gen_update_eip_cur(s);
@ -6108,7 +6135,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_update_cc_op(s); gen_update_cc_op(s);
gen_update_eip_cur(s); gen_update_eip_cur(s);
translator_io_start(&s->base); translator_io_start(&s->base);
gen_helper_rdtscp(cpu_env); gen_helper_rdtsc(cpu_env);
gen_helper_rdpid(s->T0, cpu_env);
gen_op_mov_reg_v(s, dflag, R_ECX, s->T0);
break; break;
default: default:
@ -6117,9 +6146,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 0x108: /* invd */ case 0x108: /* invd */
case 0x109: /* wbinvd */ case 0x109: /* wbinvd; wbnoinvd with REPZ prefix */
if (check_cpl0(s)) { if (check_cpl0(s)) {
gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD);
/* nothing to do */ /* nothing to do */
} }
break; break;

View File

@ -26,7 +26,6 @@
#include "tcg/helper-tcg.h" #include "tcg/helper-tcg.h"
#include "tcg/seg_helper.h" #include "tcg/seg_helper.h"
#ifdef TARGET_X86_64
void helper_syscall(CPUX86State *env, int next_eip_addend) void helper_syscall(CPUX86State *env, int next_eip_addend)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
@ -36,7 +35,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
env->exception_next_eip = env->eip + next_eip_addend; env->exception_next_eip = env->eip + next_eip_addend;
cpu_loop_exit(cs); cpu_loop_exit(cs);
} }
#endif /* TARGET_X86_64 */
/* /*
* fake user mode interrupt. is_int is TRUE if coming from the int * fake user mode interrupt. is_int is TRUE if coming from the int