mirror of https://github.com/xemu-project/xemu.git
kvm-all: Pass an error object to kvm_device_access
In some circumstances, we don't want to abort if the kvm_device_access fails. This will be the case during ITS migration, in case the ITS table save/restore fails because the guest did not program the vITS correctly. So let's pass an error object to the function and return the ioctl value. New callers will be able to make a decision upon this returned value. Existing callers pass &error_abort which will cause the function to abort on failure. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Message-id: 1497023553-18411-2-git-send-email-eric.auger@redhat.com [PMM: wrapped long line] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
1403f36447
commit
556969e938
|
@ -100,14 +100,14 @@ static void kvm_gicd_access(GICState *s, int offset, int cpu,
|
||||||
uint32_t *val, bool write)
|
uint32_t *val, bool write)
|
||||||
{
|
{
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
|
||||||
KVM_VGIC_ATTR(offset, cpu), val, write);
|
KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_gicc_access(GICState *s, int offset, int cpu,
|
static void kvm_gicc_access(GICState *s, int offset, int cpu,
|
||||||
uint32_t *val, bool write)
|
uint32_t *val, bool write)
|
||||||
{
|
{
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
|
||||||
KVM_VGIC_ATTR(offset, cpu), val, write);
|
KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define for_each_irq_reg(_ctr, _max_irq, _field_width) \
|
#define for_each_irq_reg(_ctr, _max_irq, _field_width) \
|
||||||
|
@ -538,13 +538,14 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
||||||
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
|
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
|
||||||
uint32_t numirqs = s->num_irq;
|
uint32_t numirqs = s->num_irq;
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0,
|
||||||
&numirqs, true);
|
&numirqs, true, &error_abort);
|
||||||
}
|
}
|
||||||
/* Tell the kernel to complete VGIC initialization now */
|
/* Tell the kernel to complete VGIC initialization now */
|
||||||
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||||
KVM_DEV_ARM_VGIC_CTRL_INIT)) {
|
KVM_DEV_ARM_VGIC_CTRL_INIT)) {
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||||
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
|
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
|
||||||
|
&error_abort);
|
||||||
}
|
}
|
||||||
} else if (ret != -ENODEV && ret != -ENOTSUP) {
|
} else if (ret != -ENODEV && ret != -ENOTSUP) {
|
||||||
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
|
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
|
||||||
|
|
|
@ -78,7 +78,7 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
/* explicit init of the ITS */
|
/* explicit init of the ITS */
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||||
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
|
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);
|
||||||
|
|
||||||
/* register the base address */
|
/* register the base address */
|
||||||
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
|
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
|
|
|
@ -93,7 +93,7 @@ static inline void kvm_gicd_access(GICv3State *s, int offset,
|
||||||
{
|
{
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
|
||||||
KVM_VGIC_ATTR(offset, 0),
|
KVM_VGIC_ATTR(offset, 0),
|
||||||
val, write);
|
val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
|
static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
|
||||||
|
@ -101,7 +101,7 @@ static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
|
||||||
{
|
{
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
|
||||||
KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer),
|
KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer),
|
||||||
val, write);
|
val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
|
static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
|
||||||
|
@ -109,7 +109,7 @@ static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
|
||||||
{
|
{
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
|
||||||
KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer),
|
KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer),
|
||||||
val, write);
|
val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
|
static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
|
||||||
|
@ -119,7 +119,7 @@ static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
|
||||||
KVM_VGIC_ATTR(irq, s->cpu[cpu].gicr_typer) |
|
KVM_VGIC_ATTR(irq, s->cpu[cpu].gicr_typer) |
|
||||||
(VGIC_LEVEL_INFO_LINE_LEVEL <<
|
(VGIC_LEVEL_INFO_LINE_LEVEL <<
|
||||||
KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT),
|
KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT),
|
||||||
val, write);
|
val, write, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through each distributor IRQ related register; since bits
|
/* Loop through each distributor IRQ related register; since bits
|
||||||
|
@ -630,7 +630,7 @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
/* Initialize to actual HW supported configuration */
|
/* Initialize to actual HW supported configuration */
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
|
||||||
KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
|
KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
|
||||||
&c->icc_ctlr_el1[GICV3_NS], false);
|
&c->icc_ctlr_el1[GICV3_NS], false, &error_abort);
|
||||||
|
|
||||||
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
|
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
|
||||||
}
|
}
|
||||||
|
@ -717,11 +717,11 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
|
||||||
0, &s->num_irq, true);
|
0, &s->num_irq, true, &error_abort);
|
||||||
|
|
||||||
/* Tell the kernel to complete VGIC initialization now */
|
/* Tell the kernel to complete VGIC initialization now */
|
||||||
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
|
||||||
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
|
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);
|
||||||
|
|
||||||
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
|
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
|
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
|
||||||
|
|
|
@ -294,12 +294,15 @@ int kvm_device_check_attr(int fd, uint32_t group, uint64_t attr);
|
||||||
* @attr: the attribute of that group to set or get
|
* @attr: the attribute of that group to set or get
|
||||||
* @val: pointer to a storage area for the value
|
* @val: pointer to a storage area for the value
|
||||||
* @write: true for set and false for get operation
|
* @write: true for set and false for get operation
|
||||||
|
* @errp: error object handle
|
||||||
*
|
*
|
||||||
* This function is not allowed to fail. Use kvm_device_check_attr()
|
* Returns: 0 on success
|
||||||
* in order to check for the availability of optional attributes.
|
* < 0 on error
|
||||||
|
* Use kvm_device_check_attr() in order to check for the availability
|
||||||
|
* of optional attributes.
|
||||||
*/
|
*/
|
||||||
void kvm_device_access(int fd, int group, uint64_t attr,
|
int kvm_device_access(int fd, int group, uint64_t attr,
|
||||||
void *val, bool write);
|
void *val, bool write, Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_create_device - create a KVM device for the device control API
|
* kvm_create_device - create a KVM device for the device control API
|
||||||
|
|
14
kvm-all.c
14
kvm-all.c
|
@ -23,6 +23,7 @@
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "hw/pci/msix.h"
|
#include "hw/pci/msix.h"
|
||||||
|
@ -2216,8 +2217,8 @@ int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr)
|
||||||
return kvm_device_ioctl(dev_fd, KVM_HAS_DEVICE_ATTR, &attribute) ? 0 : 1;
|
return kvm_device_ioctl(dev_fd, KVM_HAS_DEVICE_ATTR, &attribute) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_device_access(int fd, int group, uint64_t attr,
|
int kvm_device_access(int fd, int group, uint64_t attr,
|
||||||
void *val, bool write)
|
void *val, bool write, Error **errp)
|
||||||
{
|
{
|
||||||
struct kvm_device_attr kvmattr;
|
struct kvm_device_attr kvmattr;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2231,11 +2232,12 @@ void kvm_device_access(int fd, int group, uint64_t attr,
|
||||||
write ? KVM_SET_DEVICE_ATTR : KVM_GET_DEVICE_ATTR,
|
write ? KVM_SET_DEVICE_ATTR : KVM_GET_DEVICE_ATTR,
|
||||||
&kvmattr);
|
&kvmattr);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error_report("KVM_%s_DEVICE_ATTR failed: %s",
|
error_setg_errno(errp, -err,
|
||||||
write ? "SET" : "GET", strerror(-err));
|
"KVM_%s_DEVICE_ATTR failed: Group %d "
|
||||||
error_printf("Group %d attr 0x%016" PRIx64 "\n", group, attr);
|
"attr 0x%016" PRIx64,
|
||||||
abort();
|
write ? "SET" : "GET", group, attr);
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 on success, 0 on failure */
|
/* Return 1 on success, 0 on failure */
|
||||||
|
|
Loading…
Reference in New Issue