mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
hyperv/vmbus: Redefine event flags.
- Nuke unnecessary union. - Avoid convoluted macro indirection. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6671
This commit is contained in:
parent
84bcd65e0f
commit
417afb00cb
6 changed files with 55 additions and 78 deletions
|
|
@ -33,6 +33,7 @@
|
|||
#include <sys/mutex.h>
|
||||
|
||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
||||
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||
|
||||
/*
|
||||
|
|
@ -713,8 +714,8 @@ hv_vmbus_release_unattached_channels(void)
|
|||
}
|
||||
hv_vmbus_free_vmbus_channel(channel);
|
||||
}
|
||||
bzero(hv_vmbus_g_connection.channels,
|
||||
sizeof(hv_vmbus_channel*) * HV_CHANNEL_MAX_COUNT);
|
||||
bzero(hv_vmbus_g_connection.channels,
|
||||
sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX);
|
||||
mtx_unlock(&hv_vmbus_g_connection.channel_lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <vm/pmap.h>
|
||||
|
||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
||||
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||
|
||||
/*
|
||||
|
|
@ -209,8 +210,7 @@ hv_vmbus_connect(void)
|
|||
M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
|
||||
hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
|
||||
HV_CHANNEL_MAX_COUNT,
|
||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
/*
|
||||
* Find the highest vmbus version number we can support.
|
||||
*/
|
||||
|
|
@ -292,20 +292,20 @@ hv_vmbus_disconnect(void)
|
|||
}
|
||||
|
||||
static __inline void
|
||||
vmbus_event_flags_proc(unsigned long *event_flags, int flag_cnt)
|
||||
vmbus_event_flags_proc(volatile u_long *event_flags, int flag_cnt)
|
||||
{
|
||||
int f;
|
||||
|
||||
for (f = 0; f < flag_cnt; ++f) {
|
||||
uint32_t rel_id_base;
|
||||
unsigned long flags;
|
||||
u_long flags;
|
||||
int bit;
|
||||
|
||||
if (event_flags[f] == 0)
|
||||
continue;
|
||||
|
||||
flags = atomic_swap_long(&event_flags[f], 0);
|
||||
rel_id_base = f << HV_CHANNEL_ULONG_SHIFT;
|
||||
rel_id_base = f << VMBUS_EVTFLAG_SHIFT;
|
||||
|
||||
while ((bit = ffsl(flags)) != 0) {
|
||||
struct hv_vmbus_channel *channel;
|
||||
|
|
@ -331,27 +331,27 @@ vmbus_event_flags_proc(unsigned long *event_flags, int flag_cnt)
|
|||
void
|
||||
vmbus_event_proc(struct vmbus_softc *sc, int cpu)
|
||||
{
|
||||
hv_vmbus_synic_event_flags *event;
|
||||
struct vmbus_evtflags *eventf;
|
||||
|
||||
/*
|
||||
* On Host with Win8 or above, the event page can be checked directly
|
||||
* to get the id of the channel that has the pending interrupt.
|
||||
*/
|
||||
event = VMBUS_PCPU_GET(sc, event_flag, cpu) + VMBUS_SINT_MESSAGE;
|
||||
vmbus_event_flags_proc(event->flagsul,
|
||||
VMBUS_PCPU_GET(sc, event_flag_cnt, cpu));
|
||||
eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
|
||||
vmbus_event_flags_proc(eventf->evt_flags,
|
||||
VMBUS_PCPU_GET(sc, event_flags_cnt, cpu));
|
||||
}
|
||||
|
||||
void
|
||||
vmbus_event_proc_compat(struct vmbus_softc *sc __unused, int cpu)
|
||||
{
|
||||
hv_vmbus_synic_event_flags *event;
|
||||
struct vmbus_evtflags *eventf;
|
||||
|
||||
event = VMBUS_PCPU_GET(sc, event_flag, cpu) + VMBUS_SINT_MESSAGE;
|
||||
if (atomic_testandclear_int(&event->flags32[0], 0)) {
|
||||
eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
|
||||
if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) {
|
||||
vmbus_event_flags_proc(
|
||||
hv_vmbus_g_connection.recv_interrupt_page,
|
||||
HV_MAX_NUM_CHANNELS_SUPPORTED >> HV_CHANNEL_ULONG_SHIFT);
|
||||
VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -414,8 +414,8 @@ vmbus_on_channel_open(const struct hv_vmbus_channel *chan)
|
|||
volatile int *flag_cnt_ptr;
|
||||
int flag_cnt;
|
||||
|
||||
flag_cnt = (chan->offer_msg.child_rel_id / HV_CHANNEL_ULONG_LEN) + 1;
|
||||
flag_cnt_ptr = VMBUS_PCPU_PTR(vmbus_get_softc(), event_flag_cnt,
|
||||
flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1;
|
||||
flag_cnt_ptr = VMBUS_PCPU_PTR(vmbus_get_softc(), event_flags_cnt,
|
||||
chan->target_cpu);
|
||||
|
||||
for (;;) {
|
||||
|
|
|
|||
|
|
@ -248,8 +248,8 @@ vmbus_synic_setup(void *xsc)
|
|||
*/
|
||||
orig = rdmsr(MSR_HV_SIEFP);
|
||||
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
|
||||
((VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
|
||||
MSR_HV_SIEFP_PGSHIFT);
|
||||
((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
|
||||
>> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
|
||||
wrmsr(MSR_HV_SIEFP, val);
|
||||
|
||||
|
||||
|
|
@ -339,11 +339,11 @@ vmbus_dma_alloc(struct vmbus_softc *sc)
|
|||
|
||||
ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
|
||||
PAGE_SIZE, 0, PAGE_SIZE,
|
||||
VMBUS_PCPU_PTR(sc, event_flag_dma, cpu),
|
||||
VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
|
||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
||||
if (ptr == NULL)
|
||||
return ENOMEM;
|
||||
VMBUS_PCPU_GET(sc, event_flag, cpu) = ptr;
|
||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -360,11 +360,11 @@ vmbus_dma_free(struct vmbus_softc *sc)
|
|||
VMBUS_PCPU_GET(sc, message, cpu));
|
||||
VMBUS_PCPU_GET(sc, message, cpu) = NULL;
|
||||
}
|
||||
if (VMBUS_PCPU_GET(sc, event_flag, cpu) != NULL) {
|
||||
if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
|
||||
hyperv_dmamem_free(
|
||||
VMBUS_PCPU_PTR(sc, event_flag_dma, cpu),
|
||||
VMBUS_PCPU_GET(sc, event_flag, cpu));
|
||||
VMBUS_PCPU_GET(sc, event_flag, cpu) = NULL;
|
||||
VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
|
||||
VMBUS_PCPU_GET(sc, event_flags, cpu));
|
||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,28 +50,6 @@ typedef uint16_t hv_vmbus_status;
|
|||
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
|
||||
#define HV_ANY_VP (0xFFFFFFFF)
|
||||
|
||||
/*
|
||||
* Synthetic interrupt controller flag constants.
|
||||
*/
|
||||
|
||||
#define HV_EVENT_FLAGS_COUNT (256 * 8)
|
||||
#define HV_EVENT_FLAGS_BYTE_COUNT (256)
|
||||
#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(uint32_t))
|
||||
#define HV_EVENT_FLAGS_ULONG_COUNT (256 / sizeof(unsigned long))
|
||||
|
||||
/**
|
||||
* max channel count <== event_flags_dword_count * bit_of_dword
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
#define HV_CHANNEL_ULONG_LEN (64)
|
||||
#define HV_CHANNEL_ULONG_SHIFT (6)
|
||||
#else
|
||||
#define HV_CHANNEL_ULONG_LEN (32)
|
||||
#define HV_CHANNEL_ULONG_SHIFT (5)
|
||||
#endif
|
||||
#define HV_CHANNEL_DWORD_LEN (32)
|
||||
#define HV_CHANNEL_MAX_COUNT \
|
||||
((HV_EVENT_FLAGS_DWORD_COUNT) * HV_CHANNEL_DWORD_LEN)
|
||||
/*
|
||||
* MessageId: HV_STATUS_INSUFFICIENT_BUFFERS
|
||||
* MessageText:
|
||||
|
|
@ -195,9 +173,6 @@ enum {
|
|||
|
||||
#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t)
|
||||
|
||||
struct vmbus_message;
|
||||
union vmbus_event_flags;
|
||||
|
||||
/*
|
||||
* Define hypervisor message types
|
||||
*/
|
||||
|
|
@ -253,21 +228,6 @@ typedef union _hv_vmbus_port_id {
|
|||
|
||||
typedef uint64_t hv_vmbus_partition_id;
|
||||
|
||||
/*
|
||||
* Maximum channels is determined by the size of the interrupt
|
||||
* page which is PAGE_SIZE. 1/2 of PAGE_SIZE is for
|
||||
* send endpoint interrupt and the other is receive
|
||||
* endpoint interrupt.
|
||||
*
|
||||
* Note: (PAGE_SIZE >> 1) << 3 allocates 16348 channels
|
||||
*/
|
||||
#define HV_MAX_NUM_CHANNELS (PAGE_SIZE >> 1) << 3
|
||||
|
||||
/*
|
||||
* (The value here must be in multiple of 32)
|
||||
*/
|
||||
#define HV_MAX_NUM_CHANNELS_SUPPORTED 256
|
||||
|
||||
/*
|
||||
* VM Bus connection states
|
||||
*/
|
||||
|
|
@ -390,16 +350,6 @@ typedef struct {
|
|||
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
||||
} hv_vmbus_input_post_message;
|
||||
|
||||
/*
|
||||
* Define the synthetic interrupt controller event flags format
|
||||
*/
|
||||
typedef union vmbus_event_flags {
|
||||
uint8_t flags8[HV_EVENT_FLAGS_BYTE_COUNT];
|
||||
uint32_t flags32[HV_EVENT_FLAGS_DWORD_COUNT];
|
||||
unsigned long flagsul[HV_EVENT_FLAGS_ULONG_COUNT];
|
||||
} hv_vmbus_synic_event_flags;
|
||||
CTASSERT(sizeof(hv_vmbus_synic_event_flags) == HV_EVENT_FLAGS_BYTE_COUNT);
|
||||
|
||||
/*
|
||||
* Declare the various hypercall operations
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,4 +53,30 @@ CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
|
|||
|
||||
#define VMBUS_MSGFLAG_PENDING 0x01
|
||||
|
||||
/*
|
||||
* Hyper-V SynIC event flags
|
||||
*/
|
||||
|
||||
#ifdef __LP64__
|
||||
#define VMBUS_EVTFLAGS_MAX 32
|
||||
#define VMBUS_EVTFLAG_SHIFT 6
|
||||
#else
|
||||
#define VMBUS_EVTFLAGS_MAX 64
|
||||
#define VMBUS_EVTFLAG_SHIFT 5
|
||||
#endif
|
||||
#define VMBUS_EVTFLAG_LEN (1 << VMBUS_EVTFLAG_SHIFT)
|
||||
#define VMBUS_EVTFLAGS_SIZE 256
|
||||
|
||||
struct vmbus_evtflags {
|
||||
u_long evt_flags[VMBUS_EVTFLAGS_MAX];
|
||||
} __packed;
|
||||
CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
|
||||
|
||||
/*
|
||||
* Channel
|
||||
*/
|
||||
|
||||
#define VMBUS_CHAN_MAX_COMPAT 256
|
||||
#define VMBUS_CHAN_MAX (VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX)
|
||||
|
||||
#endif /* !_VMBUS_REG_H_ */
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ struct vmbus_pcpu_data {
|
|||
u_long *intr_cnt; /* Hyper-V interrupt counter */
|
||||
struct vmbus_message *message; /* shared messages */
|
||||
uint32_t vcpuid; /* virtual cpuid */
|
||||
int event_flag_cnt; /* # of event flags */
|
||||
union vmbus_event_flags *event_flag; /* shared event flags */
|
||||
int event_flags_cnt;/* # of event flags */
|
||||
struct vmbus_evtflags *event_flags; /* shared event flags */
|
||||
|
||||
/* Rarely used fields */
|
||||
struct hyperv_dma message_dma; /* busdma glue */
|
||||
struct hyperv_dma event_flag_dma; /* busdma glue */
|
||||
struct hyperv_dma event_flags_dma;/* busdma glue */
|
||||
struct taskqueue *event_tq; /* event taskq */
|
||||
struct taskqueue *message_tq; /* message taskq */
|
||||
struct task message_task; /* message task */
|
||||
|
|
|
|||
Loading…
Reference in a new issue