kvm/i386: Add xen-evtchn-max-pirq property
The default number of PIRQs is set to 256 to avoid issues with 32-bit MSI devices. Allow it to be increased if the user desires. Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Reviewed-by: Paul Durrant <paul@xen.org>
This commit is contained in:
parent
6096cf7877
commit
e16aff4cc2
@ -3705,6 +3705,7 @@ static void kvm_accel_instance_init(Object *obj)
|
|||||||
s->notify_window = 0;
|
s->notify_window = 0;
|
||||||
s->xen_version = 0;
|
s->xen_version = 0;
|
||||||
s->xen_gnttab_max_frames = 64;
|
s->xen_gnttab_max_frames = 64;
|
||||||
|
s->xen_evtchn_max_pirq = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,17 +302,18 @@ void xen_evtchn_create(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We could parameterise the number of PIRQs available if needed,
|
* The Xen scheme for encoding PIRQ# into an MSI message is not
|
||||||
* but for now limit it to 256. The Xen scheme for encoding PIRQ#
|
* compatible with 32-bit MSI, as it puts the high bits of the
|
||||||
* into an MSI message is not compatible with 32-bit MSI, as it
|
* PIRQ# into the high bits of the MSI message address, instead of
|
||||||
* puts the high bits of the PIRQ# into the high bits of the MSI
|
* using the Extended Destination ID in address bits 4-11 which
|
||||||
* message address, instead of using the Extended Destination ID
|
* perhaps would have been a better choice.
|
||||||
* in address bits 4-11 which perhaps would have been a better
|
*
|
||||||
* choice. So to keep life simple, just stick with 256 as the
|
* To keep life simple, kvm_accel_instance_init() initialises the
|
||||||
* default, which conveniently doesn't need to set anything
|
* default to 256. which conveniently doesn't need to set anything
|
||||||
* outside the low 32 bits of the address.
|
* outside the low 32 bits of the address. It can be increased by
|
||||||
|
* setting the xen-evtchn-max-pirq property.
|
||||||
*/
|
*/
|
||||||
s->nr_pirqs = 256;
|
s->nr_pirqs = kvm_xen_get_evtchn_max_pirq();
|
||||||
|
|
||||||
s->nr_pirq_inuse_words = DIV_ROUND_UP(s->nr_pirqs, 64);
|
s->nr_pirq_inuse_words = DIV_ROUND_UP(s->nr_pirqs, 64);
|
||||||
s->pirq_inuse_bitmap = g_new0(uint64_t, s->nr_pirq_inuse_words);
|
s->pirq_inuse_bitmap = g_new0(uint64_t, s->nr_pirq_inuse_words);
|
||||||
|
@ -121,6 +121,7 @@ struct KVMState
|
|||||||
uint32_t xen_version;
|
uint32_t xen_version;
|
||||||
uint32_t xen_caps;
|
uint32_t xen_caps;
|
||||||
uint16_t xen_gnttab_max_frames;
|
uint16_t xen_gnttab_max_frames;
|
||||||
|
uint16_t xen_evtchn_max_pirq;
|
||||||
};
|
};
|
||||||
|
|
||||||
void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
|
void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
|
||||||
|
@ -26,6 +26,7 @@ void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
|
|||||||
void kvm_xen_set_callback_asserted(void);
|
void kvm_xen_set_callback_asserted(void);
|
||||||
int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
|
int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
|
||||||
uint16_t kvm_xen_get_gnttab_max_frames(void);
|
uint16_t kvm_xen_get_gnttab_max_frames(void);
|
||||||
|
uint16_t kvm_xen_get_evtchn_max_pirq(void);
|
||||||
|
|
||||||
#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
|
#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
|
||||||
KVM_XEN_HVM_CONFIG_ ## cap))
|
KVM_XEN_HVM_CONFIG_ ## cap))
|
||||||
|
@ -5922,6 +5922,33 @@ static void kvm_arch_set_xen_gnttab_max_frames(Object *obj, Visitor *v,
|
|||||||
s->xen_gnttab_max_frames = value;
|
s->xen_gnttab_max_frames = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kvm_arch_get_xen_evtchn_max_pirq(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
KVMState *s = KVM_STATE(obj);
|
||||||
|
uint16_t value = s->xen_evtchn_max_pirq;
|
||||||
|
|
||||||
|
visit_type_uint16(v, name, &value, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kvm_arch_set_xen_evtchn_max_pirq(Object *obj, Visitor *v,
|
||||||
|
const char *name, void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
KVMState *s = KVM_STATE(obj);
|
||||||
|
Error *error = NULL;
|
||||||
|
uint16_t value;
|
||||||
|
|
||||||
|
visit_type_uint16(v, name, &value, &error);
|
||||||
|
if (error) {
|
||||||
|
error_propagate(errp, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->xen_evtchn_max_pirq = value;
|
||||||
|
}
|
||||||
|
|
||||||
void kvm_arch_accel_class_init(ObjectClass *oc)
|
void kvm_arch_accel_class_init(ObjectClass *oc)
|
||||||
{
|
{
|
||||||
object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
|
object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
|
||||||
@ -5954,6 +5981,13 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
object_class_property_set_description(oc, "xen-gnttab-max-frames",
|
object_class_property_set_description(oc, "xen-gnttab-max-frames",
|
||||||
"Maximum number of grant table frames");
|
"Maximum number of grant table frames");
|
||||||
|
|
||||||
|
object_class_property_add(oc, "xen-evtchn-max-pirq", "uint16",
|
||||||
|
kvm_arch_get_xen_evtchn_max_pirq,
|
||||||
|
kvm_arch_set_xen_evtchn_max_pirq,
|
||||||
|
NULL, NULL);
|
||||||
|
object_class_property_set_description(oc, "xen-evtchn-max-pirq",
|
||||||
|
"Maximum number of Xen PIRQs");
|
||||||
}
|
}
|
||||||
|
|
||||||
void kvm_set_max_apic_id(uint32_t max_apic_id)
|
void kvm_set_max_apic_id(uint32_t max_apic_id)
|
||||||
|
@ -1765,6 +1765,12 @@ uint16_t kvm_xen_get_gnttab_max_frames(void)
|
|||||||
return s->xen_gnttab_max_frames;
|
return s->xen_gnttab_max_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t kvm_xen_get_evtchn_max_pirq(void)
|
||||||
|
{
|
||||||
|
KVMState *s = KVM_STATE(current_accel());
|
||||||
|
return s->xen_evtchn_max_pirq;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_put_xen_state(CPUState *cs)
|
int kvm_put_xen_state(CPUState *cs)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = X86_CPU(cs);
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
Loading…
Reference in New Issue
Block a user