Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
rth7680 committed Jun 26, 2023
2 parents 52ed34c + 8edddaa commit cd041dd
Show file tree
Hide file tree
Showing 22 changed files with 224 additions and 94 deletions.
17 changes: 13 additions & 4 deletions Makefile
Expand Up @@ -83,16 +83,17 @@ config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/scripts/meson-buildoptions.sh
@if test -f meson-private/coredata.dat; then \
./config.status --skip-meson; \
else \
./config.status && touch build.ninja.stamp; \
./config.status; \
fi

# 2. meson.stamp exists if meson has run at least once (so ninja reconfigure
# works), but otherwise never needs to be updated

meson-private/coredata.dat: meson.stamp
meson.stamp: config-host.mak
@touch meson.stamp

# 3. ensure generated build files are up-to-date
# 3. ensure meson-generated build files are up-to-date

ifneq ($(NINJA),)
Makefile.ninja: build.ninja
Expand All @@ -106,11 +107,19 @@ Makefile.ninja: build.ninja
endif

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-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
$(MESON) introspect --targets --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@
Expand Down
30 changes: 15 additions & 15 deletions accel/kvm/kvm-all.c
Expand Up @@ -450,6 +450,8 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
"kvm_init_vcpu: kvm_arch_init_vcpu failed (%lu)",
kvm_arch_vcpu_id(cpu));
}
cpu->kvm_vcpu_stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);

err:
return ret;
}
Expand Down Expand Up @@ -4007,7 +4009,7 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd

/* Read 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)) {
error_setg(errp, "KVM stats: failed to read stats header: "
"expected %zu actual %zu",
Expand Down Expand Up @@ -4038,7 +4040,8 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd
}

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_header *kvm_stats_header;
Expand Down Expand Up @@ -4096,7 +4099,7 @@ static void query_stats(StatsResultList **result, StatsTarget target,
break;
case STATS_TARGET_VCPU:
add_stats_entry(result, STATS_PROVIDER_KVM,
current_cpu->parent_obj.canonical_path,
cpu->parent_obj.canonical_path,
stats_list);
break;
default:
Expand Down Expand Up @@ -4133,10 +4136,9 @@ static void query_stats_schema(StatsSchemaList **result, StatsTarget target,
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 = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
int stats_fd = cpu->kvm_vcpu_stats_fd;
Error *local_err = NULL;

if (stats_fd == -1) {
Expand All @@ -4145,14 +4147,13 @@ static void query_stats_vcpu(CPUState *cpu, run_on_cpu_data data)
return;
}
query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU,
kvm_stats_args->names, stats_fd, kvm_stats_args->errp);
close(stats_fd);
kvm_stats_args->names, stats_fd, cpu,
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 = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
int stats_fd = cpu->kvm_vcpu_stats_fd;
Error *local_err = NULL;

if (stats_fd == -1) {
Expand All @@ -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,
kvm_stats_args->errp);
close(stats_fd);
}

static void query_stats_cb(StatsResultList **result, StatsTarget target,
Expand All @@ -4180,7 +4180,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target,
error_setg_errno(errp, errno, "KVM stats: ioctl failed");
return;
}
query_stats(result, target, names, stats_fd, errp);
query_stats(result, target, names, stats_fd, NULL, errp);
close(stats_fd);
break;
}
Expand All @@ -4194,7 +4194,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target,
if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) {
continue;
}
run_on_cpu(cpu, query_stats_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args));
query_stats_vcpu(cpu, &stats_args);
}
break;
}
Expand All @@ -4220,6 +4220,6 @@ void query_stats_schemas_cb(StatsSchemaList **result, Error **errp)
if (first_cpu) {
stats_args.result.schema = result;
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);
}
}
4 changes: 4 additions & 0 deletions bsd-user/i386/target_arch_cpu.h
Expand Up @@ -164,6 +164,10 @@ static inline void target_cpu_loop(CPUX86State *env)
}
break;

case EXCP_SYSCALL:
/* doesn't do anything */
break;

case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
Expand Down
3 changes: 2 additions & 1 deletion configure
Expand Up @@ -758,7 +758,7 @@ done

if ! test -e "$source_path/.git"
then
git_submodules_action="ignore"
git_submodules_action="validate"
fi

