mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* pc: Add a description for the i8042 property * kvm: support for nested FRED * tests/unit: fix warning when compiling test-nested-aio-poll with LTO * kvm: refactoring of VM creation * target/i386: expose IBPB-BRTYPE and SBPB CPUID bits to the guest * hw/char: clean up serial * remove virtfs-proxy-helper * target/i386/kvm: Report which action failed in kvm_arch_put/get_registers * qom: improvements to object_resolve_path*() # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmb++MsUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroPVnwf/cdvfxvDm22tEdlh8vHlV17HtVdcC # Hw334M/3PDvbTmGzPBg26lzo4nFS6SLrZ8ETCeqvuJrtKzqVk9bI8ssZW5KA4ijM # nkxguRPHO8E6U33ZSucc+Hn56+bAx4I2X80dLKXJ87OsbMffIeJ6aHGSEI1+fKVh # pK7q53+Y3lQWuRBGhDIyKNuzqU4g+irpQwXOhux63bV3ADadmsqzExP6Gmtl8OKM # DylPu1oK7EPZumlSiJa7Gy1xBqL4Rc4wGPNYx2RVRjp+i7W2/Y1uehm3wSBw+SXC # a6b7SvLoYfWYS14/qCF4cBL3sJH/0f/4g8ZAhDDxi2i5kBr0/5oioDyE/A== # =/zo4 # -----END PGP SIGNATURE----- # gpg: Signature made Thu 03 Oct 2024 21:04:27 BST # 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] # 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: (23 commits) qom: update object_resolve_path*() documentation qom: set *ambiguous on all paths qom: rename object_resolve_path_type() "ambiguousp" target/i386/kvm: Report which action failed in kvm_arch_put/get_registers kvm: Allow kvm_arch_get/put_registers to accept Error** accel/kvm: refactor dirty ring setup minikconf: print error entirely on stderr 9p: remove 'proxy' filesystem backend driver hw/char: Extract serial-mm hw/char/serial.h: Extract serial-isa.h hw: Remove unused inclusion of hw/char/serial.h target/i386: Expose IBPB-BRTYPE and SBPB CPUID bits to the guest kvm: refactor core virtual machine creation into its own function kvm/i386: replace identity_base variable with a constant kvm/i386: refactor kvm_arch_init and split it into smaller functions kvm: replace fprintf with error_report()/printf() in kvm_init() kvm/i386: fix return values of is_host_cpu_intel() kvm/i386: make kvm_filter_msr() and related definitions private to kvm module hw/i386/pc: Add a description for the i8042 property tests/unit: remove block layer code from test-nested-aio-poll ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # hw/arm/Kconfig # hw/arm/pxa2xx.c
This commit is contained in:
@@ -2207,20 +2207,12 @@ S: Maintained
|
||||
W: https://wiki.qemu.org/Documentation/9p
|
||||
F: hw/9pfs/
|
||||
X: hw/9pfs/xen-9p*
|
||||
X: hw/9pfs/9p-proxy*
|
||||
F: fsdev/
|
||||
X: fsdev/virtfs-proxy-helper.c
|
||||
F: tests/qtest/virtio-9p-test.c
|
||||
F: tests/qtest/libqos/virtio-9p*
|
||||
T: git https://gitlab.com/gkurz/qemu.git 9p-next
|
||||
T: git https://github.com/cschoenebeck/qemu.git 9p.next
|
||||
|
||||
virtio-9p-proxy
|
||||
F: hw/9pfs/9p-proxy*
|
||||
F: fsdev/virtfs-proxy-helper.c
|
||||
F: docs/tools/virtfs-proxy-helper.rst
|
||||
S: Obsolete
|
||||
|
||||
virtio-blk
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
|
||||
+204
-150
@@ -2381,171 +2381,64 @@ uint32_t kvm_dirty_ring_size(void)
|
||||
return kvm_state->kvm_dirty_ring_size;
|
||||
}
|
||||
|
||||
static int kvm_init(MachineState *ms)
|
||||
static int do_kvm_create_vm(MachineState *ms, int type)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
static const char upgrade_note[] =
|
||||
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
|
||||
"(see http://sourceforge.net/projects/kvm).\n";
|
||||
const struct {
|
||||
const char *name;
|
||||
int num;
|
||||
} num_cpus[] = {
|
||||
{ "SMP", ms->smp.cpus },
|
||||
{ "hotpluggable", ms->smp.max_cpus },
|
||||
{ /* end of list */ }
|
||||
}, *nc = num_cpus;
|
||||
int soft_vcpus_limit, hard_vcpus_limit;
|
||||
KVMState *s;
|
||||
const KVMCapabilityInfo *missing_cap;
|
||||
int ret;
|
||||
int type;
|
||||
uint64_t dirty_log_manual_caps;
|
||||
|
||||
qemu_mutex_init(&kml_slots_lock);
|
||||
|
||||
s = KVM_STATE(ms->accelerator);
|
||||
|
||||
/*
|
||||
* On systems where the kernel can support different base page
|
||||
* sizes, host page size may be different from TARGET_PAGE_SIZE,
|
||||
* even with KVM. TARGET_PAGE_SIZE is assumed to be the minimum
|
||||
* page size for the system though.
|
||||
*/
|
||||
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size());
|
||||
|
||||
s->sigmask_len = 8;
|
||||
accel_blocker_init();
|
||||
|
||||
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
|
||||
QTAILQ_INIT(&s->kvm_sw_breakpoints);
|
||||
#endif
|
||||
QLIST_INIT(&s->kvm_parked_vcpus);
|
||||
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
|
||||
if (s->fd == -1) {
|
||||
fprintf(stderr, "Could not access KVM kernel module: %m\n");
|
||||
ret = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
|
||||
if (ret < KVM_API_VERSION) {
|
||||
if (ret >= 0) {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
fprintf(stderr, "kvm version too old\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret > KVM_API_VERSION) {
|
||||
ret = -EINVAL;
|
||||
fprintf(stderr, "kvm version not supported\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
|
||||
kvm_guest_memfd_supported =
|
||||
kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
|
||||
kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
|
||||
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
||||
|
||||
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
|
||||
s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
||||
|
||||
/* If unspecified, use the default value */
|
||||
if (!s->nr_slots) {
|
||||
s->nr_slots = 32;
|
||||
}
|
||||
|
||||
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
|
||||
if (s->nr_as <= 1) {
|
||||
s->nr_as = 1;
|
||||
}
|
||||
s->as = g_new0(struct KVMAs, s->nr_as);
|
||||
|
||||
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||
g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||
"kvm-type",
|
||||
&error_abort);
|
||||
type = mc->kvm_type(ms, kvm_type);
|
||||
} else if (mc->kvm_type) {
|
||||
type = mc->kvm_type(ms, NULL);
|
||||
} else {
|
||||
type = kvm_arch_get_default_type(ms);
|
||||
}
|
||||
|
||||
if (type < 0) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
||||
} while (ret == -EINTR);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret,
|
||||
strerror(-ret));
|
||||
error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
|
||||
|
||||
#ifdef TARGET_S390X
|
||||
if (ret == -EINVAL) {
|
||||
fprintf(stderr,
|
||||
"Host kernel setup problem detected. Please verify:\n");
|
||||
fprintf(stderr, "- for kernels supporting the switch_amode or"
|
||||
" user_mode parameters, whether\n");
|
||||
fprintf(stderr,
|
||||
" user space is running in primary address space\n");
|
||||
fprintf(stderr,
|
||||
"- for kernels supporting the vm.allocate_pgste sysctl, "
|
||||
"whether it is enabled\n");
|
||||
error_printf("Host kernel setup problem detected."
|
||||
" Please verify:\n");
|
||||
error_printf("- for kernels supporting the"
|
||||
" switch_amode or user_mode parameters, whether");
|
||||
error_printf(" user space is running in primary address space\n");
|
||||
error_printf("- for kernels supporting the vm.allocate_pgste"
|
||||
" sysctl, whether it is enabled\n");
|
||||
}
|
||||
#elif defined(TARGET_PPC)
|
||||
if (ret == -EINVAL) {
|
||||
fprintf(stderr,
|
||||
"PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||
(type == 2) ? "pr" : "hv");
|
||||
error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||
(type == 2) ? "pr" : "hv");
|
||||
}
|
||||
#endif
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->vmfd = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* check the vcpu limits */
|
||||
soft_vcpus_limit = kvm_recommended_vcpus(s);
|
||||
hard_vcpus_limit = kvm_max_vcpus(s);
|
||||
static int find_kvm_machine_type(MachineState *ms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
int type;
|
||||
|
||||
while (nc->name) {
|
||||
if (nc->num > soft_vcpus_limit) {
|
||||
warn_report("Number of %s cpus requested (%d) exceeds "
|
||||
"the recommended cpus supported by KVM (%d)",
|
||||
nc->name, nc->num, soft_vcpus_limit);
|
||||
|
||||
if (nc->num > hard_vcpus_limit) {
|
||||
fprintf(stderr, "Number of %s cpus requested (%d) exceeds "
|
||||
"the maximum cpus supported by KVM (%d)\n",
|
||||
nc->name, nc->num, hard_vcpus_limit);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
nc++;
|
||||
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||
g_autofree char *kvm_type;
|
||||
kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||
"kvm-type",
|
||||
&error_abort);
|
||||
type = mc->kvm_type(ms, kvm_type);
|
||||
} else if (mc->kvm_type) {
|
||||
type = mc->kvm_type(ms, NULL);
|
||||
} else {
|
||||
type = kvm_arch_get_default_type(ms);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
|
||||
if (!missing_cap) {
|
||||
missing_cap =
|
||||
kvm_check_extension_list(s, kvm_arch_required_capabilities);
|
||||
}
|
||||
if (missing_cap) {
|
||||
ret = -EINVAL;
|
||||
fprintf(stderr, "kvm does not support %s\n%s",
|
||||
missing_cap->name, upgrade_note);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
||||
s->coalesced_pio = s->coalesced_mmio &&
|
||||
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||
static int kvm_setup_dirty_ring(KVMState *s)
|
||||
{
|
||||
uint64_t dirty_log_manual_caps;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Enable KVM dirty ring if supported, otherwise fall back to
|
||||
@@ -2553,7 +2446,7 @@ static int kvm_init(MachineState *ms)
|
||||
*/
|
||||
ret = kvm_dirty_ring_init(s);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2588,6 +2481,144 @@ static int kvm_init(MachineState *ms)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_init(MachineState *ms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
static const char upgrade_note[] =
|
||||
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
|
||||
"(see http://sourceforge.net/projects/kvm).\n";
|
||||
const struct {
|
||||
const char *name;
|
||||
int num;
|
||||
} num_cpus[] = {
|
||||
{ "SMP", ms->smp.cpus },
|
||||
{ "hotpluggable", ms->smp.max_cpus },
|
||||
{ /* end of list */ }
|
||||
}, *nc = num_cpus;
|
||||
int soft_vcpus_limit, hard_vcpus_limit;
|
||||
KVMState *s;
|
||||
const KVMCapabilityInfo *missing_cap;
|
||||
int ret;
|
||||
int type;
|
||||
|
||||
qemu_mutex_init(&kml_slots_lock);
|
||||
|
||||
s = KVM_STATE(ms->accelerator);
|
||||
|
||||
/*
|
||||
* On systems where the kernel can support different base page
|
||||
* sizes, host page size may be different from TARGET_PAGE_SIZE,
|
||||
* even with KVM. TARGET_PAGE_SIZE is assumed to be the minimum
|
||||
* page size for the system though.
|
||||
*/
|
||||
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size());
|
||||
|
||||
s->sigmask_len = 8;
|
||||
accel_blocker_init();
|
||||
|
||||
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
|
||||
QTAILQ_INIT(&s->kvm_sw_breakpoints);
|
||||
#endif
|
||||
QLIST_INIT(&s->kvm_parked_vcpus);
|
||||
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
|
||||
if (s->fd == -1) {
|
||||
error_report("Could not access KVM kernel module: %m");
|
||||
ret = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
|
||||
if (ret < KVM_API_VERSION) {
|
||||
if (ret >= 0) {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
error_report("kvm version too old");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret > KVM_API_VERSION) {
|
||||
ret = -EINVAL;
|
||||
error_report("kvm version not supported");
|
||||
goto err;
|
||||
}
|
||||
|
||||
kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
|
||||
kvm_guest_memfd_supported =
|
||||
kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
|
||||
kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
|
||||
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
||||
|
||||
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
|
||||
s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
||||
|
||||
/* If unspecified, use the default value */
|
||||
if (!s->nr_slots) {
|
||||
s->nr_slots = 32;
|
||||
}
|
||||
|
||||
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
|
||||
if (s->nr_as <= 1) {
|
||||
s->nr_as = 1;
|
||||
}
|
||||
s->as = g_new0(struct KVMAs, s->nr_as);
|
||||
|
||||
type = find_kvm_machine_type(ms);
|
||||
if (type < 0) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = do_kvm_create_vm(ms, type);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->vmfd = ret;
|
||||
|
||||
/* check the vcpu limits */
|
||||
soft_vcpus_limit = kvm_recommended_vcpus(s);
|
||||
hard_vcpus_limit = kvm_max_vcpus(s);
|
||||
|
||||
while (nc->name) {
|
||||
if (nc->num > soft_vcpus_limit) {
|
||||
warn_report("Number of %s cpus requested (%d) exceeds "
|
||||
"the recommended cpus supported by KVM (%d)",
|
||||
nc->name, nc->num, soft_vcpus_limit);
|
||||
|
||||
if (nc->num > hard_vcpus_limit) {
|
||||
error_report("Number of %s cpus requested (%d) exceeds "
|
||||
"the maximum cpus supported by KVM (%d)",
|
||||
nc->name, nc->num, hard_vcpus_limit);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
nc++;
|
||||
}
|
||||
|
||||
missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
|
||||
if (!missing_cap) {
|
||||
missing_cap =
|
||||
kvm_check_extension_list(s, kvm_arch_required_capabilities);
|
||||
}
|
||||
if (missing_cap) {
|
||||
ret = -EINVAL;
|
||||
error_report("kvm does not support %s", missing_cap->name);
|
||||
error_printf("%s", upgrade_note);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
||||
s->coalesced_pio = s->coalesced_mmio &&
|
||||
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||
|
||||
ret = kvm_setup_dirty_ring(s);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef KVM_CAP_VCPU_EVENTS
|
||||
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
|
||||
#endif
|
||||
@@ -2762,9 +2793,15 @@ void kvm_flush_coalesced_mmio_buffer(void)
|
||||
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
|
||||
{
|
||||
if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
|
||||
int ret = kvm_arch_get_registers(cpu);
|
||||
Error *err = NULL;
|
||||
int ret = kvm_arch_get_registers(cpu, &err);
|
||||
if (ret) {
|
||||
error_report("Failed to get registers: %s", strerror(-ret));
|
||||
if (err) {
|
||||
error_reportf_err(err, "Failed to synchronize CPU state: ");
|
||||
} else {
|
||||
error_report("Failed to get registers: %s", strerror(-ret));
|
||||
}
|
||||
|
||||
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||
}
|
||||
@@ -2782,9 +2819,15 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
|
||||
|
||||
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
|
||||
{
|
||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
|
||||
Error *err = NULL;
|
||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE, &err);
|
||||
if (ret) {
|
||||
error_report("Failed to put registers after reset: %s", strerror(-ret));
|
||||
if (err) {
|
||||
error_reportf_err(err, "Restoring resisters after reset: ");
|
||||
} else {
|
||||
error_report("Failed to put registers after reset: %s",
|
||||
strerror(-ret));
|
||||
}
|
||||
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||
}
|
||||
@@ -2799,9 +2842,15 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
|
||||
|
||||
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
|
||||
{
|
||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
|
||||
Error *err = NULL;
|
||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE, &err);
|
||||
if (ret) {
|
||||
error_report("Failed to put registers after init: %s", strerror(-ret));
|
||||
if (err) {
|
||||
error_reportf_err(err, "Putting registers after init: ");
|
||||
} else {
|
||||
error_report("Failed to put registers after init: %s",
|
||||
strerror(-ret));
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -2991,10 +3040,15 @@ int kvm_cpu_exec(CPUState *cpu)
|
||||
MemTxAttrs attrs;
|
||||
|
||||
if (cpu->vcpu_dirty) {
|
||||
ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
|
||||
Error *err = NULL;
|
||||
ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE, &err);
|
||||
if (ret) {
|
||||
error_report("Failed to put registers after init: %s",
|
||||
strerror(-ret));
|
||||
if (err) {
|
||||
error_reportf_err(err, "Putting registers after init: ");
|
||||
} else {
|
||||
error_report("Failed to put registers after init: %s",
|
||||
strerror(-ret));
|
||||
}
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -314,28 +314,6 @@ the addition of volatile memory support, it is now necessary to distinguish
|
||||
between persistent and volatile memory backends. As such, memdev is deprecated
|
||||
in favor of persistent-memdev.
|
||||
|
||||
``-fsdev proxy`` and ``-virtfs proxy`` (since 8.1)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 9p ``proxy`` filesystem backend driver has been deprecated and will be
|
||||
removed (along with its proxy helper daemon) in a future version of QEMU. Please
|
||||
use ``-fsdev local`` or ``-virtfs local`` for using the 9p ``local`` filesystem
|
||||
backend, or alternatively consider deploying virtiofsd instead.
|
||||
|
||||
The 9p ``proxy`` backend was originally developed as an alternative to the 9p
|
||||
``local`` backend. The idea was to enhance security by dispatching actual low
|
||||
level filesystem operations from 9p server (QEMU process) over to a separate
|
||||
process (the virtfs-proxy-helper binary). However this alternative never gained
|
||||
momentum. The proxy backend is much slower than the local backend, hasn't seen
|
||||
any development in years, and showed to be less secure, especially due to the
|
||||
fact that its helper daemon must be run as root, whereas with the local backend
|
||||
QEMU is typically run as unprivileged user and allows to tighten behaviour by
|
||||
mapping permissions et al by using its 'mapped' security model option.
|
||||
|
||||
Nowadays it would make sense to reimplement the ``proxy`` backend by using
|
||||
QEMU's ``vhost`` feature, which would eliminate the high latency costs under
|
||||
which the 9p ``proxy`` backend currently suffers. However as of to date nobody
|
||||
has indicated plans for such kind of reimplementation unfortunately.
|
||||
|
||||
RISC-V CPU properties which start with capital 'Z' (since 8.2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -517,6 +517,20 @@ The virtio-blk SCSI passthrough feature is a legacy VIRTIO feature. VIRTIO 1.0
|
||||
and later do not support it because the virtio-scsi device was introduced for
|
||||
full SCSI support. Use virtio-scsi instead when SCSI passthrough is required.
|
||||
|
||||
``-fsdev proxy`` and ``-virtfs proxy`` (since 9.2)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The 9p ``proxy`` filesystem backend driver was originally developed to
|
||||
enhance security by dispatching low level filesystem operations from 9p
|
||||
server (QEMU process) over to a separate process (the virtfs-proxy-helper
|
||||
binary). However the proxy backend was much slower than the local backend,
|
||||
didn't see any development in years, and showed to be less secure,
|
||||
especially due to the fact that its helper daemon must be run as root.
|
||||
|
||||
Use ``local``, possibly mapping permissions et al by using its 'mapped'
|
||||
security model option, or switch to ``virtiofs``. The virtiofs daemon
|
||||
``virtiofsd`` uses vhost to eliminate the high latency costs of the 9p
|
||||
``proxy`` backend.
|
||||
|
||||
User-mode emulator command line arguments
|
||||
-----------------------------------------
|
||||
|
||||
@@ -275,9 +275,6 @@ man_pages = [
|
||||
('tools/qemu-trace-stap', 'qemu-trace-stap',
|
||||
'QEMU SystemTap trace tool',
|
||||
[], 1),
|
||||
('tools/virtfs-proxy-helper', 'virtfs-proxy-helper',
|
||||
'QEMU 9p virtfs proxy filesystem helper',
|
||||
['M. Mohan Kumar'], 1),
|
||||
]
|
||||
man_make_section_directory = False
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ if build_docs
|
||||
'qemu-pr-helper.8': (have_tools ? 'man8' : ''),
|
||||
'qemu-storage-daemon.1': (have_tools ? 'man1' : ''),
|
||||
'qemu-trace-stap.1': (stap.found() ? 'man1' : ''),
|
||||
'virtfs-proxy-helper.1': (have_virtfs_proxy_helper ? 'man1' : ''),
|
||||
'qemu.1': 'man1',
|
||||
'qemu-block-drivers.7': 'man7',
|
||||
'qemu-cpu-models.7': 'man7'
|
||||
|
||||
@@ -15,5 +15,4 @@ command line utilities and other standalone programs.
|
||||
qemu-nbd
|
||||
qemu-pr-helper
|
||||
qemu-trace-stap
|
||||
virtfs-proxy-helper
|
||||
qemu-vmsr-helper
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
QEMU 9p virtfs proxy filesystem helper
|
||||
======================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**virtfs-proxy-helper** [*OPTIONS*]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
NOTE: The 9p 'proxy' backend is deprecated (since QEMU 8.1) and will be
|
||||
removed, along with this daemon, in a future version of QEMU!
|
||||
|
||||
Pass-through security model in QEMU 9p server needs root privilege to do
|
||||
few file operations (like chown, chmod to any mode/uid:gid). There are two
|
||||
issues in pass-through security model:
|
||||
|
||||
- TOCTTOU vulnerability: Following symbolic links in the server could
|
||||
provide access to files beyond 9p export path.
|
||||
|
||||
- Running QEMU with root privilege could be a security issue.
|
||||
|
||||
To overcome above issues, following approach is used: A new filesystem
|
||||
type 'proxy' is introduced. Proxy FS uses chroot + socket combination
|
||||
for securing the vulnerability known with following symbolic links.
|
||||
Intention of adding a new filesystem type is to allow qemu to run
|
||||
in non-root mode, but doing privileged operations using socket IO.
|
||||
|
||||
Proxy helper (a stand alone binary part of qemu) is invoked with
|
||||
root privileges. Proxy helper chroots into 9p export path and creates
|
||||
a socket pair or a named socket based on the command line parameter.
|
||||
QEMU and proxy helper communicate using this socket. QEMU proxy fs
|
||||
driver sends filesystem request to proxy helper and receives the
|
||||
response from it.
|
||||
|
||||
The proxy helper is designed so that it can drop root privileges except
|
||||
for the capabilities needed for doing filesystem operations.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
The following options are supported:
|
||||
|
||||
.. program:: virtfs-proxy-helper
|
||||
|
||||
.. option:: -h
|
||||
|
||||
Display help and exit
|
||||
|
||||
.. option:: -p, --path PATH
|
||||
|
||||
Path to export for proxy filesystem driver
|
||||
|
||||
.. option:: -f, --fd SOCKET_ID
|
||||
|
||||
Use given file descriptor as socket descriptor for communicating with
|
||||
qemu proxy fs drier. Usually a helper like libvirt will create
|
||||
socketpair and pass one of the fds as parameter to this option.
|
||||
|
||||
.. option:: -s, --socket SOCKET_FILE
|
||||
|
||||
Creates named socket file for communicating with qemu proxy fs driver
|
||||
|
||||
.. option:: -u, --uid UID
|
||||
|
||||
uid to give access to named socket file; used in combination with -g.
|
||||
|
||||
.. option:: -g, --gid GID
|
||||
|
||||
gid to give access to named socket file; used in combination with -u.
|
||||
|
||||
.. option:: -n, --nodaemon
|
||||
|
||||
Run as a normal program. By default program will run in daemon mode
|
||||
@@ -8,11 +8,3 @@ fsdev_ss.add(when: ['CONFIG_FSDEV_9P'], if_true: files(
|
||||
if host_os in ['linux', 'darwin']
|
||||
system_ss.add_all(fsdev_ss)
|
||||
endif
|
||||
|
||||
if have_virtfs_proxy_helper
|
||||
executable('virtfs-proxy-helper',
|
||||
files('virtfs-proxy-helper.c', '9p-marshal.c', '9p-iov-marshal.c'),
|
||||
dependencies: [qemuutil, libattr, libcap_ng],
|
||||
install: true,
|
||||
install_dir: get_option('libexecdir'))
|
||||
endif
|
||||
|
||||
@@ -89,17 +89,6 @@ static FsDriverTable FsDrivers[] = {
|
||||
NULL
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "proxy",
|
||||
.ops = &proxy_ops,
|
||||
.opts = (const char * []) {
|
||||
COMMON_FS_DRIVER_OPTIONS,
|
||||
"socket",
|
||||
"sock_fd",
|
||||
"writeout",
|
||||
NULL
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int validate_opt(void *opaque, const char *name, const char *value,
|
||||
@@ -133,14 +122,6 @@ int qemu_fsdev_add(QemuOpts *opts, Error **errp)
|
||||
}
|
||||
|
||||
if (fsdriver) {
|
||||
if (strncmp(fsdriver, "proxy", 5) == 0) {
|
||||
warn_report(
|
||||
"'-fsdev proxy' and '-virtfs proxy' are deprecated, use "
|
||||
"'local' instead of 'proxy, or consider deploying virtiofsd "
|
||||
"as alternative to 9p"
|
||||
);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(FsDrivers); i++) {
|
||||
if (strcmp(FsDrivers[i].name, fsdriver) == 0) {
|
||||
break;
|
||||
|
||||
@@ -18,5 +18,4 @@ int qemu_fsdev_add(QemuOpts *opts, Error **errp);
|
||||
FsDriverEntry *get_fsdev_fsentry(char *id);
|
||||
extern FileOperations local_ops;
|
||||
extern FileOperations synth_ops;
|
||||
extern FileOperations proxy_ops;
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
-1279
File diff suppressed because it is too large
Load Diff
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* 9p Proxy callback
|
||||
*
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* M. Mohan Kumar <mohan@in.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: The 9p 'proxy' backend is deprecated (since QEMU 8.1) and will be
|
||||
* removed in a future version of QEMU!
|
||||
*/
|
||||
|
||||
#ifndef QEMU_9P_PROXY_H
|
||||
#define QEMU_9P_PROXY_H
|
||||
|
||||
#define PROXY_MAX_IO_SZ (64 * 1024)
|
||||
#define V9FS_FD_VALID INT_MAX
|
||||
|
||||
/*
|
||||
* proxy iovec only support one element and
|
||||
* marsha/unmarshal doesn't do little endian conversion.
|
||||
*/
|
||||
#define proxy_unmarshal(in_sg, offset, fmt, args...) \
|
||||
v9fs_iov_unmarshal(in_sg, 1, offset, 0, fmt, ##args)
|
||||
#define proxy_marshal(out_sg, offset, fmt, args...) \
|
||||
v9fs_iov_marshal(out_sg, 1, offset, 0, fmt, ##args)
|
||||
|
||||
union MsgControl {
|
||||
struct cmsghdr cmsg;
|
||||
char control[CMSG_SPACE(sizeof(int))];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
} ProxyHeader;
|
||||
|
||||
#define PROXY_HDR_SZ (sizeof(ProxyHeader))
|
||||
|
||||
enum {
|
||||
T_SUCCESS = 0,
|
||||
T_ERROR,
|
||||
T_OPEN,
|
||||
T_CREATE,
|
||||
T_MKNOD,
|
||||
T_MKDIR,
|
||||
T_SYMLINK,
|
||||
T_LINK,
|
||||
T_LSTAT,
|
||||
T_READLINK,
|
||||
T_STATFS,
|
||||
T_CHMOD,
|
||||
T_CHOWN,
|
||||
T_TRUNCATE,
|
||||
T_UTIME,
|
||||
T_RENAME,
|
||||
T_REMOVE,
|
||||
T_LGETXATTR,
|
||||
T_LLISTXATTR,
|
||||
T_LSETXATTR,
|
||||
T_LREMOVEXATTR,
|
||||
T_GETVERSION,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint64_t st_dev;
|
||||
uint64_t st_ino;
|
||||
uint64_t st_nlink;
|
||||
uint32_t st_mode;
|
||||
uint32_t st_uid;
|
||||
uint32_t st_gid;
|
||||
uint64_t st_rdev;
|
||||
uint64_t st_size;
|
||||
uint64_t st_blksize;
|
||||
uint64_t st_blocks;
|
||||
uint64_t st_atim_sec;
|
||||
uint64_t st_atim_nsec;
|
||||
uint64_t st_mtim_sec;
|
||||
uint64_t st_mtim_nsec;
|
||||
uint64_t st_ctim_sec;
|
||||
uint64_t st_ctim_nsec;
|
||||
} ProxyStat;
|
||||
|
||||
typedef struct {
|
||||
uint64_t f_type;
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_fsid[2];
|
||||
uint64_t f_namelen;
|
||||
uint64_t f_frsize;
|
||||
} ProxyStatFS;
|
||||
#endif
|
||||
@@ -2,7 +2,6 @@ fs_ss = ss.source_set()
|
||||
fs_ss.add(files(
|
||||
'9p-local.c',
|
||||
'9p-posix-acl.c',
|
||||
'9p-proxy.c',
|
||||
'9p-synth.c',
|
||||
'9p-xattr-user.c',
|
||||
'9p-xattr.c',
|
||||
|
||||
+9
-9
@@ -121,7 +121,7 @@ config MUSICPAL
|
||||
select MARVELL_88W8618
|
||||
select PTIMER
|
||||
select PFLASH_CFI02
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select WM8750
|
||||
|
||||
config NETDUINO2
|
||||
@@ -150,7 +150,7 @@ config OMAP
|
||||
select NAND
|
||||
select PFLASH_CFI01
|
||||
select SD
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
|
||||
config REALVIEW
|
||||
bool
|
||||
@@ -321,7 +321,7 @@ config ALLWINNER_A10
|
||||
select ALLWINNER_EMAC
|
||||
select ALLWINNER_I2C
|
||||
select AXP2XX_PMU
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select UNIMP
|
||||
select USB_OHCI_SYSBUS
|
||||
|
||||
@@ -333,7 +333,7 @@ config ALLWINNER_H3
|
||||
select ALLWINNER_SUN8I_EMAC
|
||||
select ALLWINNER_I2C
|
||||
select ALLWINNER_WDT
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select ARM_TIMER
|
||||
select ARM_GIC
|
||||
select UNIMP
|
||||
@@ -349,7 +349,7 @@ config ALLWINNER_R40
|
||||
select ALLWINNER_A10_PIT
|
||||
select ALLWINNER_WDT
|
||||
select AXP2XX_PMU
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select ARM_TIMER
|
||||
select ARM_GIC
|
||||
select UNIMP
|
||||
@@ -464,7 +464,7 @@ config NPCM7XX
|
||||
select ISL_PMBUS_VR
|
||||
select PL310 # cache controller
|
||||
select PMBUS
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select SSI
|
||||
select UNIMP
|
||||
select PCA954X
|
||||
@@ -486,7 +486,7 @@ config FSL_IMX31
|
||||
default y
|
||||
depends on TCG && ARM
|
||||
imply I2C_DEVICES
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select IMX
|
||||
select IMX_I2C
|
||||
select WDT_IMX2
|
||||
@@ -515,7 +515,7 @@ config ASPEED_SOC
|
||||
select I2C
|
||||
select DPS310
|
||||
select PCA9552
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select SMBUS_EEPROM
|
||||
select PCA954X
|
||||
select SSI
|
||||
@@ -603,7 +603,7 @@ config MSF2
|
||||
bool
|
||||
select ARM_V7M
|
||||
select PTIMER
|
||||
select SERIAL
|
||||
select SERIAL_MM
|
||||
select SSI
|
||||
select UNIMP
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/char/serial-mm.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/arm/allwinner-a10.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "qemu/units.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/char/serial-mm.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/usb/hcd-ehci.h"
|
||||
#include "hw/loader.h"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "hw/boards.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/char/serial-mm.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/usb/hcd-ehci.h"
|
||||
#include "hw/loader.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "hw/arm/aspeed_soc.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/char/serial-mm.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/i2c/aspeed_i2c.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user