mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
MFC 301017,301018,301019,301020,301021,301022,301106
301017 hyperv/vmbus: Indentation cleanup No functional changes. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6602 301018 hyperv/vmbus: Move global vmbus id array to stack. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6603 301019 hyperv/vmbus: Redefine SynIC message. - Avoid unnecessary indirection. - Avoid bit fields. - Use __packed. Reviewed by: Jun Su <junsu microsoft com> MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6636 301020 hyperv/vmbus: White space cleanup No functional changes MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6637 301021 hyperv: Move guid2str from vmbus file to hyperv file - Use uint8_t for GUID byte array. - Define GUID string length. - Break long lines. - Nuke unnecessary stack variable. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6640 301022 hyperv/kvp: Use if_xname. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6641 301106 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
b2e69e76fc
commit
14c9deb6f9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=302166
@ -121,10 +121,12 @@ typedef uint8_t hv_bool_uint8_t;
|
|||||||
HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
|
HV_ALIGN_DOWN(addr, PAGE_SIZE)) >> PAGE_SHIFT )
|
||||||
|
|
||||||
typedef struct hv_guid {
|
typedef struct hv_guid {
|
||||||
unsigned char data[16];
|
uint8_t data[16];
|
||||||
} __packed hv_guid;
|
} __packed hv_guid;
|
||||||
|
|
||||||
int snprintf_hv_guid(char *, size_t, const hv_guid *);
|
#define HYPERV_GUID_STRLEN 40
|
||||||
|
|
||||||
|
int hyperv_guid2str(const struct hv_guid *, char *, size_t);
|
||||||
|
|
||||||
#define HV_NIC_GUID \
|
#define HV_NIC_GUID \
|
||||||
.data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \
|
.data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \
|
||||||
|
@ -58,7 +58,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
|
#include <net/if_var.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/netvsc/hv_net_vsc.h>
|
#include <dev/hyperv/netvsc/hv_net_vsc.h>
|
||||||
@ -306,8 +309,7 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(struct hv_kvp_ip_msg *host_ip_msg,
|
|||||||
int UNUSED_FLAG = 1;
|
int UNUSED_FLAG = 1;
|
||||||
struct hv_device *hv_dev; /* GUID Data Structure */
|
struct hv_device *hv_dev; /* GUID Data Structure */
|
||||||
hn_softc_t *sc; /* hn softc structure */
|
hn_softc_t *sc; /* hn softc structure */
|
||||||
char if_name[4];
|
char buf[HYPERV_GUID_STRLEN];
|
||||||
char buf[39];
|
|
||||||
|
|
||||||
device_t *devs;
|
device_t *devs;
|
||||||
int devcnt;
|
int devcnt;
|
||||||
@ -335,11 +337,12 @@ hv_kvp_convert_utf16_ipinfo_to_utf8(struct hv_kvp_ip_msg *host_ip_msg,
|
|||||||
/* Trying to find GUID of Network Device */
|
/* Trying to find GUID of Network Device */
|
||||||
hv_dev = sc->hn_dev_obj;
|
hv_dev = sc->hn_dev_obj;
|
||||||
|
|
||||||
snprintf_hv_guid(buf, sizeof(buf), &hv_dev->device_id);
|
hyperv_guid2str(&hv_dev->device_id, buf, sizeof(buf));
|
||||||
sprintf(if_name, "%s%d", "hn", device_get_unit(devs[devcnt]));
|
|
||||||
|
|
||||||
if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id, 39) == 0) {
|
if (strncmp(buf, (char *)umsg->body.kvp_ip_val.adapter_id,
|
||||||
strcpy((char *)umsg->body.kvp_ip_val.adapter_id, if_name);
|
HYPERV_GUID_STRLEN - 1) == 0) {
|
||||||
|
strlcpy((char *)umsg->body.kvp_ip_val.adapter_id,
|
||||||
|
sc->hn_ifp->if_xname, MAX_ADAPTER_ID_SIZE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
||||||
|
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -720,8 +721,8 @@ hv_vmbus_release_unattached_channels(void)
|
|||||||
}
|
}
|
||||||
hv_vmbus_free_vmbus_channel(channel);
|
hv_vmbus_free_vmbus_channel(channel);
|
||||||
}
|
}
|
||||||
bzero(hv_vmbus_g_connection.channels,
|
bzero(hv_vmbus_g_connection.channels,
|
||||||
sizeof(hv_vmbus_channel*) * HV_CHANNEL_MAX_COUNT);
|
sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX);
|
||||||
mtx_unlock(&hv_vmbus_g_connection.channel_lock);
|
mtx_unlock(&hv_vmbus_g_connection.channel_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
||||||
|
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -212,8 +213,7 @@ hv_vmbus_connect(void)
|
|||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
M_DEVBUF, M_WAITOK | M_ZERO);
|
||||||
|
|
||||||
hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
|
hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
|
||||||
HV_CHANNEL_MAX_COUNT,
|
VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO);
|
||||||
M_DEVBUF, M_WAITOK | M_ZERO);
|
|
||||||
/*
|
/*
|
||||||
* Find the highest vmbus version number we can support.
|
* Find the highest vmbus version number we can support.
|
||||||
*/
|
*/
|
||||||
@ -295,20 +295,20 @@ hv_vmbus_disconnect(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static __inline 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;
|
int f;
|
||||||
|
|
||||||
for (f = 0; f < flag_cnt; ++f) {
|
for (f = 0; f < flag_cnt; ++f) {
|
||||||
uint32_t rel_id_base;
|
uint32_t rel_id_base;
|
||||||
unsigned long flags;
|
u_long flags;
|
||||||
int bit;
|
int bit;
|
||||||
|
|
||||||
if (event_flags[f] == 0)
|
if (event_flags[f] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
flags = atomic_swap_long(&event_flags[f], 0);
|
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) {
|
while ((bit = ffsl(flags)) != 0) {
|
||||||
struct hv_vmbus_channel *channel;
|
struct hv_vmbus_channel *channel;
|
||||||
@ -334,27 +334,27 @@ vmbus_event_flags_proc(unsigned long *event_flags, int flag_cnt)
|
|||||||
void
|
void
|
||||||
vmbus_event_proc(struct vmbus_softc *sc, int cpu)
|
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
|
* 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.
|
* to get the id of the channel that has the pending interrupt.
|
||||||
*/
|
*/
|
||||||
event = VMBUS_PCPU_GET(sc, event_flag, cpu) + VMBUS_SINT_MESSAGE;
|
eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
|
||||||
vmbus_event_flags_proc(event->flagsul,
|
vmbus_event_flags_proc(eventf->evt_flags,
|
||||||
VMBUS_PCPU_GET(sc, event_flag_cnt, cpu));
|
VMBUS_PCPU_GET(sc, event_flags_cnt, cpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
vmbus_event_proc_compat(struct vmbus_softc *sc __unused, int cpu)
|
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;
|
eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
|
||||||
if (atomic_testandclear_int(&event->flags32[0], 0)) {
|
if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) {
|
||||||
vmbus_event_flags_proc(
|
vmbus_event_flags_proc(
|
||||||
hv_vmbus_g_connection.recv_interrupt_page,
|
hv_vmbus_g_connection.recv_interrupt_page,
|
||||||
HV_MAX_NUM_CHANNELS_SUPPORTED >> HV_CHANNEL_ULONG_SHIFT);
|
VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,8 +417,8 @@ vmbus_on_channel_open(const struct hv_vmbus_channel *chan)
|
|||||||
volatile int *flag_cnt_ptr;
|
volatile int *flag_cnt_ptr;
|
||||||
int flag_cnt;
|
int flag_cnt;
|
||||||
|
|
||||||
flag_cnt = (chan->offer_msg.child_rel_id / HV_CHANNEL_ULONG_LEN) + 1;
|
flag_cnt = (chan->offer_msg.child_rel_id / VMBUS_EVTFLAG_LEN) + 1;
|
||||||
flag_cnt_ptr = VMBUS_PCPU_PTR(vmbus_get_softc(), event_flag_cnt,
|
flag_cnt_ptr = VMBUS_PCPU_PTR(vmbus_get_softc(), event_flags_cnt,
|
||||||
chan->target_cpu);
|
chan->target_cpu);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -202,6 +202,18 @@ hv_vmbus_signal_event(void *con_id)
|
|||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hyperv_guid2str(const struct hv_guid *guid, char *buf, size_t sz)
|
||||||
|
{
|
||||||
|
const uint8_t *d = guid->data;
|
||||||
|
|
||||||
|
return snprintf(buf, sz, "%02x%02x%02x%02x-"
|
||||||
|
"%02x%02x-%02x%02x-%02x%02x-"
|
||||||
|
"%02x%02x%02x%02x%02x%02x",
|
||||||
|
d[3], d[2], d[1], d[0],
|
||||||
|
d[5], d[4], d[7], d[6], d[8], d[9],
|
||||||
|
d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
hyperv_identify(void)
|
hyperv_identify(void)
|
||||||
|
@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
#include <dev/hyperv/vmbus/hv_vmbus_priv.h>
|
||||||
#include <dev/hyperv/vmbus/hyperv_reg.h>
|
#include <dev/hyperv/vmbus/hyperv_reg.h>
|
||||||
#include <dev/hyperv/vmbus/hyperv_var.h>
|
#include <dev/hyperv/vmbus/hyperv_var.h>
|
||||||
|
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||||
|
|
||||||
#include <contrib/dev/acpica/include/acpi.h>
|
#include <contrib/dev/acpica/include/acpi.h>
|
||||||
@ -70,15 +71,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
struct vmbus_softc *vmbus_sc;
|
struct vmbus_softc *vmbus_sc;
|
||||||
|
|
||||||
static char *vmbus_ids[] = { "VMBUS", NULL };
|
|
||||||
|
|
||||||
extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr);
|
extern inthand_t IDTVEC(rsvd), IDTVEC(vmbus_isr);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vmbus_msg_task(void *xsc, int pending __unused)
|
vmbus_msg_task(void *xsc, int pending __unused)
|
||||||
{
|
{
|
||||||
struct vmbus_softc *sc = xsc;
|
struct vmbus_softc *sc = xsc;
|
||||||
hv_vmbus_message *msg;
|
volatile struct vmbus_message *msg;
|
||||||
|
|
||||||
msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
|
msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -86,10 +85,12 @@ vmbus_msg_task(void *xsc, int pending __unused)
|
|||||||
hv_vmbus_channel_msg_header *hdr;
|
hv_vmbus_channel_msg_header *hdr;
|
||||||
hv_vmbus_channel_msg_type msg_type;
|
hv_vmbus_channel_msg_type msg_type;
|
||||||
|
|
||||||
if (msg->header.message_type == HV_MESSAGE_TYPE_NONE)
|
if (msg->msg_type == VMBUS_MSGTYPE_NONE)
|
||||||
break; /* no message */
|
break; /* no message */
|
||||||
|
|
||||||
hdr = (hv_vmbus_channel_msg_header *)msg->u.payload;
|
/* XXX: update messageHandler interface */
|
||||||
|
hdr = __DEVOLATILE(hv_vmbus_channel_msg_header *,
|
||||||
|
msg->msg_data);
|
||||||
msg_type = hdr->message_type;
|
msg_type = hdr->message_type;
|
||||||
|
|
||||||
if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) {
|
if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) {
|
||||||
@ -101,20 +102,20 @@ vmbus_msg_task(void *xsc, int pending __unused)
|
|||||||
if (entry->messageHandler)
|
if (entry->messageHandler)
|
||||||
entry->messageHandler(hdr);
|
entry->messageHandler(hdr);
|
||||||
handled:
|
handled:
|
||||||
msg->header.message_type = HV_MESSAGE_TYPE_NONE;
|
msg->msg_type = VMBUS_MSGTYPE_NONE;
|
||||||
/*
|
/*
|
||||||
* Make sure the write to message_type (ie set to
|
* Make sure the write to msg_type (i.e. set to
|
||||||
* HV_MESSAGE_TYPE_NONE) happens before we read the
|
* VMBUS_MSGTYPE_NONE) happens before we read the
|
||||||
* message_pending and EOMing. Otherwise, the EOMing will
|
* msg_flags and EOMing. Otherwise, the EOMing will
|
||||||
* not deliver any more messages
|
* not deliver any more messages since there is no
|
||||||
* since there is no empty slot
|
* empty slot
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* mb() is used here, since atomic_thread_fence_seq_cst()
|
* mb() is used here, since atomic_thread_fence_seq_cst()
|
||||||
* will become compiler fence on UP kernel.
|
* will become compiler fence on UP kernel.
|
||||||
*/
|
*/
|
||||||
mb();
|
mb();
|
||||||
if (msg->header.message_flags.u.message_pending) {
|
if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
|
||||||
/*
|
/*
|
||||||
* This will cause message queue rescan to possibly
|
* This will cause message queue rescan to possibly
|
||||||
* deliver another msg from the hypervisor
|
* deliver another msg from the hypervisor
|
||||||
@ -127,7 +128,8 @@ handled:
|
|||||||
static __inline int
|
static __inline int
|
||||||
vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
|
vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
|
||||||
{
|
{
|
||||||
hv_vmbus_message *msg, *msg_base;
|
volatile struct vmbus_message *msg;
|
||||||
|
struct vmbus_message *msg_base;
|
||||||
|
|
||||||
msg_base = VMBUS_PCPU_GET(sc, message, cpu);
|
msg_base = VMBUS_PCPU_GET(sc, message, cpu);
|
||||||
|
|
||||||
@ -137,25 +139,24 @@ vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
|
|||||||
* TODO: move this to independent IDT vector.
|
* TODO: move this to independent IDT vector.
|
||||||
*/
|
*/
|
||||||
msg = msg_base + VMBUS_SINT_TIMER;
|
msg = msg_base + VMBUS_SINT_TIMER;
|
||||||
if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {
|
if (msg->msg_type == VMBUS_MSGTYPE_TIMER_EXPIRED) {
|
||||||
msg->header.message_type = HV_MESSAGE_TYPE_NONE;
|
msg->msg_type = VMBUS_MSGTYPE_NONE;
|
||||||
|
|
||||||
vmbus_et_intr(frame);
|
vmbus_et_intr(frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the write to message_type (ie set to
|
* Make sure the write to msg_type (i.e. set to
|
||||||
* HV_MESSAGE_TYPE_NONE) happens before we read the
|
* VMBUS_MSGTYPE_NONE) happens before we read the
|
||||||
* message_pending and EOMing. Otherwise, the EOMing will
|
* msg_flags and EOMing. Otherwise, the EOMing will
|
||||||
* not deliver any more messages
|
* not deliver any more messages since there is no
|
||||||
* since there is no empty slot
|
* empty slot
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* mb() is used here, since atomic_thread_fence_seq_cst()
|
* mb() is used here, since atomic_thread_fence_seq_cst()
|
||||||
* will become compiler fence on UP kernel.
|
* will become compiler fence on UP kernel.
|
||||||
*/
|
*/
|
||||||
mb();
|
mb();
|
||||||
|
if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
|
||||||
if (msg->header.message_flags.u.message_pending) {
|
|
||||||
/*
|
/*
|
||||||
* This will cause message queue rescan to possibly
|
* This will cause message queue rescan to possibly
|
||||||
* deliver another msg from the hypervisor
|
* deliver another msg from the hypervisor
|
||||||
@ -177,7 +178,7 @@ vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
|
|||||||
* Check messages. Mainly management stuffs; ultra low rate.
|
* Check messages. Mainly management stuffs; ultra low rate.
|
||||||
*/
|
*/
|
||||||
msg = msg_base + VMBUS_SINT_MESSAGE;
|
msg = msg_base + VMBUS_SINT_MESSAGE;
|
||||||
if (__predict_false(msg->header.message_type != HV_MESSAGE_TYPE_NONE)) {
|
if (__predict_false(msg->msg_type != VMBUS_MSGTYPE_NONE)) {
|
||||||
taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
|
taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
|
||||||
VMBUS_PCPU_PTR(sc, message_task, cpu));
|
VMBUS_PCPU_PTR(sc, message_task, cpu));
|
||||||
}
|
}
|
||||||
@ -247,8 +248,8 @@ vmbus_synic_setup(void *xsc)
|
|||||||
*/
|
*/
|
||||||
orig = rdmsr(MSR_HV_SIEFP);
|
orig = rdmsr(MSR_HV_SIEFP);
|
||||||
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
|
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
|
||||||
((VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
|
((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
|
||||||
MSR_HV_SIEFP_PGSHIFT);
|
>> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
|
||||||
wrmsr(MSR_HV_SIEFP, val);
|
wrmsr(MSR_HV_SIEFP, val);
|
||||||
|
|
||||||
|
|
||||||
@ -338,11 +339,11 @@ vmbus_dma_alloc(struct vmbus_softc *sc)
|
|||||||
|
|
||||||
ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
|
ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
|
||||||
PAGE_SIZE, 0, PAGE_SIZE,
|
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);
|
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
VMBUS_PCPU_GET(sc, event_flag, cpu) = ptr;
|
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -359,11 +360,11 @@ vmbus_dma_free(struct vmbus_softc *sc)
|
|||||||
VMBUS_PCPU_GET(sc, message, cpu));
|
VMBUS_PCPU_GET(sc, message, cpu));
|
||||||
VMBUS_PCPU_GET(sc, message, cpu) = NULL;
|
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(
|
hyperv_dmamem_free(
|
||||||
VMBUS_PCPU_PTR(sc, event_flag_dma, cpu),
|
VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
|
||||||
VMBUS_PCPU_GET(sc, event_flag, cpu));
|
VMBUS_PCPU_GET(sc, event_flags, cpu));
|
||||||
VMBUS_PCPU_GET(sc, event_flag, cpu) = NULL;
|
VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,16 +535,19 @@ vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
|
|||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case HV_VMBUS_IVAR_TYPE:
|
case HV_VMBUS_IVAR_TYPE:
|
||||||
*result = (uintptr_t) &child_dev_ctx->class_id;
|
*result = (uintptr_t)&child_dev_ctx->class_id;
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case HV_VMBUS_IVAR_INSTANCE:
|
case HV_VMBUS_IVAR_INSTANCE:
|
||||||
*result = (uintptr_t) &child_dev_ctx->device_id;
|
*result = (uintptr_t)&child_dev_ctx->device_id;
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case HV_VMBUS_IVAR_DEVCTX:
|
case HV_VMBUS_IVAR_DEVCTX:
|
||||||
*result = (uintptr_t) child_dev_ctx;
|
*result = (uintptr_t)child_dev_ctx;
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
case HV_VMBUS_IVAR_NODE:
|
case HV_VMBUS_IVAR_NODE:
|
||||||
*result = (uintptr_t) child_dev_ctx->device;
|
*result = (uintptr_t)child_dev_ctx->device;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
@ -566,18 +570,18 @@ vmbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
|
|||||||
static int
|
static int
|
||||||
vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
|
vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
char guidbuf[40];
|
|
||||||
struct hv_device *dev_ctx = device_get_ivars(child);
|
struct hv_device *dev_ctx = device_get_ivars(child);
|
||||||
|
char guidbuf[HYPERV_GUID_STRLEN];
|
||||||
|
|
||||||
if (dev_ctx == NULL)
|
if (dev_ctx == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
strlcat(buf, "classid=", buflen);
|
strlcat(buf, "classid=", buflen);
|
||||||
snprintf_hv_guid(guidbuf, sizeof(guidbuf), &dev_ctx->class_id);
|
hyperv_guid2str(&dev_ctx->class_id, guidbuf, sizeof(guidbuf));
|
||||||
strlcat(buf, guidbuf, buflen);
|
strlcat(buf, guidbuf, buflen);
|
||||||
|
|
||||||
strlcat(buf, " deviceid=", buflen);
|
strlcat(buf, " deviceid=", buflen);
|
||||||
snprintf_hv_guid(guidbuf, sizeof(guidbuf), &dev_ctx->device_id);
|
hyperv_guid2str(&dev_ctx->device_id, guidbuf, sizeof(guidbuf));
|
||||||
strlcat(buf, guidbuf, buflen);
|
strlcat(buf, guidbuf, buflen);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -601,31 +605,20 @@ hv_vmbus_child_device_create(hv_guid type, hv_guid instance,
|
|||||||
return (child_dev);
|
return (child_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
snprintf_hv_guid(char *buf, size_t sz, const hv_guid *guid)
|
|
||||||
{
|
|
||||||
int cnt;
|
|
||||||
const unsigned char *d = guid->data;
|
|
||||||
|
|
||||||
cnt = snprintf(buf, sz,
|
|
||||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
|
||||||
d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6],
|
|
||||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
|
||||||
return (cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hv_vmbus_child_device_register(struct hv_device *child_dev)
|
hv_vmbus_child_device_register(struct hv_device *child_dev)
|
||||||
{
|
{
|
||||||
device_t child;
|
device_t child, parent;
|
||||||
|
|
||||||
|
parent = vmbus_get_device();
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
char name[40];
|
char name[HYPERV_GUID_STRLEN];
|
||||||
snprintf_hv_guid(name, sizeof(name), &child_dev->class_id);
|
|
||||||
printf("VMBUS: Class ID: %s\n", name);
|
hyperv_guid2str(&child_dev->class_id, name, sizeof(name));
|
||||||
|
device_printf(parent, "add device, classid: %s\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
child = device_add_child(vmbus_get_device(), NULL, -1);
|
child = device_add_child(parent, NULL, -1);
|
||||||
child_dev->device = child;
|
child_dev->device = child;
|
||||||
device_set_ivars(child, child_dev);
|
device_set_ivars(child, child_dev);
|
||||||
|
|
||||||
@ -649,7 +642,9 @@ hv_vmbus_child_device_unregister(struct hv_device *child_dev)
|
|||||||
static int
|
static int
|
||||||
vmbus_probe(device_t dev)
|
vmbus_probe(device_t dev)
|
||||||
{
|
{
|
||||||
if (ACPI_ID_PROBE(device_get_parent(dev), dev, vmbus_ids) == NULL ||
|
char *id[] = { "VMBUS", NULL };
|
||||||
|
|
||||||
|
if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL ||
|
||||||
device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
|
device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
|
||||||
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
|
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
@ -50,28 +50,6 @@ typedef uint16_t hv_vmbus_status;
|
|||||||
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
|
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
|
||||||
#define HV_ANY_VP (0xFFFFFFFF)
|
#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
|
* MessageId: HV_STATUS_INSUFFICIENT_BUFFERS
|
||||||
* MessageText:
|
* MessageText:
|
||||||
@ -195,9 +173,6 @@ enum {
|
|||||||
|
|
||||||
#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t)
|
#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t)
|
||||||
|
|
||||||
struct vmbus_message;
|
|
||||||
union vmbus_event_flags;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define hypervisor message types
|
* Define hypervisor message types
|
||||||
*/
|
*/
|
||||||
@ -251,58 +226,8 @@ typedef union _hv_vmbus_port_id {
|
|||||||
} u ;
|
} u ;
|
||||||
} hv_vmbus_port_id;
|
} hv_vmbus_port_id;
|
||||||
|
|
||||||
/*
|
|
||||||
* Define synthetic interrupt controller message flag
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
uint8_t as_uint8_t;
|
|
||||||
struct {
|
|
||||||
uint8_t message_pending:1;
|
|
||||||
uint8_t reserved:7;
|
|
||||||
} u;
|
|
||||||
} hv_vmbus_msg_flags;
|
|
||||||
|
|
||||||
typedef uint64_t hv_vmbus_partition_id;
|
typedef uint64_t hv_vmbus_partition_id;
|
||||||
|
|
||||||
/*
|
|
||||||
* Define synthetic interrupt controller message header
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
hv_vmbus_msg_type message_type;
|
|
||||||
uint8_t payload_size;
|
|
||||||
hv_vmbus_msg_flags message_flags;
|
|
||||||
uint8_t reserved[2];
|
|
||||||
union {
|
|
||||||
hv_vmbus_partition_id sender;
|
|
||||||
hv_vmbus_port_id port;
|
|
||||||
} u;
|
|
||||||
} hv_vmbus_msg_header;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define synthetic interrupt controller message format
|
|
||||||
*/
|
|
||||||
typedef struct vmbus_message {
|
|
||||||
hv_vmbus_msg_header header;
|
|
||||||
union {
|
|
||||||
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
|
||||||
} u ;
|
|
||||||
} hv_vmbus_message;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
* VM Bus connection states
|
||||||
*/
|
*/
|
||||||
@ -425,16 +350,6 @@ typedef struct {
|
|||||||
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
||||||
} hv_vmbus_input_post_message;
|
} 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
|
* Declare the various hypercall operations
|
||||||
*/
|
*/
|
||||||
|
@ -35,15 +35,15 @@
|
|||||||
* This is the Hyper-V vmbus channel direct callback interrupt.
|
* This is the Hyper-V vmbus channel direct callback interrupt.
|
||||||
* Only used when it is running on Hyper-V.
|
* Only used when it is running on Hyper-V.
|
||||||
*/
|
*/
|
||||||
.text
|
.text
|
||||||
SUPERALIGN_TEXT
|
SUPERALIGN_TEXT
|
||||||
IDTVEC(vmbus_isr)
|
IDTVEC(vmbus_isr)
|
||||||
PUSH_FRAME
|
PUSH_FRAME
|
||||||
SET_KERNEL_SREGS
|
SET_KERNEL_SREGS
|
||||||
cld
|
cld
|
||||||
FAKE_MCOUNT(TF_EIP(%esp))
|
FAKE_MCOUNT(TF_EIP(%esp))
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call vmbus_handle_intr
|
call vmbus_handle_intr
|
||||||
add $4, %esp
|
add $4, %esp
|
||||||
MEXITCOUNT
|
MEXITCOUNT
|
||||||
jmp doreti
|
jmp doreti
|
||||||
|
82
sys/dev/hyperv/vmbus/vmbus_reg.h
Normal file
82
sys/dev/hyperv/vmbus/vmbus_reg.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2016 Microsoft Corp.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice unmodified, this list of conditions, and the following
|
||||||
|
* disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VMBUS_REG_H_
|
||||||
|
#define _VMBUS_REG_H_
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hyper-V SynIC message format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VMBUS_MSG_DSIZE_MAX 240
|
||||||
|
#define VMBUS_MSG_SIZE 256
|
||||||
|
|
||||||
|
struct vmbus_message {
|
||||||
|
uint32_t msg_type; /* VMBUS_MSGTYPE_ */
|
||||||
|
uint8_t msg_dsize; /* data size */
|
||||||
|
uint8_t msg_flags; /* VMBUS_MSGFLAG_ */
|
||||||
|
uint16_t msg_rsvd;
|
||||||
|
uint64_t msg_id;
|
||||||
|
uint8_t msg_data[VMBUS_MSG_DSIZE_MAX];
|
||||||
|
} __packed;
|
||||||
|
CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
|
||||||
|
|
||||||
|
#define VMBUS_MSGTYPE_NONE 0
|
||||||
|
#define VMBUS_MSGTYPE_TIMER_EXPIRED 0x80000010
|
||||||
|
|
||||||
|
#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_ */
|
@ -49,12 +49,12 @@ struct vmbus_pcpu_data {
|
|||||||
u_long *intr_cnt; /* Hyper-V interrupt counter */
|
u_long *intr_cnt; /* Hyper-V interrupt counter */
|
||||||
struct vmbus_message *message; /* shared messages */
|
struct vmbus_message *message; /* shared messages */
|
||||||
uint32_t vcpuid; /* virtual cpuid */
|
uint32_t vcpuid; /* virtual cpuid */
|
||||||
int event_flag_cnt; /* # of event flags */
|
int event_flags_cnt;/* # of event flags */
|
||||||
union vmbus_event_flags *event_flag; /* shared event flags */
|
struct vmbus_evtflags *event_flags; /* shared event flags */
|
||||||
|
|
||||||
/* Rarely used fields */
|
/* Rarely used fields */
|
||||||
struct hyperv_dma message_dma; /* busdma glue */
|
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 *event_tq; /* event taskq */
|
||||||
struct taskqueue *message_tq; /* message taskq */
|
struct taskqueue *message_tq; /* message taskq */
|
||||||
struct task message_task; /* message task */
|
struct task message_task; /* message task */
|
||||||
|
Loading…
Reference in New Issue
Block a user