# test for any invalid configuration combinations
Expand Down Expand Up @@ -1895,6 +1895,7 @@ if test "$skip_meson" = no; then
if test "$?" -ne 0 ; then
error_exit "meson setup failed"
fi
echo "$meson" > build.ninja.stamp
else
if test -f meson-private/cmd_line.txt; then
# Adjust old command line options that were removed
Expand Down
2 changes: 2 additions & 0 deletions hw/arm/sbsa-ref.c
Expand Up @@ -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->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props;
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 = {
Expand Down
2 changes: 2 additions & 0 deletions hw/arm/virt.c
Expand Up @@ -3033,6 +3033,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->smp_props.clusters_supported = true;
mc->auto_enable_numa_with_memhp = 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_nic = "virtio-net-pci";

Expand Down
42 changes: 42 additions & 0 deletions hw/core/machine.c
Expand Up @@ -1262,6 +1262,45 @@ static void machine_numa_finish_cpu_init(MachineState *machine)
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,
HostMemoryBackend *backend)
{
Expand Down Expand Up @@ -1355,6 +1394,9 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error *
numa_complete_configuration(machine);
if (machine->numa_state->num_nodes) {
machine_numa_finish_cpu_init(machine);
if (machine_class->cpu_cluster_has_numa_boundary) {
validate_cpu_cluster_to_numa_boundary(machine);
}
}
}

Expand Down
1 change: 0 additions & 1 deletion hw/remote/proxy.c
Expand Up @@ -22,7 +22,6 @@
#include "qom/object.h"
#include "qemu/event_notifier.h"
#include "sysemu/kvm.h"
#include "util/event_notifier-posix.c"

static void probe_pci_info(PCIDevice *dev, Error **errp);
static void proxy_device_reset(DeviceState *dev);
Expand Down
2 changes: 2 additions & 0 deletions hw/riscv/spike.c
Expand Up @@ -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->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
mc->numa_mem_supported = true;
/* platform instead of architectural choice */
mc->cpu_cluster_has_numa_boundary = true;
mc->default_ram_id = "riscv.spike.ram";
object_class_property_add_str(oc, "signature", NULL, spike_set_signature);
object_class_property_set_description(oc, "signature",
Expand Down
2 changes: 2 additions & 0 deletions hw/riscv/virt.c
Expand Up @@ -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->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
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";
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
Expand Down
1 change: 1 addition & 0 deletions include/hw/boards.h
Expand Up @@ -274,6 +274,7 @@ struct MachineClass {
bool nvdimm_supported;
bool numa_mem_supported;
bool auto_enable_numa;
bool cpu_cluster_has_numa_boundary;
SMPCompatProps smp_props;
const char *default_ram_id;

Expand Down
1 change: 1 addition & 0 deletions include/hw/core/cpu.h
Expand Up @@ -402,6 +402,7 @@ struct CPUState {
struct kvm_dirty_gfn *kvm_dirty_gfns;
uint32_t kvm_fetch_index;
uint64_t dirty_pages;
int kvm_vcpu_stats_fd;

/* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock;
Expand Down
9 changes: 5 additions & 4 deletions linux-user/i386/cpu_loop.c
Expand Up @@ -211,6 +211,9 @@ void cpu_loop(CPUX86State *env)

switch(trapnr) {
case 0x80:
#ifndef TARGET_X86_64
case EXCP_SYSCALL:
#endif
/* linux syscall from int $0x80 */
ret = do_syscall(env,
env->regs[R_EAX],
Expand All @@ -227,9 +230,9 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EAX] = ret;
}
break;
#ifndef TARGET_ABI32
#ifdef TARGET_X86_64
case EXCP_SYSCALL:
/* linux syscall from syscall instruction */
/* linux syscall from syscall instruction. */
ret = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EDI],
Expand All @@ -245,8 +248,6 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EAX] = ret;
}
break;
#endif
#ifdef TARGET_X86_64
case EXCP_VSYSCALL:
emulate_vsyscall(env);
break;
Expand Down
2 changes: 2 additions & 0 deletions meson.build
Expand Up @@ -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_FALLOCATE', cc.has_function('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
# thinking that Windows has posix_memalign()
config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
Expand Down

0 comments on commit cd041dd

Please sign in to comment.