diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-08-16 14:43:32 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-08-16 14:43:32 +0000 |
commit | b3c36897c44bba6a2418bd115a42fa25e2030371 (patch) | |
tree | 8e56d5e84df97037c89a1d3f75a47dc212f872da /sys/dev | |
parent | d4f4ea3e8fb8bcb95faf351707604f8c0d1c23a5 (diff) |
Update Hyper-V structure definitions to the 2016 version
Microsoft has performed a significant clean up and stylistic improvement
of Hyper-V structure definitions and updated FreeBSD port. We update to
stay in sync with the upstream and improve maintainability of this code
in the future.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pv/hyperv.c | 471 | ||||
-rw-r--r-- | sys/dev/pv/hypervreg.h | 1001 | ||||
-rw-r--r-- | sys/dev/pv/hypervvar.h | 19 | ||||
-rw-r--r-- | sys/dev/pv/if_hvn.c | 47 |
4 files changed, 771 insertions, 767 deletions
diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c index b6e5c55abcd..be9bc9747f2 100644 --- a/sys/dev/pv/hyperv.c +++ b/sys/dev/pv/hyperv.c @@ -94,9 +94,9 @@ void hv_intr(void); void hv_event_intr(struct hv_softc *); void hv_message_intr(struct hv_softc *); int hv_vmbus_connect(struct hv_softc *); -void hv_channel_response(struct hv_softc *, struct hv_channel_msg_header *); -void hv_channel_offer(struct hv_softc *, struct hv_channel_msg_header *); -void hv_channel_delivered(struct hv_softc *, struct hv_channel_msg_header *); +void hv_channel_response(struct hv_softc *, struct vmbus_chanmsg_hdr *); +void hv_channel_offer(struct hv_softc *, struct vmbus_chanmsg_hdr *); +void hv_channel_delivered(struct hv_softc *, struct vmbus_chanmsg_hdr *); int hv_channel_scan(struct hv_softc *); void hv_process_offer(struct hv_softc *, struct hv_offer *); struct hv_channel * @@ -118,31 +118,31 @@ struct { int hmd_response; int hmd_request; void (*hmd_handler)(struct hv_softc *, - struct hv_channel_msg_header *); + struct vmbus_chanmsg_hdr *); } hv_msg_dispatch[] = { - { HV_CHANMSG_INVALID, 0, NULL }, - { HV_CHANMSG_OFFER_CHANNEL, 0, hv_channel_offer }, - { HV_CHANMSG_RESCIND_CHANNEL_OFFER, 0, NULL }, - { HV_CHANMSG_REQUEST_OFFERS, HV_CHANMSG_OFFER_CHANNEL, + { 0, 0, NULL }, + { VMBUS_CHANMSG_CHOFFER, 0, hv_channel_offer }, + { VMBUS_CHANMSG_CHRESCIND, 0, NULL }, + { VMBUS_CHANMSG_CHREQUEST, VMBUS_CHANMSG_CHOFFER, NULL }, - { HV_CHANMSG_ALL_OFFERS_DELIVERED, 0, + { VMBUS_CHANMSG_CHOFFER_DONE, 0, hv_channel_delivered }, - { HV_CHANMSG_OPEN_CHANNEL, 0, NULL }, - { HV_CHANMSG_OPEN_CHANNEL_RESULT, HV_CHANMSG_OPEN_CHANNEL, + { VMBUS_CHANMSG_CHOPEN, 0, NULL }, + { VMBUS_CHANMSG_CHOPEN_RESP, VMBUS_CHANMSG_CHOPEN, hv_channel_response }, - { HV_CHANMSG_CLOSE_CHANNEL, 0, NULL }, - { HV_CHANMSG_GPADL_HEADER, 0, NULL }, - { HV_CHANMSG_GPADL_BODY, 0, NULL }, - { HV_CHANMSG_GPADL_CREATED, HV_CHANMSG_GPADL_HEADER, + { VMBUS_CHANMSG_CHCLOSE, 0, NULL }, + { VMBUS_CHANMSG_GPADL_CONN, 0, NULL }, + { VMBUS_CHANMSG_GPADL_SUBCONN, 0, NULL }, + { VMBUS_CHANMSG_GPADL_CONNRESP, VMBUS_CHANMSG_GPADL_CONN, hv_channel_response }, - { HV_CHANMSG_GPADL_TEARDOWN, 0, NULL }, - { HV_CHANMSG_GPADL_TORNDOWN, HV_CHANMSG_GPADL_TEARDOWN, + { VMBUS_CHANMSG_GPADL_DISCONN, 0, NULL }, + { VMBUS_CHANMSG_GPADL_DISCONNRESP, VMBUS_CHANMSG_GPADL_DISCONN, hv_channel_response }, - { HV_CHANMSG_REL_ID_RELEASED, 0, NULL }, - { HV_CHANMSG_INITIATED_CONTACT, 0, NULL }, - { HV_CHANMSG_VERSION_RESPONSE, HV_CHANMSG_INITIATED_CONTACT, + { VMBUS_CHANMSG_CHFREE, 0, NULL }, + { VMBUS_CHANMSG_CONNECT, 0, NULL }, + { VMBUS_CHANMSG_CONNECT_RESP, VMBUS_CHANMSG_CONNECT, hv_channel_response }, - { HV_CHANMSG_UNLOAD, 0, NULL }, + { VMBUS_CHANMSG_DISCONNECT, 0, NULL }, }; struct timecounter hv_timecounter = { @@ -222,13 +222,13 @@ hv_fake_version(struct hv_softc *sc) /* FreeBSD 10 apparently */ ver = 0x8200ULL << 48; ver |= 10 << 16; - wrmsr(HV_X64_MSR_GUEST_OS_ID, ver); + wrmsr(MSR_HV_GUEST_OS_ID, ver); } u_int hv_gettime(struct timecounter *tc) { - u_int now = rdmsr(HV_X64_MSR_TIME_REF_COUNT); + u_int now = rdmsr(MSR_HV_TIME_REF_COUNT); return (now); } @@ -247,11 +247,10 @@ hv_init_hypercall(struct hv_softc *sc) return (-1); } - msr = (atop(pa) << HV_X64_MSR_HYPERCALL_PASHIFT) | - HV_X64_MSR_HYPERCALL_ENABLED; - wrmsr(HV_X64_MSR_HYPERCALL, msr); + msr = (atop(pa) << MSR_HV_HYPERCALL_PGSHIFT) | MSR_HV_HYPERCALL_ENABLE; + wrmsr(MSR_HV_HYPERCALL, msr); - if (!(rdmsr(HV_X64_MSR_HYPERCALL) & HV_X64_MSR_HYPERCALL_ENABLED)) { + if (!(rdmsr(MSR_HV_HYPERCALL) & MSR_HV_HYPERCALL_ENABLE)) { printf(": failed to set up a hypercall page\n"); return (-1); } @@ -270,14 +269,14 @@ hv_hypercall(struct hv_softc *sc, uint64_t control, void *input, pmap_extract(pmap_kernel(), (vaddr_t)input, &input_pa) == 0) { printf("%s: hypercall input PA extraction failed\n", sc->sc_dev.dv_xname); - return (~HV_STATUS_SUCCESS); + return (~HYPERCALL_STATUS_SUCCESS); } if (output != NULL && pmap_extract(pmap_kernel(), (vaddr_t)output, &output_pa) == 0) { printf("%s: hypercall output PA extraction failed\n", sc->sc_dev.dv_xname); - return (~HV_STATUS_SUCCESS); + return (~HYPERCALL_STATUS_SUCCESS); } #ifdef __amd64__ @@ -331,7 +330,7 @@ hv_init_interrupts(struct hv_softc *sc) return (-1); } - sc->sc_proto = HV_VMBUS_VERSION_WS2008; + sc->sc_proto = VMBUS_VERSION_WS2008; return (hv_init_synic(sc)); } @@ -341,11 +340,9 @@ hv_init_synic(struct hv_softc *sc) { struct cpu_info *ci = curcpu(); int cpu = CPU_INFO_UNIT(ci); - uint64_t simp, siefp, sctrl, sint, version; + uint64_t simp, siefp, sctrl, sint; paddr_t pa; - version = rdmsr(HV_X64_MSR_SVERSION); - /* * Setup the Synic's message page */ @@ -353,11 +350,11 @@ hv_init_synic(struct hv_softc *sc) printf(": SIMP PA extraction failed\n"); return (-1); } - simp = rdmsr(HV_X64_MSR_SIMP); - simp &= (1 << HV_X64_MSR_SIMP_PASHIFT) - 1; - simp |= (atop(pa) << HV_X64_MSR_SIMP_PASHIFT); - simp |= HV_X64_MSR_SIMP_ENABLED; - wrmsr(HV_X64_MSR_SIMP, simp); + simp = rdmsr(MSR_HV_SIMP); + simp &= (1 << MSR_HV_SIMP_PGSHIFT) - 1; + simp |= (atop(pa) << MSR_HV_SIMP_PGSHIFT); + simp |= MSR_HV_SIMP_ENABLE; + wrmsr(MSR_HV_SIMP, simp); /* * Setup the Synic's event page @@ -366,22 +363,26 @@ hv_init_synic(struct hv_softc *sc) printf(": SIEP PA extraction failed\n"); return (-1); } - siefp = rdmsr(HV_X64_MSR_SIEFP); - siefp &= (1<<HV_X64_MSR_SIEFP_PASHIFT) - 1; - siefp |= (atop(pa) << HV_X64_MSR_SIEFP_PASHIFT); - siefp |= HV_X64_MSR_SIEFP_ENABLED; - wrmsr(HV_X64_MSR_SIEFP, siefp); + siefp = rdmsr(MSR_HV_SIEFP); + siefp &= (1<<MSR_HV_SIEFP_PGSHIFT) - 1; + siefp |= (atop(pa) << MSR_HV_SIEFP_PGSHIFT); + siefp |= MSR_HV_SIEFP_ENABLE; + wrmsr(MSR_HV_SIEFP, siefp); - /* HV_SHARED_SINT_IDT_VECTOR + 0x20 */ - sint = sc->sc_idtvec | HV_X64_MSR_SINT_AUTOEOI; - wrmsr(HV_X64_MSR_SINT0 + HV_MESSAGE_SINT, sint); + /* + * Configure and unmask SINT for message and event flags + */ + sint = rdmsr(MSR_HV_SINT0 + VMBUS_SINT_MESSAGE); + sint = sc->sc_idtvec | MSR_HV_SINT_AUTOEOI | + (sint & MSR_HV_SINT_RSVD_MASK); + wrmsr(MSR_HV_SINT0 + VMBUS_SINT_MESSAGE, sint); /* Enable the global synic bit */ - sctrl = rdmsr(HV_X64_MSR_SCONTROL); - sctrl |= HV_X64_MSR_SCONTROL_ENABLED; - wrmsr(HV_X64_MSR_SCONTROL, sctrl); + sctrl = rdmsr(MSR_HV_SCONTROL); + sctrl |= MSR_HV_SCTRL_ENABLE; + wrmsr(MSR_HV_SCONTROL, sctrl); - sc->sc_vcpus[cpu] = rdmsr(HV_X64_MSR_VP_INDEX); + sc->sc_vcpus[cpu] = rdmsr(MSR_HV_VP_INDEX); DPRINTF("vcpu%u: SIMP %#llx SIEFP %#llx SCTRL %#llx\n", sc->sc_vcpus[cpu], simp, siefp, sctrl); @@ -396,7 +397,7 @@ hv_cmd(struct hv_softc *sc, void *cmd, size_t cmdlen, void *rsp, struct hv_msg msg; int rv; - if (cmdlen > HV_MESSAGE_PAYLOAD) { + if (cmdlen > VMBUS_MSG_DSIZE_MAX) { printf("%s: payload too large (%lu)\n", sc->sc_dev.dv_xname, cmdlen); return (EMSGSIZE); @@ -404,8 +405,8 @@ hv_cmd(struct hv_softc *sc, void *cmd, size_t cmdlen, void *rsp, memset(&msg, 0, sizeof(msg)); - msg.msg_req.payload_size = cmdlen; - memcpy(msg.msg_req.payload, cmd, cmdlen); + msg.msg_req.hc_dsize = cmdlen; + memcpy(msg.msg_req.hc_data, cmd, cmdlen); if (!(flags & HCF_NOREPLY)) { msg.msg_rsp = rsp; @@ -429,8 +430,8 @@ hv_start(struct hv_softc *sc, struct hv_msg *msg) uint16_t status; int i, s; - msg->msg_req.connection_id = HV_MESSAGE_CONNECTION_ID; - msg->msg_req.message_type = 1; + msg->msg_req.hc_connid = VMBUS_CONNID_MESSAGE; + msg->msg_req.hc_msgtype = 1; if (!(msg->msg_flags & MSGF_NOQUEUE)) { mtx_enter(&sc->sc_reqlck); @@ -439,9 +440,9 @@ hv_start(struct hv_softc *sc, struct hv_msg *msg) } for (i = 0; i < nitems(delays); i++) { - status = hv_hypercall(sc, HV_CALL_POST_MESSAGE, + status = hv_hypercall(sc, HYPERCALL_POST_MESSAGE, &msg->msg_req, NULL); - if (status != HV_STATUS_INSUFFICIENT_BUFFERS) + if (status == HYPERCALL_STATUS_SUCCESS) break; if (msg->msg_flags & MSGF_NOSLEEP) { delay(delays[i]); @@ -513,7 +514,7 @@ hv_intr_signal(struct hv_softc *sc, void *con) { uint64_t status; - status = hv_hypercall(sc, HV_CALL_SIGNAL_EVENT, con, NULL); + status = hv_hypercall(sc, HYPERCALL_SIGNAL_EVENT, con, NULL); return ((uint16_t)status); } @@ -529,31 +530,32 @@ hv_intr(void) void hv_event_intr(struct hv_softc *sc) { - struct hv_synic_event_flags *evt; + struct vmbus_evtflags *evt; struct cpu_info *ci = curcpu(); int cpu = CPU_INFO_UNIT(ci); - int bit, dword, maxdword, relid; + int bit, dword, maxdword, chanid; struct hv_channel *ch; uint32_t *revents, pending; - evt = (struct hv_synic_event_flags *)sc->sc_siep[cpu] + HV_MESSAGE_SINT; - if ((sc->sc_proto == HV_VMBUS_VERSION_WS2008) || - (sc->sc_proto == HV_VMBUS_VERSION_WIN7)) { - if (atomic_clearbit_ptr(&evt->flags[0], 0) == 0) + evt = (struct vmbus_evtflags *)sc->sc_siep[cpu] + + VMBUS_SINT_MESSAGE; + if ((sc->sc_proto == VMBUS_VERSION_WS2008) || + (sc->sc_proto == VMBUS_VERSION_WIN7)) { + if (atomic_clearbit_ptr(&evt->evt_flags[0], 0) == 0) return; - maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5; + maxdword = VMBUS_CHAN_MAX_COMPAT >> 5; /* * receive size is 1/2 page and divide that by 4 bytes */ revents = sc->sc_revents; } else { - maxdword = nitems(evt->flags); + maxdword = nitems(evt->evt_flags); /* * 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. */ - revents = &evt->flags[0]; + revents = &evt->evt_flags[0]; } for (dword = 0; dword < maxdword; dword++) { @@ -563,19 +565,19 @@ hv_event_intr(struct hv_softc *sc) for (bit = 0; pending > 0; pending >>= 1, bit++) { if ((pending & 1) == 0) continue; - relid = (dword << 5) + bit; + chanid = (dword << 5) + bit; /* vmbus channel protocol message */ - if (relid == 0) + if (chanid == 0) continue; - ch = hv_channel_lookup(sc, relid); + ch = hv_channel_lookup(sc, chanid); if (ch == NULL) { printf("%s: unhandled event on %d\n", - sc->sc_dev.dv_xname, relid); + sc->sc_dev.dv_xname, chanid); continue; } if (ch->ch_state != HV_CHANSTATE_OPENED) { printf("%s: channel %d is not active\n", - sc->sc_dev.dv_xname, relid); + sc->sc_dev.dv_xname, chanid); continue; } ch->ch_evcnt.ec_count++; @@ -588,49 +590,49 @@ hv_event_intr(struct hv_softc *sc) void hv_message_intr(struct hv_softc *sc) { - struct hv_vmbus_message *msg; - struct hv_channel_msg_header *hdr; + struct vmbus_message *msg; + struct vmbus_chanmsg_hdr *hdr; struct cpu_info *ci = curcpu(); int cpu = CPU_INFO_UNIT(ci); for (;;) { - msg = (struct hv_vmbus_message *)sc->sc_simp[cpu] + - HV_MESSAGE_SINT; - if (msg->header.message_type == HV_MESSAGE_TYPE_NONE) + msg = (struct vmbus_message *)sc->sc_simp[cpu] + + VMBUS_SINT_MESSAGE; + if (msg->msg_type == VMBUS_MSGTYPE_NONE) break; - hdr = (struct hv_channel_msg_header *)msg->payload; - if (hdr->message_type >= HV_CHANMSG_COUNT) { + hdr = (struct vmbus_chanmsg_hdr *)msg->msg_data; + if (hdr->chm_type >= VMBUS_CHANMSG_COUNT) { printf("%s: unhandled message type %u flags %#x\n", - sc->sc_dev.dv_xname, hdr->message_type, - msg->header.message_flags); + sc->sc_dev.dv_xname, hdr->chm_type, + msg->msg_flags); goto skip; } - if (hv_msg_dispatch[hdr->message_type].hmd_handler) - hv_msg_dispatch[hdr->message_type].hmd_handler(sc, hdr); + if (hv_msg_dispatch[hdr->chm_type].hmd_handler) + hv_msg_dispatch[hdr->chm_type].hmd_handler(sc, hdr); else printf("%s: unhandled message type %u\n", - sc->sc_dev.dv_xname, hdr->message_type); + sc->sc_dev.dv_xname, hdr->chm_type); skip: - msg->header.message_type = HV_MESSAGE_TYPE_NONE; + msg->msg_type = VMBUS_MSGTYPE_NONE; membar_sync(); - if (msg->header.message_flags & HV_SYNIC_MHF_PENDING) - wrmsr(HV_X64_MSR_EOM, 0); + if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) + wrmsr(MSR_HV_EOM, 0); } } void -hv_channel_response(struct hv_softc *sc, struct hv_channel_msg_header *rsphdr) +hv_channel_response(struct hv_softc *sc, struct vmbus_chanmsg_hdr *rsphdr) { struct hv_msg *msg, *tmp; - struct hv_channel_msg_header *reqhdr; + struct vmbus_chanmsg_hdr *reqhdr; int req; - req = hv_msg_dispatch[rsphdr->message_type].hmd_request; + req = hv_msg_dispatch[rsphdr->chm_type].hmd_request; mtx_enter(&sc->sc_reqlck); TAILQ_FOREACH_SAFE(msg, &sc->sc_reqs, msg_entry, tmp) { - reqhdr = (struct hv_channel_msg_header *)&msg->msg_req.payload; - if (reqhdr->message_type == req) { + reqhdr = (struct vmbus_chanmsg_hdr *)&msg->msg_req.hc_data; + if (reqhdr->chm_type == req) { TAILQ_REMOVE(&sc->sc_reqs, msg, msg_entry); break; } @@ -646,7 +648,7 @@ hv_channel_response(struct hv_softc *sc, struct hv_channel_msg_header *rsphdr) } void -hv_channel_offer(struct hv_softc *sc, struct hv_channel_msg_header *hdr) +hv_channel_offer(struct hv_softc *sc, struct vmbus_chanmsg_hdr *hdr) { struct hv_offer *co; @@ -665,7 +667,7 @@ hv_channel_offer(struct hv_softc *sc, struct hv_channel_msg_header *hdr) } void -hv_channel_delivered(struct hv_softc *sc, struct hv_channel_msg_header *hdr) +hv_channel_delivered(struct hv_softc *sc, struct vmbus_chanmsg_hdr *hdr) { atomic_setbits_int(&sc->sc_flags, HSF_OFFERS_DELIVERED); wakeup(hdr); @@ -674,12 +676,12 @@ hv_channel_delivered(struct hv_softc *sc, struct hv_channel_msg_header *hdr) int hv_vmbus_connect(struct hv_softc *sc) { - const uint32_t versions[] = { HV_VMBUS_VERSION_WIN8_1, - HV_VMBUS_VERSION_WIN8, HV_VMBUS_VERSION_WIN7, - HV_VMBUS_VERSION_WS2008, HV_VMBUS_VERSION_INVALID + const uint32_t versions[] = { + VMBUS_VERSION_WIN8_1, VMBUS_VERSION_WIN8, + VMBUS_VERSION_WIN7, VMBUS_VERSION_WS2008 }; - struct hv_channel_initiate_contact cmd; - struct hv_channel_version_response rsp; + struct vmbus_chanmsg_connect cmd; + struct vmbus_chanmsg_connect_resp rsp; paddr_t epa, mpa1, mpa2; int i; @@ -718,22 +720,22 @@ hv_vmbus_connect(struct hv_softc *sc) } memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.message_type = HV_CHANMSG_INITIATED_CONTACT; - cmd.interrupt_page = (uint64_t)epa; - cmd.monitor_page_1 = (uint64_t)mpa1; - cmd.monitor_page_2 = (uint64_t)mpa2; + cmd.chm_hdr.chm_type = VMBUS_CHANMSG_CONNECT; + cmd.chm_evtflags = (uint64_t)epa; + cmd.chm_mnf1 = (uint64_t)mpa1; + cmd.chm_mnf2 = (uint64_t)mpa2; memset(&rsp, 0, sizeof(rsp)); - for (i = 0; versions[i] != HV_VMBUS_VERSION_INVALID; i++) { - cmd.vmbus_version_requested = versions[i]; + for (i = 0; i < nitems(versions); i++) { + cmd.chm_ver = versions[i]; if (hv_cmd(sc, &cmd, sizeof(cmd), &rsp, sizeof(rsp), HCF_NOSLEEP)) { - DPRINTF("%s: INITIATED_CONTACT failed\n", + DPRINTF("%s: CONNECT failed\n", sc->sc_dev.dv_xname); goto errout; } - if (rsp.version_supported) { + if (rsp.chm_done) { sc->sc_flags |= HSF_CONNECTED; sc->sc_proto = versions[i]; sc->sc_handle = 0xe1e10 - 1; /* magic! */ @@ -742,7 +744,7 @@ hv_vmbus_connect(struct hv_softc *sc) break; } } - if (versions[i] == HV_VMBUS_VERSION_INVALID) { + if (i == nitems(versions)) { printf("%s: failed to negotiate protocol version\n", sc->sc_dev.dv_xname); goto errout; @@ -948,18 +950,18 @@ hv_guid_sprint(struct hv_guid *guid, char *str, size_t size) int hv_channel_scan(struct hv_softc *sc) { - struct hv_channel_msg_header hdr; - struct hv_channel_offer_channel rsp, *offer; + struct vmbus_chanmsg_hdr hdr; + struct vmbus_chanmsg_choffer rsp, *offer; struct hv_offer *co; SIMPLEQ_INIT(&sc->sc_offers); mtx_init(&sc->sc_offerlck, IPL_NET); - hdr.message_type = HV_CHANMSG_REQUEST_OFFERS; - hdr.padding = 0; + memset(&hdr, 0, sizeof(hdr)); + hdr.chm_type = VMBUS_CHANMSG_CHREQUEST; if (hv_cmd(sc, &hdr, sizeof(hdr), &rsp, sizeof(rsp), HCF_NOREPLY)) { - DPRINTF("%s: REQUEST_OFFERS failed\n", sc->sc_dev.dv_xname); + DPRINTF("%s: CHREQUEST failed\n", sc->sc_dev.dv_xname); return (-1); } @@ -997,7 +999,7 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co) return; } nch->ch_sc = sc; - hv_guid_sprint(&co->co_chan.offer.interface_type, nch->ch_ident, + hv_guid_sprint(&co->co_chan.chm_chtype, nch->ch_ident, sizeof(nch->ch_ident)); /* @@ -1007,28 +1009,23 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co) */ nch->ch_flags |= CHF_BATCHED; - KASSERT((((vaddr_t)&nch->ch_sigevt) & 0x7) == 0); - memset(&nch->ch_sigevt, 0, sizeof(nch->ch_sigevt)); - nch->ch_sigevt.connection_id = HV_EVENT_CONNECTION_ID; + KASSERT((((vaddr_t)&nch->ch_monprm) & 0x7) == 0); + memset(&nch->ch_monprm, 0, sizeof(nch->ch_monprm)); + nch->ch_monprm.mp_connid = VMBUS_CONNID_EVENT; - if (sc->sc_proto != HV_VMBUS_VERSION_WS2008) { - if (co->co_chan.is_dedicated_interrupt) - nch->ch_flags |= CHF_DEDICATED; - nch->ch_sigevt.connection_id = co->co_chan.connection_id; - } + if (sc->sc_proto != VMBUS_VERSION_WS2008) + nch->ch_monprm.mp_connid = co->co_chan.chm_connid; - if (co->co_chan.monitor_allocated) { - nch->ch_mgroup = co->co_chan.monitor_id >> 5; - nch->ch_mindex = co->co_chan.monitor_id & 0x1f; + if (co->co_chan.chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) { + nch->ch_mgroup = co->co_chan.chm_montrig >> 5; + nch->ch_mindex = co->co_chan.chm_montrig & 0x1f; nch->ch_flags |= CHF_MONITOR; } - nch->ch_relid = co->co_chan.child_rel_id; + nch->ch_id = co->co_chan.chm_chanid; - memcpy(&nch->ch_type, &co->co_chan.offer.interface_type, - sizeof(ch->ch_type)); - memcpy(&nch->ch_inst, &co->co_chan.offer.interface_instance, - sizeof(ch->ch_inst)); + memcpy(&nch->ch_type, &co->co_chan.chm_chtype, sizeof(ch->ch_type)); + memcpy(&nch->ch_inst, &co->co_chan.chm_chinst, sizeof(ch->ch_inst)); mtx_enter(&sc->sc_channelck); TAILQ_FOREACH(ch, &sc->sc_channels, ch_entry) { @@ -1037,7 +1034,7 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co) break; } if (ch != NULL) { - if (co->co_chan.offer.sub_channel_index == 0) { + if (co->co_chan.chm_subidx == 0) { printf("%s: unknown offer \"%s\"\n", sc->sc_dev.dv_xname, nch->ch_ident); mtx_leave(&sc->sc_channelck); @@ -1046,7 +1043,7 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co) } #ifdef HYPERV_DEBUG printf("%s: subchannel %u for \"%s\"\n", sc->sc_dev.dv_xname, - co->co_chan.offer.sub_channel_index, ch->ch_ident); + co->co_chan.chm_subidx, ch->ch_ident); #endif mtx_leave(&sc->sc_channelck); free(nch, M_DEVBUF, sizeof(*nch)); @@ -1059,10 +1056,10 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co) mtx_leave(&sc->sc_channelck); #ifdef HYPERV_DEBUG - printf("%s: channel %u: \"%s\"", sc->sc_dev.dv_xname, nch->ch_relid, + printf("%s: channel %u: \"%s\"", sc->sc_dev.dv_xname, nch->ch_id, nch->ch_ident); - if (co->co_chan.monitor_allocated) - printf(", monitor %u\n", co->co_chan.monitor_id); + if (nch->ch_flags & CHF_MONITOR) + printf(", monitor %u\n", co->co_chan.chm_montrig); else printf("\n"); #endif @@ -1074,7 +1071,7 @@ hv_channel_lookup(struct hv_softc *sc, uint32_t relid) struct hv_channel *ch; TAILQ_FOREACH(ch, &sc->sc_channels, ch_entry) { - if (ch->ch_relid == relid) + if (ch->ch_id == relid) return (ch); } return (NULL); @@ -1099,20 +1096,20 @@ hv_channel_ring_create(struct hv_channel *ch, uint32_t sndbuflen, ch->ch_ring_npg = ch->ch_ring_size >> PAGE_SHIFT; memset(&ch->ch_wrd, 0, sizeof(ch->ch_wrd)); - ch->ch_wrd.rd_ring = (struct hv_ring_buffer *)ch->ch_ring; + ch->ch_wrd.rd_ring = (struct vmbus_bufring *)ch->ch_ring; ch->ch_wrd.rd_size = sndbuflen; - ch->ch_wrd.rd_data_size = sndbuflen - sizeof(struct hv_ring_buffer); + ch->ch_wrd.rd_data_size = sndbuflen - sizeof(struct vmbus_bufring); mtx_init(&ch->ch_wrd.rd_lock, IPL_NET); memset(&ch->ch_rrd, 0, sizeof(ch->ch_rrd)); - ch->ch_rrd.rd_ring = (struct hv_ring_buffer *)((uint8_t *)ch->ch_ring + + ch->ch_rrd.rd_ring = (struct vmbus_bufring *)((uint8_t *)ch->ch_ring + sndbuflen); ch->ch_rrd.rd_size = rcvbuflen; - ch->ch_rrd.rd_data_size = rcvbuflen - sizeof(struct hv_ring_buffer); + ch->ch_rrd.rd_data_size = rcvbuflen - sizeof(struct vmbus_bufring); mtx_init(&ch->ch_rrd.rd_lock, IPL_NET); if (hv_handle_alloc(ch, ch->ch_ring, sndbuflen + rcvbuflen, - &ch->ch_ring_hndl)) { + &ch->ch_ring_gpadl)) { printf("%s: failed to obtain a PA handle for the ring\n", sc->sc_dev.dv_xname); hv_channel_ring_destroy(ch); @@ -1128,7 +1125,7 @@ hv_channel_ring_destroy(struct hv_channel *ch) km_free(ch->ch_ring, ch->ch_wrd.rd_size + ch->ch_rrd.rd_size, &kv_any, &kp_zero); ch->ch_ring = NULL; - hv_handle_free(ch, ch->ch_ring_hndl); + hv_handle_free(ch, ch->ch_ring_gpadl); memset(&ch->ch_wrd, 0, sizeof(ch->ch_wrd)); memset(&ch->ch_rrd, 0, sizeof(ch->ch_rrd)); @@ -1139,8 +1136,8 @@ hv_channel_open(struct hv_channel *ch, void *udata, size_t udatalen, void (*handler)(void *), void *arg) { struct hv_softc *sc = ch->ch_sc; - struct hv_channel_open cmd; - struct hv_channel_open_result rsp; + struct vmbus_chanmsg_chopen cmd; + struct vmbus_chanmsg_chopen_resp rsp; int rv; if (ch->ch_ring == NULL && @@ -1150,16 +1147,15 @@ hv_channel_open(struct hv_channel *ch, void *udata, size_t udatalen, } memset(&cmd, 0, sizeof(cmd)); - cmd.header.message_type = HV_CHANMSG_OPEN_CHANNEL; - cmd.open_id = ch->ch_relid; - cmd.child_rel_id = ch->ch_relid; - cmd.ring_buffer_gpadl_handle = ch->ch_ring_hndl; - cmd.downstream_ring_buffer_page_offset = - ch->ch_wrd.rd_size >> PAGE_SHIFT; - cmd.target_vcpu = ch->ch_vcpu; + cmd.chm_hdr.chm_type = VMBUS_CHANMSG_CHOPEN; + cmd.chm_openid = ch->ch_id; + cmd.chm_chanid = ch->ch_id; + cmd.chm_gpadl = ch->ch_ring_gpadl; + cmd.chm_txbr_pgcnt = ch->ch_wrd.rd_size >> PAGE_SHIFT; + cmd.chm_vcpuid = ch->ch_vcpu; if (udata && udatalen > 0) - memcpy(&cmd.user_data, udata, udatalen); + memcpy(cmd.chm_udata, udata, udatalen); memset(&rsp, 0, sizeof(rsp)); @@ -1171,7 +1167,7 @@ hv_channel_open(struct hv_channel *ch, void *udata, size_t udatalen, rv = hv_cmd(sc, &cmd, sizeof(cmd), &rsp, sizeof(rsp), 0); if (rv) { hv_channel_ring_destroy(ch); - DPRINTF("%s: OPEN_CHANNEL failed with %d\n", + DPRINTF("%s: CHOPEN failed with %d\n", sc->sc_dev.dv_xname, rv); ch->ch_handler = NULL; ch->ch_ctx = NULL; @@ -1186,17 +1182,17 @@ int hv_channel_close(struct hv_channel *ch) { struct hv_softc *sc = ch->ch_sc; - struct hv_channel_close cmd; + struct vmbus_chanmsg_chclose cmd; int rv; memset(&cmd, 0, sizeof(cmd)); - cmd.header.message_type = HV_CHANMSG_CLOSE_CHANNEL; - cmd.child_rel_id = ch->ch_relid; + cmd.chm_hdr.chm_type = VMBUS_CHANMSG_CHCLOSE; + cmd.chm_chanid = ch->ch_id; ch->ch_state = HV_CHANSTATE_CLOSING; rv = hv_cmd(sc, &cmd, sizeof(cmd), NULL, 0, HCF_NOREPLY); if (rv) { - DPRINTF("%s: CLOSE_CHANNEL failed with %d\n", + DPRINTF("%s: CHCLOSE failed with %d\n", sc->sc_dev.dv_xname, rv); return (-1); } @@ -1208,16 +1204,16 @@ hv_channel_close(struct hv_channel *ch) static inline void hv_channel_setevent(struct hv_softc *sc, struct hv_channel *ch) { - struct hv_monitor_trigger_group *mtg; + struct vmbus_mon_trig *mtg; /* Each uint32_t represents 32 channels */ - atomic_setbit_ptr((uint32_t *)sc->sc_wevents + (ch->ch_relid >> 5), - ch->ch_relid & 31); + atomic_setbit_ptr((uint32_t *)sc->sc_wevents + (ch->ch_id >> 5), + ch->ch_id & 31); if (ch->ch_flags & CHF_MONITOR) { - mtg = &sc->sc_monitor[1]->trigger_group[ch->ch_mgroup]; - atomic_setbit_ptr((uint32_t *)&mtg->pending, ch->ch_mindex); + mtg = &sc->sc_monitor[1]->mnf_trigs[ch->ch_mgroup]; + atomic_setbit_ptr((uint32_t *)&mtg->mt_pending, ch->ch_mindex); } else - hv_intr_signal(sc, &ch->ch_sigevt); + hv_intr_signal(sc, &ch->ch_monprm); } static inline void @@ -1225,8 +1221,8 @@ hv_ring_put(struct hv_ring_data *wrd, uint8_t *data, uint32_t datalen) { int left = MIN(datalen, wrd->rd_data_size - wrd->rd_prod); - memcpy(&wrd->rd_ring->buffer[wrd->rd_prod], data, left); - memcpy(&wrd->rd_ring->buffer[0], data + left, datalen - left); + memcpy(&wrd->rd_ring->br_data[wrd->rd_prod], data, left); + memcpy(&wrd->rd_ring->br_data[0], data + left, datalen - left); wrd->rd_prod += datalen; wrd->rd_prod %= wrd->rd_data_size; } @@ -1237,8 +1233,8 @@ hv_ring_get(struct hv_ring_data *rrd, uint8_t *data, uint32_t datalen, { int left = MIN(datalen, rrd->rd_data_size - rrd->rd_cons); - memcpy(data, &rrd->rd_ring->buffer[rrd->rd_cons], left); - memcpy(data + left, &rrd->rd_ring->buffer[0], datalen - left); + memcpy(data, &rrd->rd_ring->br_data[rrd->rd_cons], left); + memcpy(data + left, &rrd->rd_ring->br_data[0], datalen - left); if (!peek) { rrd->rd_cons += datalen; rrd->rd_cons %= rrd->rd_data_size; @@ -1251,8 +1247,8 @@ hv_ring_get(struct hv_ring_data *rrd, uint8_t *data, uint32_t datalen, static inline void hv_ring_avail(struct hv_ring_data *rd, uint32_t *towrite, uint32_t *toread) { - uint32_t ridx = rd->rd_ring->read_index; - uint32_t widx = rd->rd_ring->write_index; + uint32_t ridx = rd->rd_ring->br_rindex; + uint32_t widx = rd->rd_ring->br_windex; uint32_t r, w; w = HV_BYTES_AVAIL_TO_WRITE(ridx, widx, rd->rd_data_size); @@ -1293,13 +1289,13 @@ hv_ring_write(struct hv_ring_data *wrd, struct iovec *iov, int iov_cnt, hv_ring_put(wrd, (uint8_t *)&indices, sizeof(indices)); membar_sync(); - wrd->rd_ring->write_index = wrd->rd_prod; + wrd->rd_ring->br_windex = wrd->rd_prod; mtx_leave(&wrd->rd_lock); /* Signal when the ring transitions from being empty to non-empty */ - if (wrd->rd_ring->interrupt_mask == 0 && - wrd->rd_ring->read_index == oprod) + if (wrd->rd_ring->br_imask == 0 && + wrd->rd_ring->br_rindex == oprod) *needsig = 1; else *needsig = 0; @@ -1312,23 +1308,23 @@ hv_channel_send(struct hv_channel *ch, void *data, uint32_t datalen, uint64_t rid, int type, uint32_t flags) { struct hv_softc *sc = ch->ch_sc; - struct hv_pktdesc d; + struct vmbus_chanpkt cp; struct iovec iov[3]; uint32_t pktlen, pktlen_aligned; uint64_t zeropad = 0; int rv, needsig = 0; - pktlen = sizeof(d) + datalen; + pktlen = sizeof(cp) + datalen; pktlen_aligned = roundup(pktlen, sizeof(uint64_t)); - d.type = type; - d.flags = flags; - d.offset = sizeof(d) >> 3; - d.length = pktlen_aligned >> 3; - d.tid = rid; + cp.cp_hdr.cph_type = type; + cp.cp_hdr.cph_flags = flags; + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_hlen, sizeof(cp)); + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_tlen, pktlen_aligned); + cp.cp_hdr.cph_tid = rid; - iov[0].iov_base = &d; - iov[0].iov_len = sizeof(d); + iov[0].iov_base = &cp; + iov[0].iov_len = sizeof(cp); iov[1].iov_base = data; iov[1].iov_len = datalen; @@ -1344,31 +1340,31 @@ hv_channel_send(struct hv_channel *ch, void *data, uint32_t datalen, } int -hv_channel_sendbuf(struct hv_channel *ch, struct hv_page_buffer *pb, - uint32_t npb, void *data, uint32_t datalen, uint64_t rid) +hv_channel_send_sgl(struct hv_channel *ch, struct vmbus_gpa *sgl, + uint32_t nsge, void *data, uint32_t datalen, uint64_t rid) { struct hv_softc *sc = ch->ch_sc; - struct hv_gpadesc d; + struct vmbus_chanpkt_sglist cp; struct iovec iov[4]; uint32_t buflen, pktlen, pktlen_aligned; uint64_t zeropad = 0; int rv, needsig = 0; - buflen = sizeof(struct hv_page_buffer) * npb; - pktlen = sizeof(d) + datalen + buflen; + buflen = sizeof(struct vmbus_gpa) * nsge; + pktlen = sizeof(cp) + datalen + buflen; pktlen_aligned = roundup(pktlen, sizeof(uint64_t)); - d.type = HV_PKT_DATA_USING_GPA_DIRECT; - d.flags = HV_PKTFLAG_COMPLETION_REQUESTED; - d.offset = (sizeof(d) + buflen) >> 3; - d.length = pktlen_aligned >> 3; - d.tid = rid; - d.range_count = npb; + cp.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; + cp.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_hlen, sizeof(cp) + buflen); + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_tlen, pktlen_aligned); + cp.cp_hdr.cph_tid = rid; + cp.cp_gpa_cnt = nsge; - iov[0].iov_base = &d; - iov[0].iov_len = sizeof(d); + iov[0].iov_base = &cp; + iov[0].iov_len = sizeof(cp); - iov[1].iov_base = pb; + iov[1].iov_base = sgl; iov[1].iov_len = buflen; iov[2].iov_base = data; @@ -1427,7 +1423,7 @@ hv_ring_read(struct hv_ring_data *rrd, void *data, uint32_t datalen, hv_ring_get(rrd, (uint8_t *)&indices, sizeof(indices), 0); membar_sync(); - rrd->rd_ring->read_index = rrd->rd_cons; + rrd->rd_ring->br_rindex = rrd->rd_cons; mtx_leave(&rrd->rd_lock); @@ -1438,17 +1434,17 @@ int hv_channel_recv(struct hv_channel *ch, void *data, uint32_t datalen, uint32_t *rlen, uint64_t *rid, int raw) { - struct hv_pktdesc d; + struct vmbus_chanpkt_hdr cph; uint32_t offset, pktlen; int rv; *rlen = 0; - if ((rv = hv_ring_peek(&ch->ch_rrd, &d, sizeof(d))) != 0) + if ((rv = hv_ring_peek(&ch->ch_rrd, &cph, sizeof(cph))) != 0) return (rv); - offset = raw ? 0 : (d.offset << 3); - pktlen = (d.length << 3) - offset; + offset = raw ? 0 : VMBUS_CHANPKT_GETLEN(cph.cph_hlen); + pktlen = VMBUS_CHANPKT_GETLEN(cph.cph_tlen) - offset; if (pktlen > datalen) { printf("%s: pktlen %u datalen %u\n", __func__, pktlen, datalen); return (EINVAL); @@ -1457,7 +1453,7 @@ hv_channel_recv(struct hv_channel *ch, void *data, uint32_t datalen, rv = hv_ring_read(&ch->ch_rrd, data, pktlen, offset); if (rv == 0) { *rlen = pktlen; - *rid = d.tid; + *rid = cph.cph_tid; } return (rv); @@ -1468,15 +1464,16 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, uint32_t *handle) { struct hv_softc *sc = ch->ch_sc; - struct hv_gpadl_header *hdr; - struct hv_gpadl_body *body, *cmd; - struct hv_gpadl_created rsp; + struct vmbus_chanmsg_gpadl_conn *hdr; + struct vmbus_chanmsg_gpadl_subconn *cmd; + struct vmbus_chanmsg_gpadl_connresp rsp; struct hv_msg *msg; int i, j, last, left, rv; int bodylen = 0, ncmds = 0, pfn = 0; int waitok = cold ? M_NOWAIT : M_WAITOK; uint64_t *frames; paddr_t pa; + caddr_t body; /* Total number of pages to reference */ int total = atop(buflen); /* Number of pages that will fit the header */ @@ -1503,9 +1500,9 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, frames[i] = atop(pa); } - msg->msg_req.payload_size = sizeof(struct hv_gpadl_header) + - sizeof(struct hv_gpa_range) + inhdr * sizeof(uint64_t); - hdr = (struct hv_gpadl_header *)msg->msg_req.payload; + msg->msg_req.hc_dsize = sizeof(struct vmbus_chanmsg_gpadl_conn) + + /* sizeof(struct vmbus_gpa_range) */ + inhdr * sizeof(uint64_t); + hdr = (struct vmbus_chanmsg_gpadl_conn *)msg->msg_req.hc_data; msg->msg_rsp = &rsp; msg->msg_rsplen = sizeof(rsp); if (!waitok) @@ -1516,7 +1513,7 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, /* Allocate additional gpadl_body structures if required */ if (left > 0) { ncmds = MAX(1, left / HV_NPFNBODY + left % HV_NPFNBODY); - bodylen = ncmds * HV_MESSAGE_PAYLOAD; + bodylen = ncmds * VMBUS_MSG_DSIZE_MAX; body = malloc(bodylen, M_DEVBUF, M_ZERO | waitok); if (body == NULL) { free(msg, M_DEVBUF, sizeof(*msg)); @@ -1527,41 +1524,41 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, *handle = atomic_inc_int_nv(&sc->sc_handle); - hdr->header.message_type = HV_CHANMSG_GPADL_HEADER; - hdr->child_rel_id = ch->ch_relid; - hdr->gpadl = *handle; + hdr->chm_hdr.chm_type = VMBUS_CHANMSG_GPADL_CONN; + hdr->chm_chanid = ch->ch_id; + hdr->chm_gpadl = *handle; /* Single range for a contiguous buffer */ - hdr->range_count = 1; - hdr->range_buf_len = sizeof(struct hv_gpa_range) + total * + hdr->chm_range_cnt = 1; + hdr->chm_range_len = sizeof(struct vmbus_gpa_range) + total * sizeof(uint64_t); - hdr->range[0].byte_offset = 0; - hdr->range[0].byte_count = buflen; + hdr->chm_range.gpa_ofs = 0; + hdr->chm_range.gpa_len = buflen; /* Fit as many pages as possible into the header */ for (i = 0; i < inhdr; i++) - hdr->range[0].pfn_array[i] = frames[pfn++]; + hdr->chm_range.gpa_page[i] = frames[pfn++]; for (i = 0; i < ncmds; i++) { - cmd = (struct hv_gpadl_body *)((caddr_t)body + - HV_MESSAGE_PAYLOAD * i); - cmd->header.message_type = HV_CHANMSG_GPADL_BODY; - cmd->gpadl = *handle; + cmd = (struct vmbus_chanmsg_gpadl_subconn *)(body + + VMBUS_MSG_DSIZE_MAX * i); + cmd->chm_hdr.chm_type = VMBUS_CHANMSG_GPADL_SUBCONN; + cmd->chm_gpadl = *handle; last = MIN(left, HV_NPFNBODY); for (j = 0; j < last; j++) - cmd->pfn[j] = frames[pfn++]; + cmd->chm_gpa_page[j] = frames[pfn++]; left -= last; } rv = hv_start(sc, msg); if (rv != 0) { - DPRINTF("%s: GPADL_HEADER failed\n", sc->sc_dev.dv_xname); + DPRINTF("%s: GPADL_CONN failed\n", sc->sc_dev.dv_xname); goto out; } for (i = 0; i < ncmds; i++) { int cmdlen = sizeof(*cmd); - cmd = (struct hv_gpadl_body *)((caddr_t)body + - HV_MESSAGE_PAYLOAD * i); + cmd = (struct vmbus_chanmsg_gpadl_subconn *)(body + + VMBUS_MSG_DSIZE_MAX * i); /* Last element can be short */ if (i == ncmds - 1) cmdlen += last * sizeof(uint64_t); @@ -1569,7 +1566,7 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, cmdlen += HV_NPFNBODY * sizeof(uint64_t); rv = hv_cmd(sc, cmd, cmdlen, NULL, 0, waitok | HCF_NOREPLY); if (rv != 0) { - DPRINTF("%s: GPADL_BODY (iteration %d/%d) failed " + DPRINTF("%s: GPADL_SUBCONN (iteration %d/%d) failed " "with %d\n", sc->sc_dev.dv_xname, i, ncmds, rv); goto out; } @@ -1587,7 +1584,7 @@ hv_handle_alloc(struct hv_channel *ch, void *buffer, uint32_t buflen, if (rv != 0) return (rv); - KASSERT(*handle == rsp.gpadl); + KASSERT(*handle == rsp.chm_gpadl); return (0); } @@ -1596,18 +1593,18 @@ void hv_handle_free(struct hv_channel *ch, uint32_t handle) { struct hv_softc *sc = ch->ch_sc; - struct hv_gpadl_teardown cmd; - struct hv_gpadl_torndown rsp; + struct vmbus_chanmsg_gpadl_disconn cmd; + struct vmbus_chanmsg_gpadl_disconn rsp; int rv; memset(&cmd, 0, sizeof(cmd)); - cmd.header.message_type = HV_CHANMSG_GPADL_TEARDOWN; - cmd.child_rel_id = ch->ch_relid; - cmd.gpadl = handle; + cmd.chm_hdr.chm_type = VMBUS_CHANMSG_GPADL_DISCONN; + cmd.chm_chanid = ch->ch_id; + cmd.chm_gpadl = handle; rv = hv_cmd(sc, &cmd, sizeof(cmd), &rsp, sizeof(rsp), 0); if (rv) - DPRINTF("%s: GPADL_TEARDOWN failed with %d\n", + DPRINTF("%s: GPADL_DISCONN failed with %d\n", sc->sc_dev.dv_xname, rv); } @@ -1734,7 +1731,7 @@ hv_heartbeat(void *arg) sc->sc_dev.dv_xname, hdr->icmsgtype); } hdr->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_channel_send(ch, ch->ch_buf, rlen, rid, HV_PKT_DATA_IN_BAND, 0); + hv_channel_send(ch, ch->ch_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); } void @@ -1806,16 +1803,16 @@ hv_shutdown(void *arg) msg = (struct hv_shutdown_msg *)(hdr + 1); if (msg->flags == 0 || msg->flags == 1) { shutdown = 1; - hdr->status = HV_S_OK; + hdr->status = HV_ICMSG_STATUS_OK; } else - hdr->status = HV_E_FAIL; + hdr->status = HV_ICMSG_STATUS_FAIL; } else if (hdr->icmsgtype != HV_ICMSGTYPE_NEGOTIATE) { printf("%s: unhandled shutdown message type %u\n", sc->sc_dev.dv_xname, hdr->icmsgtype); } hdr->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_channel_send(ch, ch->ch_buf, rlen, rid, HV_PKT_DATA_IN_BAND, 0); + hv_channel_send(ch, ch->ch_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); if (shutdown) task_add(systq, &sc->sc_sdtask); @@ -1875,7 +1872,7 @@ hv_timesync(void *arg) } hdr->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; - hv_channel_send(ch, ch->ch_buf, rlen, rid, HV_PKT_DATA_IN_BAND, 0); + hv_channel_send(ch, ch->ch_buf, rlen, rid, VMBUS_CHANPKT_TYPE_INBAND, 0); } static int diff --git a/sys/dev/pv/hypervreg.h b/sys/dev/pv/hypervreg.h index 00dadfc0695..93278db266c 100644 --- a/sys/dev/pv/hypervreg.h +++ b/sys/dev/pv/hypervreg.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2012 Microsoft Corp. + * Copyright (c) 2009-2012,2016 Microsoft Corp. * Copyright (c) 2012 NetApp Inc. * Copyright (c) 2012 Citrix Inc. * All rights reserved. @@ -29,8 +29,179 @@ #ifndef _HYPERVREG_H_ #define _HYPERVREG_H_ +struct hv_guid { + unsigned char data[16]; +} __packed; + +#define VMBUS_CONNID_MESSAGE 1 +#define VMBUS_CONNID_EVENT 2 +#define VMBUS_SINT_MESSAGE 2 + +/* ============================================================================= + * hyperv_reg.h + * ============================================================================= + */ + +/* + * Hyper-V Synthetic MSRs + */ + +#define MSR_HV_GUEST_OS_ID 0x40000000 +#define MSR_HV_GUESTID_BUILD_MASK 0xffffULL +#define MSR_HV_GUESTID_VERSION_MASK 0x0000ffffffff0000ULL +#define MSR_HV_GUESTID_VERSION_SHIFT 16 +#define MSR_HV_GUESTID_OSID_MASK 0x00ff000000000000ULL +#define MSR_HV_GUESTID_OSID_SHIFT 48 +#define MSR_HV_GUESTID_OSTYPE_MASK 0x7f00000000000000ULL +#define MSR_HV_GUESTID_OSTYPE_SHIFT 56 +#define MSR_HV_GUESTID_OPENSRC 0x8000000000000000ULL +#define MSR_HV_GUESTID_OSTYPE_LINUX \ + ((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) +#define MSR_HV_GUESTID_OSTYPE_FREEBSD \ + ((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) + +#define MSR_HV_HYPERCALL 0x40000001 +#define MSR_HV_HYPERCALL_ENABLE 0x0001ULL +#define MSR_HV_HYPERCALL_RSVD_MASK 0x0ffeULL +#define MSR_HV_HYPERCALL_PGSHIFT 12 + +#define MSR_HV_VP_INDEX 0x40000002 + +#define MSR_HV_TIME_REF_COUNT 0x40000020 + +#define MSR_HV_SCONTROL 0x40000080 +#define MSR_HV_SCTRL_ENABLE 0x0001ULL +#define MSR_HV_SCTRL_RSVD_MASK 0xfffffffffffffffeULL + +#define MSR_HV_SIEFP 0x40000082 +#define MSR_HV_SIEFP_ENABLE 0x0001ULL +#define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL +#define MSR_HV_SIEFP_PGSHIFT 12 + +#define MSR_HV_SIMP 0x40000083 +#define MSR_HV_SIMP_ENABLE 0x0001ULL +#define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL +#define MSR_HV_SIMP_PGSHIFT 12 + +#define MSR_HV_EOM 0x40000084 + +#define MSR_HV_SINT0 0x40000090 +#define MSR_HV_SINT_VECTOR_MASK 0x00ffULL +#define MSR_HV_SINT_RSVD1_MASK 0xff00ULL +#define MSR_HV_SINT_MASKED 0x00010000ULL +#define MSR_HV_SINT_AUTOEOI 0x00020000ULL +#define MSR_HV_SINT_RSVD2_MASK 0xfffffffffffc0000ULL +#define MSR_HV_SINT_RSVD_MASK (MSR_HV_SINT_RSVD1_MASK | \ + MSR_HV_SINT_RSVD2_MASK) + +#define MSR_HV_STIMER0_CONFIG 0x400000b0 +#define MSR_HV_STIMER_CFG_ENABLE 0x0001ULL +#define MSR_HV_STIMER_CFG_PERIODIC 0x0002ULL +#define MSR_HV_STIMER_CFG_LAZY 0x0004ULL +#define MSR_HV_STIMER_CFG_AUTOEN 0x0008ULL +#define MSR_HV_STIMER_CFG_SINT_MASK 0x000f0000ULL +#define MSR_HV_STIMER_CFG_SINT_SHIFT 16 + +#define MSR_HV_STIMER0_COUNT 0x400000b1 + +/* + * CPUID leaves + */ + +#define CPUID_LEAF_HV_MAXLEAF 0x40000000 + +#define CPUID_LEAF_HV_INTERFACE 0x40000001 +#define CPUID_HV_IFACE_HYPERV 0x31237648 /* HV#1 */ + +#define CPUID_LEAF_HV_IDENTITY 0x40000002 + +#define CPUID_LEAF_HV_FEATURES 0x40000003 +/* EAX: features */ +#define CPUID_HV_MSR_TIME_REFCNT 0x0002 /* MSR_HV_TIME_REF_COUNT */ +#define CPUID_HV_MSR_SYNIC 0x0004 /* MSRs for SynIC */ +#define CPUID_HV_MSR_SYNTIMER 0x0008 /* MSRs for SynTimer */ +#define CPUID_HV_MSR_APIC 0x0010 /* MSR_HV_{EOI,ICR,TPR} */ +#define CPUID_HV_MSR_HYPERCALL 0x0020 /* MSR_HV_GUEST_OS_ID + * MSR_HV_HYPERCALL */ +#define CPUID_HV_MSR_VP_INDEX 0x0040 /* MSR_HV_VP_INDEX */ +#define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_HV_GUEST_IDLE */ +/* ECX: power management features */ +#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */ +#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */ +#define CPUPM_HV_CSTATE(f) ((f) & CPUPM_HV_CSTATE_MASK) +/* EDX: features3 */ +#define CPUID3_HV_MWAIT 0x0001 /* MWAIT */ +#define CPUID3_HV_XMM_HYPERCALL 0x0010 /* Hypercall input through + * XMM regs */ +#define CPUID3_HV_GUEST_IDLE 0x0020 /* guest idle */ +#define CPUID3_HV_NUMA 0x0080 /* NUMA distance query */ +#define CPUID3_HV_TIME_FREQ 0x0100 /* timer frequency query + * (TSC, LAPIC) */ +#define CPUID3_HV_MSR_CRASH 0x0400 /* MSRs for guest crash */ + +#define CPUID_LEAF_HV_RECOMMENDS 0x40000004 +#define CPUID_LEAF_HV_LIMITS 0x40000005 +#define CPUID_LEAF_HV_HWFEATURES 0x40000006 + +/* + * Hyper-V Monitor Notification Facility + */ +struct hv_mon_param { + uint32_t mp_connid; + uint16_t mp_evtflag_ofs; + uint16_t mp_rsvd; +} __packed; + +/* + * Hyper-V message types + */ +#define VMBUS_MSGTYPE_NONE 0 +#define VMBUS_MSGTYPE_CHANNEL 1 +#define VMBUS_MSGTYPE_TIMER_EXPIRED 0x80000010 + +/* + * Hypercall status codes + */ +#define HYPERCALL_STATUS_SUCCESS 0x0000 + +/* + * Hypercall input values + */ +#define HYPERCALL_POST_MESSAGE 0x005c +#define HYPERCALL_SIGNAL_EVENT 0x005d + /* - * hyperv.h + * Hypercall input parameters + */ +#define HYPERCALL_PARAM_ALIGN 8 +#if 0 +/* + * XXX + * <<Hypervisor Top Level Functional Specification 4.0b>> requires + * input parameters size to be multiple of 8, however, many post + * message input parameters do _not_ meet this requirement. + */ +#define HYPERCALL_PARAM_SIZE_ALIGN 8 +#endif + +/* + * HYPERCALL_POST_MESSAGE + */ +#define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 +#define HYPERCALL_POSTMSGIN_SIZE 256 + +struct hypercall_postmsg_in { + uint32_t hc_connid; + uint32_t hc_rsvd; + uint32_t hc_msgtype; /* VMBUS_MSGTYPE_ */ + uint32_t hc_dsize; + uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; +} __packed; + +/* + * ============================================================================= + * vmbus.h + * ============================================================================= */ /* @@ -42,589 +213,431 @@ * 2.4 -- Windows 8 * 3.0 -- Windows 8.1 */ -#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13)) -#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1)) -#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4)) -#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) -#define HV_VMBUS_VERSION_INVALID -1 -#define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1 +#define VMBUS_VERSION_WS2008 ((0 << 16) | (13)) +#define VMBUS_VERSION_WIN7 ((1 << 16) | (1)) +#define VMBUS_VERSION_WIN8 ((2 << 16) | (4)) +#define VMBUS_VERSION_WIN8_1 ((3 << 16) | (0)) -#define HV_CONNECTION_ID_MASK 0x1ffffff +#define VMBUS_VERSION_MAJOR(ver) (((uint32_t)(ver)) >> 16) +#define VMBUS_VERSION_MINOR(ver) (((uint32_t)(ver)) & 0xffff) -/* Pipe modes */ -#define HV_PIPE_TYPE_BYTE 0x00000000 -#define HV_PIPE_TYPE_MESSAGE 0x00000004 +/* + * GPA stuffs. + */ +struct vmbus_gpa_range { + uint32_t gpa_len; + uint32_t gpa_ofs; + uint64_t gpa_page[0]; +} __packed; -/* The size of the user defined data buffer for non-pipe offers */ -#define HV_MAX_USER_BYTES 120 +/* This is actually vmbus_gpa_range.gpa_page[1] */ +struct vmbus_gpa { + uint32_t gpa_len; + uint32_t gpa_ofs; + uint64_t gpa_page; +} __packed; -/* The size of the user defined data buffer for pipe offers */ -#define HV_MAX_PIPE_USER_BYTES 116 +#define VMBUS_CHANPKT_SIZE_SHIFT 3 -struct hv_guid { - unsigned char data[16]; +#define VMBUS_CHANPKT_GETLEN(pktlen) \ + (((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT) + +struct vmbus_chanpkt_hdr { + uint16_t cph_type; /* VMBUS_CHANPKT_TYPE_ */ + uint16_t cph_hlen; /* header len, in 8 bytes */ + uint16_t cph_tlen; /* total len, in 8 bytes */ + uint16_t cph_flags; /* VMBUS_CHANPKT_FLAG_ */ + uint64_t cph_tid; } __packed; -/* - * This struct contains the fundamental information about an offer. - */ -struct hv_channel_offer { - struct hv_guid interface_type; - struct hv_guid interface_instance; - uint64_t interrupt_latency_in_100ns_units; - uint32_t interface_revision; - uint32_t server_context_area_size; /* in bytes */ - uint16_t channel_flags; - uint16_t mmio_megabytes; /* bytes * 1024*1024 */ - union { - /* - * Non-pipes: The user has HV_MAX_USER_BYTES bytes. - */ - struct { - uint8_t user_defined[HV_MAX_USER_BYTES]; - } __packed standard; - - /* - * Pipes: The following structure is an integrated pipe - * protocol, which is implemented on top of standard user- - * defined data. pipe clients have HV_MAX_PIPE_USER_BYTES - * left for their own use. - */ - struct { - uint32_t pipe_mode; - uint8_t user_defined[HV_MAX_PIPE_USER_BYTES]; - } __packed pipe; - } u; +#define VMBUS_CHANPKT_TYPE_INBAND 0x0006 +#define VMBUS_CHANPKT_TYPE_RXBUF 0x0007 +#define VMBUS_CHANPKT_TYPE_GPA 0x0009 +#define VMBUS_CHANPKT_TYPE_COMP 0x000b - /* - * Sub_channel_index, newly added in Win8. - */ - uint16_t sub_channel_index; - uint16_t padding; -} __packed; +#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */ -struct hv_pktdesc { - uint16_t type; - uint16_t offset; - uint16_t length; - uint16_t flags; - uint64_t tid; -} __packed; +#define VMBUS_CHANPKT_CONST_DATA(pkt) \ + ((const void *)((const uint8_t *)(pkt) + \ + VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen))) -struct hv_transfer_page { - uint32_t byte_count; - uint32_t byte_offset; +struct vmbus_rxbuf_desc { + uint32_t rb_len; + uint32_t rb_ofs; } __packed; -struct hv_transfer_page_header { - uint16_t set_id; - uint8_t sender_owns_set; - uint8_t reserved; - uint32_t range_count; - struct hv_transfer_page range[0]; +struct vmbus_chanpkt_rxbuf { + struct vmbus_chanpkt_hdr cp_hdr; + uint16_t cp_rxbuf_id; + uint16_t cp_rsvd; + uint32_t cp_rxbuf_cnt; + struct vmbus_rxbuf_desc cp_rxbuf[0]; } __packed; /* - * This structure defines a range in guest physical space that - * can be made to look virtually contiguous. + * ============================================================================= + * vmbus_reg.h + * ============================================================================= */ -struct hv_gpa_range { - uint32_t byte_count; - uint32_t byte_offset; - uint64_t pfn_array[0]; -} __packed; - -#define HV_PKT_INVALID 0x0 -#define HV_PKT_SYNCH 0x1 -#define HV_PKT_ADD_TRANSFER_PAGE_SET 0x2 -#define HV_PKT_REMOVE_TRANSFER_PAGE_SET 0x3 -#define HV_PKT_ESTABLISH_GPADL 0x4 -#define HV_PKT_TEAR_DOWN_GPADL 0x5 -#define HV_PKT_DATA_IN_BAND 0x6 -#define HV_PKT_DATA_USING_TRANSFER_PAGES 0x7 -#define HV_PKT_DATA_USING_GPADL 0x8 -#define HV_PKT_DATA_USING_GPA_DIRECT 0x9 -#define HV_PKT_CANCEL_REQUEST 0xa -#define HV_PKT_COMPLETION 0xb -#define HV_PKT_DATA_USING_ADDITIONAL_PACKETS 0xc -#define HV_PKT_ADDITIONAL_DATA 0xd - -#define HV_PKTFLAG_COMPLETION_REQUESTED 1 - -#define HV_CHANMSG_INVALID 0 -#define HV_CHANMSG_OFFER_CHANNEL 1 -#define HV_CHANMSG_RESCIND_CHANNEL_OFFER 2 -#define HV_CHANMSG_REQUEST_OFFERS 3 -#define HV_CHANMSG_ALL_OFFERS_DELIVERED 4 -#define HV_CHANMSG_OPEN_CHANNEL 5 -#define HV_CHANMSG_OPEN_CHANNEL_RESULT 6 -#define HV_CHANMSG_CLOSE_CHANNEL 7 -#define HV_CHANMSG_GPADL_HEADER 8 -#define HV_CHANMSG_GPADL_BODY 9 -#define HV_CHANMSG_GPADL_CREATED 10 -#define HV_CHANMSG_GPADL_TEARDOWN 11 -#define HV_CHANMSG_GPADL_TORNDOWN 12 -#define HV_CHANMSG_REL_ID_RELEASED 13 -#define HV_CHANMSG_INITIATED_CONTACT 14 -#define HV_CHANMSG_VERSION_RESPONSE 15 -#define HV_CHANMSG_UNLOAD 16 -#define HV_CHANMSG_COUNT 17 - -struct hv_channel_msg_header { - uint32_t message_type; - uint32_t padding; -} __packed; - -struct hv_channel_initiate_contact { - struct hv_channel_msg_header hdr; - uint32_t vmbus_version_requested; - uint32_t padding2; - uint64_t interrupt_page; - uint64_t monitor_page_1; - uint64_t monitor_page_2; -} __packed; - -struct hv_channel_version_response { - struct hv_channel_msg_header header; - uint8_t version_supported; -} __packed; /* - * Common defines for Hyper-V ICs + * Hyper-V SynIC message format. */ -#define HV_ICMSGTYPE_NEGOTIATE 0 -#define HV_ICMSGTYPE_HEARTBEAT 1 -#define HV_ICMSGTYPE_KVPEXCHANGE 2 -#define HV_ICMSGTYPE_SHUTDOWN 3 -#define HV_ICMSGTYPE_TIMESYNC 4 -#define HV_ICMSGTYPE_VSS 5 -#define HV_ICMSGHDRFLAG_TRANSACTION 1 -#define HV_ICMSGHDRFLAG_REQUEST 2 -#define HV_ICMSGHDRFLAG_RESPONSE 4 +#define VMBUS_MSG_DSIZE_MAX 240 +#define VMBUS_MSG_SIZE 256 -struct hv_pipe_hdr { - uint32_t flags; - uint32_t msgsize; +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; -struct hv_ic_version { - uint16_t major; - uint16_t minor; -} __packed; +#define VMBUS_MSGFLAG_PENDING 0x01 -struct hv_icmsg_hdr { - struct hv_ic_version icverframe; - uint16_t icmsgtype; - struct hv_ic_version icvermsg; - uint16_t icmsgsize; - uint32_t status; - uint8_t ictransaction_id; - uint8_t icflags; - uint8_t reserved[2]; -} __packed; +/* + * Hyper-V SynIC event flags + */ -struct hv_icmsg_negotiate { - uint16_t icframe_vercnt; - uint16_t icmsg_vercnt; - uint32_t reserved; - struct hv_ic_version icversion_data[1]; /* any size array */ +struct vmbus_evtflags { + uint32_t evt_flags[64]; } __packed; -struct hv_shutdown_msg { - uint32_t reason_code; - uint32_t timeout_seconds; - uint32_t flags; - uint8_t display_message[2048]; -} __packed; +/* + * Hyper-V Monitor Notification Facility + */ -struct hv_timesync_msg { - uint64_t parent_time; - uint64_t child_time; - uint64_t round_trip_time; - uint8_t flags; -#define HV_TIMESYNC_PROBE 0 -#define HV_TIMESYNC_SYNC 1 -#define HV_TIMESYNC_SAMPLE 2 +struct vmbus_mon_trig { + uint32_t mt_pending; + uint32_t mt_armed; } __packed; -struct hv_heartbeat_msg { - uint64_t seq_num; - uint32_t reserved[8]; -} __packed; +#define VMBUS_MONTRIGS_MAX 4 +#define VMBUS_MONTRIG_LEN 32 -struct hv_ring_buffer { - /* Offset in bytes from the start of ring data below */ - volatile uint32_t write_index; - /* Offset in bytes from the start of ring data below */ - volatile uint32_t read_index; - /* Interrupt mask */ - volatile uint32_t interrupt_mask; - /* Ring data starts on the next page */ - uint8_t reserved[4084]; - /* Data, doubles as interrupt mask */ - uint8_t buffer[0]; -} __packed; +struct vmbus_mnf { + uint32_t mnf_state; + uint32_t mnf_rsvd1; -struct hv_page_buffer { - int length; - int offset; - uint64_t pfn; -} __packed; + struct vmbus_mon_trig + mnf_trigs[VMBUS_MONTRIGS_MAX]; + uint8_t mnf_rsvd2[536]; -#define HV_MAX_PAGE_BUFFERS 32 + uint16_t mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN]; + uint8_t mnf_rsvd3[256]; -struct hv_gpadesc { - uint16_t type; - uint16_t offset; - uint16_t length; - uint16_t flags; - uint64_t tid; - uint32_t reserved; - uint32_t range_count; + struct hv_mon_param + mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN]; + uint8_t mnf_rsvd4[1984]; } __packed; /* - * Channel Offer parameters + * Buffer ring */ -struct hv_channel_offer_channel { - struct hv_channel_msg_header header; - struct hv_channel_offer offer; - uint32_t child_rel_id; - uint8_t monitor_id; +struct vmbus_bufring { /* - * This field has been split into a bit field on Win7 and higher. + * If br_windex == br_rindex, this bufring is empty; this + * means we can _not_ write data to the bufring, if the + * write is going to make br_windex same as br_rindex. */ - uint8_t monitor_allocated:1; - uint8_t reserved1:7; + volatile uint32_t br_windex; + volatile uint32_t br_rindex; + /* - * Following fields were added in win7 and higher. - * Make sure to check the version before accessing these fields. + * Interrupt mask {0,1} * - * If "is_dedicated_interrupt" is set, we must not set the - * associated bit in the channel bitmap while sending the - * interrupt to the host. + * For TX bufring, host set this to 1, when it is processing + * the TX bufring, so that we can safely skip the TX event + * notification to host. * - * connection_id is used in signaling the host. + * For RX bufring, once this is set to 1 by us, host will not + * further dispatch interrupts to us, even if there are data + * pending on the RX bufring. This effectively disables the + * interrupt of the channel to which this RX bufring is attached. */ - uint16_t is_dedicated_interrupt:1; - uint16_t reserved2:15; - uint32_t connection_id; -} __packed; + volatile uint32_t br_imask; -/* - * Open Channel parameters - */ -struct hv_channel_open { - struct hv_channel_msg_header header; - /* Identifies the specific VMBus channel that is being opened */ - uint32_t child_rel_id; - /* ID making a particular open request at a channel offer unique */ - uint32_t open_id; - /* GPADL for the channel's ring buffer */ - uint32_t ring_buffer_gpadl_handle; - /* - * Before win8, all incoming channel interrupts are only delivered - * on cpu 0. Setting this value to 0 would preserve the earlier - * behavior. - */ - uint32_t target_vcpu; - /* - * The upstream ring buffer begins at offset zero in the memory - * described by ring_buffer_gpadl_handle. The downstream ring - * buffer follows it at this offset (in pages). - */ - uint32_t downstream_ring_buffer_page_offset; - /* User-specific data to be passed along to the server endpoint. */ - uint8_t user_data[HV_MAX_USER_BYTES]; + uint8_t br_rsvd[4084]; + uint8_t br_data[0]; } __packed; /* - * Open Channel Result parameters + * Channel */ -struct hv_channel_open_result { - struct hv_channel_msg_header header; - uint32_t child_rel_id; - uint32_t open_id; - uint32_t status; -} __packed; -/* - * Close channel parameters - */ -struct hv_channel_close { - struct hv_channel_msg_header header; - uint32_t child_rel_id; -} __packed; +#define VMBUS_CHAN_MAX_COMPAT 256 +#define VMBUS_CHAN_MAX (VMBUS_EVTFLAG_LEN * VMBUS_EVTFLAGS_MAX) /* - * Channel Message GPADL + * Channel packets */ -#define HV_GPADL_TYPE_RING_BUFFER 1 -#define HV_GPADL_TYPE_SERVER_SAVE_AREA 2 -#define HV_GPADL_TYPE_TRANSACTION 8 -/* - * The number of PFNs in a GPADL message is defined by the number of - * pages that would be spanned by byte_count and byte_offset. If the - * implied number of PFNs won't fit in this packet, there will be a - * follow-up packet that contains more. - */ +#define VMBUS_CHANPKT_SIZE_ALIGN (1 << VMBUS_CHANPKT_SIZE_SHIFT) -struct hv_gpadl_header { - struct hv_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; - uint16_t range_buf_len; - uint16_t range_count; - struct hv_gpa_range range[0]; -} __packed; +#define VMBUS_CHANPKT_SETLEN(pktlen, len) \ +do { \ + (pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT; \ +} while (0) -/* How many PFNs can be referenced by the header */ -#define HV_NPFNHDR \ - ((HV_MESSAGE_PAYLOAD - sizeof(struct hv_gpadl_header) - \ - sizeof(struct hv_gpa_range)) / sizeof(uint64_t)) - -/* - * This is the follow-up packet that contains more PFNs - */ -struct hv_gpadl_body { - struct hv_channel_msg_header header; - uint32_t message_number; - uint32_t gpadl; - uint64_t pfn[0]; +struct vmbus_chanpkt { + struct vmbus_chanpkt_hdr cp_hdr; } __packed; -/* How many PFNs can be referenced by the body */ -#define HV_NPFNBODY \ - ((HV_MESSAGE_PAYLOAD - sizeof(struct hv_gpadl_body)) / \ - sizeof(uint64_t)) - -struct hv_gpadl_created { - struct hv_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; - uint32_t creation_status; +struct vmbus_chanpkt_sglist { + struct vmbus_chanpkt_hdr cp_hdr; + uint32_t cp_rsvd; + uint32_t cp_gpa_cnt; + struct vmbus_gpa cp_gpa[0]; } __packed; -struct hv_gpadl_teardown { - struct hv_channel_msg_header header; - uint32_t child_rel_id; - uint32_t gpadl; -} __packed; - -struct hv_gpadl_torndown { - struct hv_channel_msg_header header; - uint32_t gpadl; +struct vmbus_chanpkt_prplist { + struct vmbus_chanpkt_hdr cp_hdr; + uint32_t cp_rsvd; + uint32_t cp_range_cnt; + struct vmbus_gpa_range cp_range[0]; } __packed; /* - * hv_vmbus_priv.h + * Channel messages + * - Embedded in vmbus_message.msg_data, e.g. response and notification. + * - Embedded in hypercall_postmsg_in.hc_data, e.g. request. */ -#define HV_MESSAGE_SIZE 256 -#define HV_MESSAGE_PAYLOAD 240 +#define VMBUS_CHANMSG_CHOFFER 1 /* NOTE */ +#define VMBUS_CHANMSG_CHRESCIND 2 /* NOTE */ +#define VMBUS_CHANMSG_CHREQUEST 3 /* REQ */ +#define VMBUS_CHANMSG_CHOFFER_DONE 4 /* NOTE */ +#define VMBUS_CHANMSG_CHOPEN 5 /* REQ */ +#define VMBUS_CHANMSG_CHOPEN_RESP 6 /* RESP */ +#define VMBUS_CHANMSG_CHCLOSE 7 /* REQ */ +#define VMBUS_CHANMSG_GPADL_CONN 8 /* REQ */ +#define VMBUS_CHANMSG_GPADL_SUBCONN 9 /* REQ */ +#define VMBUS_CHANMSG_GPADL_CONNRESP 10 /* RESP */ +#define VMBUS_CHANMSG_GPADL_DISCONN 11 /* REQ */ +#define VMBUS_CHANMSG_GPADL_DISCONNRESP 12 /* RESP */ +#define VMBUS_CHANMSG_CHFREE 13 /* REQ */ +#define VMBUS_CHANMSG_CONNECT 14 /* REQ */ +#define VMBUS_CHANMSG_CONNECT_RESP 15 /* RESP */ +#define VMBUS_CHANMSG_DISCONNECT 16 /* REQ */ +#define VMBUS_CHANMSG_COUNT 17 +#define VMBUS_CHANMSG_MAX 22 -/* - * Hypervisor message IDs ??? - */ -#define HV_MESSAGE_CONNECTION_ID 1 -#define HV_MESSAGE_PORT_ID 1 -#define HV_EVENT_CONNECTION_ID 2 -#define HV_EVENT_PORT_ID 2 -#define HV_MONITOR_CONNECTION_ID 3 -#define HV_MONITOR_PORT_ID 3 -#define HV_MESSAGE_SINT 2 +struct vmbus_chanmsg_hdr { + uint32_t chm_type; /* VMBUS_CHANMSG_* */ + uint32_t chm_rsvd; +} __packed; -/* - * Hypervisor message types - */ -#define HV_MESSAGE_TYPE_NONE 0x00000000 -#define HV_MESSAGE_TIMER_EXPIRED 0x80000010 +/* VMBUS_CHANMSG_CONNECT */ +struct vmbus_chanmsg_connect { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_ver; + uint32_t chm_rsvd; + uint64_t chm_evtflags; + uint64_t chm_mnf1; + uint64_t chm_mnf2; +} __packed; + +/* VMBUS_CHANMSG_CONNECT_RESP */ +struct vmbus_chanmsg_connect_resp { + struct vmbus_chanmsg_hdr chm_hdr; + uint8_t chm_done; +} __packed; + +/* VMBUS_CHANMSG_CHREQUEST */ +struct vmbus_chanmsg_chrequest { + struct vmbus_chanmsg_hdr chm_hdr; +} __packed; + +/* VMBUS_CHANMSG_DISCONNECT */ +struct vmbus_chanmsg_disconnect { + struct vmbus_chanmsg_hdr chm_hdr; +} __packed; + +/* VMBUS_CHANMSG_CHOPEN */ +struct vmbus_chanmsg_chopen { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_openid; + uint32_t chm_gpadl; + uint32_t chm_vcpuid; + uint32_t chm_txbr_pgcnt; +#define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE 120 + uint8_t chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE]; +} __packed; + +/* VMBUS_CHANMSG_CHOPEN_RESP */ +struct vmbus_chanmsg_chopen_resp { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_openid; + uint32_t chm_status; +} __packed; + +/* VMBUS_CHANMSG_GPADL_CONN */ +struct vmbus_chanmsg_gpadl_conn { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_gpadl; + uint16_t chm_range_len; + uint16_t chm_range_cnt; + struct vmbus_gpa_range chm_range; +} __packed; + +#define VMBUS_CHANMSG_GPADL_CONN_PGMAX 26 + +/* VMBUS_CHANMSG_GPADL_SUBCONN */ +struct vmbus_chanmsg_gpadl_subconn { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_msgno; + uint32_t chm_gpadl; + uint64_t chm_gpa_page[0]; +} __packed; + +#define VMBUS_CHANMSG_GPADL_SUBCONN_PGMAX 28 + +/* VMBUS_CHANMSG_GPADL_CONNRESP */ +struct vmbus_chanmsg_gpadl_connresp { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_gpadl; + uint32_t chm_status; +} __packed; + +/* VMBUS_CHANMSG_CHCLOSE */ +struct vmbus_chanmsg_chclose { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; +} __packed; + +/* VMBUS_CHANMSG_GPADL_DISCONN */ +struct vmbus_chanmsg_gpadl_disconn { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_gpadl; +} __packed; + +/* VMBUS_CHANMSG_CHFREE */ +struct vmbus_chanmsg_chfree { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; +} __packed; -struct hv_monitor_trigger_state { - uint32_t group_enable :4; - uint32_t reserved :28; -}; +/* VMBUS_CHANMSG_CHRESCIND */ +struct vmbus_chanmsg_chrescind { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; +} __packed; -struct hv_monitor_trigger_group { - uint32_t pending; - uint32_t armed; -}; +/* VMBUS_CHANMSG_CHOFFER */ +struct vmbus_chanmsg_choffer { + struct vmbus_chanmsg_hdr chm_hdr; + struct hv_guid chm_chtype; + struct hv_guid chm_chinst; + uint64_t chm_chlat; /* unit: 100ns */ + uint32_t chm_chrev; + uint32_t chm_svrctx_sz; + uint16_t chm_chflags; + uint16_t chm_mmio_sz; /* unit: MB */ + uint8_t chm_udata[120]; + uint16_t chm_subidx; + uint16_t chm_rsvd; + uint32_t chm_chanid; + uint8_t chm_montrig; + uint8_t chm_flags1; /* VMBUS_CHOFFER_FLAG1_ */ + uint16_t chm_flags2; + uint32_t chm_connid; +} __packed; -struct hv_monitor_parameter { - uint32_t connection_id; - uint16_t flag_number; - uint16_t reserved; -}; +#define VMBUS_CHOFFER_FLAG1_HASMNF 0x01 /* - * Monitor page Layout - * ------------------------------------------------------ - * | 0 | trigger_state (4 bytes) | reserved1 (4 bytes) | - * | 8 | trigger_group[0] | - * | 10 | trigger_group[1] | - * | 18 | trigger_group[2] | - * | 20 | trigger_group[3] | - * | 28 | reserved2[0] | - * | 30 | reserved2[1] | - * | 38 | reserved2[2] | - * | 40 | next_check_time[0][0] | next_check_time[0][1] | - * | ... | - * | 240 | latency[0][0..3] | - * | 340 | reserved3[0] | - * | 440 | parameter[0][0] | - * | 448 | parameter[0][1] | - * | ... | - * | 840 | reserved4[0] | - * ------------------------------------------------------ + * ============================================================================= + * Temporary + * ============================================================================= */ -struct hv_monitor_page { - struct hv_monitor_trigger_state trigger_state; - uint32_t reserved1; - - struct hv_monitor_trigger_group trigger_group[4]; - uint64_t reserved2[3]; - int32_t next_check_time[4][32]; + /* + * Common defines for Hyper-V ICs + */ +#define HV_ICMSGTYPE_NEGOTIATE 0 +#define HV_ICMSGTYPE_HEARTBEAT 1 +#define HV_ICMSGTYPE_KVPEXCHANGE 2 +#define HV_ICMSGTYPE_SHUTDOWN 3 +#define HV_ICMSGTYPE_TIMESYNC 4 +#define HV_ICMSGTYPE_VSS 5 - uint16_t latency[4][32]; - uint64_t reserved3[32]; +#define HV_ICMSGHDRFLAG_TRANSACTION 1 +#define HV_ICMSGHDRFLAG_REQUEST 2 +#define HV_ICMSGHDRFLAG_RESPONSE 4 - struct hv_monitor_parameter parameter[4][32]; - - uint8_t reserved4[1984]; -}; - -struct hv_input_post_message { - uint32_t connection_id; - uint32_t reserved; - uint32_t message_type; - uint32_t payload_size; - uint8_t payload[HV_MESSAGE_PAYLOAD]; +struct hv_pipe_hdr { + uint32_t flags; + uint32_t msgsize; } __packed; -/* - * Synthetic interrupt controller event flags - */ -struct hv_synic_event_flags { - uint32_t flags[64]; +struct hv_ic_version { + uint16_t major; + uint16_t minor; } __packed; -#define HV_X64_MSR_GUEST_OS_ID 0x40000000 -#define HV_X64_MSR_HYPERCALL 0x40000001 -#define HV_X64_MSR_HYPERCALL_ENABLED (1 << 0) -#define HV_X64_MSR_HYPERCALL_PASHIFT 12 -#define HV_X64_MSR_VP_INDEX 0x40000002 -#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 +struct hv_icmsg_hdr { + struct hv_ic_version icverframe; + uint16_t icmsgtype; + struct hv_ic_version icvermsg; + uint16_t icmsgsize; + uint32_t status; + uint8_t ictransaction_id; + uint8_t icflags; + uint8_t reserved[2]; +} __packed; -#define HV_S_OK 0x00000000 -#define HV_E_FAIL 0x80004005 -#define HV_ERROR_NOT_SUPPORTED 0x80070032 -#define HV_ERROR_MACHINE_LOCKED 0x800704f7 +#define HV_ICMSG_STATUS_OK 0x00000000 +#define HV_ICMSG_STATUS_FAIL 0x80004005 -/* - * Synthetic interrupt controller message header - */ -struct hv_vmbus_msg_header { - uint32_t message_type; - uint8_t payload_size; - uint8_t message_flags; -#define HV_SYNIC_MHF_PENDING 0x0001 - uint8_t reserved[2]; - union { - uint64_t sender; - uint32_t port; - } u; +struct hv_icmsg_negotiate { + uint16_t icframe_vercnt; + uint16_t icmsg_vercnt; + uint32_t reserved; + struct hv_ic_version icversion_data[1]; /* any size array */ } __packed; -/* - * Define synthetic interrupt controller message format - */ -struct hv_vmbus_message { - struct hv_vmbus_msg_header header; - uint64_t payload[30]; +struct hv_shutdown_msg { + uint32_t reason_code; + uint32_t timeout_seconds; + uint32_t flags; + uint8_t display_message[2048]; } __packed; -/* - * 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) -#define HV_MAX_NUM_CHANNELS_SUPPORTED 256 - -/* Virtual APIC registers */ -#define HV_X64_MSR_EOI 0x40000070 -#define HV_X64_MSR_ICR 0x40000071 -#define HV_X64_MSR_TPR 0x40000072 -#define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073 -#define HV_APIC_ASSIST_PAGE_PASHIFT 12 +struct hv_timesync_msg { + uint64_t parent_time; + uint64_t child_time; + uint64_t round_trip_time; + uint8_t flags; +#define HV_TIMESYNC_PROBE 0 +#define HV_TIMESYNC_SYNC 1 +#define HV_TIMESYNC_SAMPLE 2 +} __packed; -/* - * Synthetic interrupt controller model specific registers - */ -/* Synthetic Interrupt Controll registers */ -#define HV_X64_MSR_SCONTROL 0x40000080 -#define HV_X64_MSR_SCONTROL_ENABLED (1<<0) -#define HV_X64_MSR_SVERSION 0x40000081 -/* Synthetic Interrupt Event Flags Page register */ -#define HV_X64_MSR_SIEFP 0x40000082 -#define HV_X64_MSR_SIEFP_ENABLED (1<<0) -#define HV_X64_MSR_SIEFP_PASHIFT 12 -/* Synthetic Interrupt Message Page register */ -#define HV_X64_MSR_SIMP 0x40000083 -#define HV_X64_MSR_SIMP_ENABLED (1<<0) -#define HV_X64_MSR_SIMP_PASHIFT 12 -#define HV_X64_MSR_EOM 0x40000084 - -#define HV_X64_MSR_SINT0 0x40000090 -#define HV_X64_MSR_SINT1 0x40000091 -#define HV_X64_MSR_SINT2 0x40000092 -#define HV_X64_MSR_SINT3 0x40000093 -#define HV_X64_MSR_SINT4 0x40000094 -#define HV_X64_MSR_SINT5 0x40000095 -#define HV_X64_MSR_SINT6 0x40000096 -#define HV_X64_MSR_SINT7 0x40000097 -#define HV_X64_MSR_SINT8 0x40000098 -#define HV_X64_MSR_SINT9 0x40000099 -#define HV_X64_MSR_SINT10 0x4000009A -#define HV_X64_MSR_SINT11 0x4000009B -#define HV_X64_MSR_SINT12 0x4000009C -#define HV_X64_MSR_SINT13 0x4000009D -#define HV_X64_MSR_SINT14 0x4000009E -#define HV_X64_MSR_SINT15 0x4000009F -#define HV_X64_MSR_SINT_VECTOR 0xff -#define HV_X64_MSR_SINT_MASKED (1<<16) -#define HV_X64_MSR_SINT_AUTOEOI (1<<17) +struct hv_heartbeat_msg { + uint64_t seq_num; + uint32_t reserved[8]; +} __packed; /* - * Hypercalls + * ============================================================================= + * Helper macros + * ============================================================================= */ -#define HV_CALL_POST_MESSAGE 0x005c -#define HV_CALL_SIGNAL_EVENT 0x005d -/* - * Hypercall status codes - */ -#define HV_STATUS_SUCCESS 0 -#define HV_STATUS_INVALID_HYPERCALL_CODE 2 -#define HV_STATUS_INVALID_HYPERCALL_INPUT 3 -#define HV_STATUS_INVALID_ALIGNMENT 4 -#define HV_STATUS_INSUFFICIENT_MEMORY 11 -#define HV_STATUS_INVALID_CONNECTION_ID 18 -#define HV_STATUS_INSUFFICIENT_BUFFERS 19 +/* How many PFNs can be referenced by the header */ +#define HV_NPFNHDR ((VMBUS_MSG_DSIZE_MAX - \ + sizeof(struct vmbus_chanmsg_gpadl_conn)) / sizeof(uint64_t)) -/* - * XXX: Hypercall signal input structure - */ -struct hv_input_signal_event { - uint32_t connection_id; - uint16_t flag_number; - uint16_t reserved; -} __packed; +/* How many PFNs can be referenced by the body */ +#define HV_NPFNBODY ((VMBUS_MSG_DSIZE_MAX - \ + sizeof(struct vmbus_chanmsg_gpadl_subconn)) / sizeof(uint64_t)) #endif /* _HYPERVREG_H_ */ diff --git a/sys/dev/pv/hypervvar.h b/sys/dev/pv/hypervvar.h index 41c973bef46..ebd23ba3ee5 100644 --- a/sys/dev/pv/hypervvar.h +++ b/sys/dev/pv/hypervvar.h @@ -32,7 +32,7 @@ struct hv_msg { #define MSGF_NOSLEEP 0x0001 #define MSGF_NOQUEUE 0x0002 #define MSGF_ORPHANED 0x0004 - struct hv_input_post_message msg_req; + struct hypercall_postmsg_in msg_req; void *msg_rsp; size_t msg_rsplen; TAILQ_ENTRY(hv_msg) msg_entry; @@ -40,13 +40,13 @@ struct hv_msg { TAILQ_HEAD(hv_queue, hv_msg); struct hv_offer { - struct hv_channel_offer_channel co_chan; + struct vmbus_chanmsg_choffer co_chan; SIMPLEQ_ENTRY(hv_offer) co_entry; }; SIMPLEQ_HEAD(hv_offers, hv_offer); struct hv_ring_data { - struct hv_ring_buffer *rd_ring; + struct vmbus_bufring *rd_ring; uint32_t rd_size; struct mutex rd_lock; uint32_t rd_prod; @@ -63,7 +63,7 @@ struct hv_channel { #define HV_CHANSTATE_OPENED 2 #define HV_CHANSTATE_CLOSING 3 #define HV_CHANSTATE_CLOSED 4 - uint32_t ch_relid; + uint32_t ch_id; struct hv_guid ch_type; struct hv_guid ch_inst; @@ -73,7 +73,7 @@ struct hv_channel { uint8_t ch_mindex; void *ch_ring; - uint32_t ch_ring_hndl; + uint32_t ch_ring_gpadl; uint32_t ch_ring_npg; ulong ch_ring_size; @@ -90,10 +90,9 @@ struct hv_channel { uint32_t ch_flags; #define CHF_BATCHED 0x0001 -#define CHF_DEDICATED 0x0002 -#define CHF_MONITOR 0x0004 +#define CHF_MONITOR 0x0002 - struct hv_input_signal_event ch_sigevt __attribute__((aligned(8))); + struct hv_mon_param ch_monprm __attribute__((aligned(8))); TAILQ_ENTRY(hv_channel) ch_entry; }; @@ -142,7 +141,7 @@ struct hv_softc { uint32_t *sc_revents; /* Read events */ /* Monitor pages for parent<->child notifications */ - struct hv_monitor_page *sc_monitor[2]; + struct vmbus_mnf *sc_monitor[2]; struct hv_queue sc_reqs; /* Request queue */ struct mutex sc_reqlck; @@ -197,7 +196,7 @@ int hv_channel_open(struct hv_channel *, void *, size_t, void (*)(void *), int hv_channel_close(struct hv_channel *); int hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t, int, uint32_t); -int hv_channel_sendbuf(struct hv_channel *, struct hv_page_buffer *, +int hv_channel_send_sgl(struct hv_channel *, struct vmbus_gpa *, uint32_t, void *, uint32_t, uint64_t); int hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *, uint64_t *, int); diff --git a/sys/dev/pv/if_hvn.c b/sys/dev/pv/if_hvn.c index 9ba9cdd0a42..2e3408f7439 100644 --- a/sys/dev/pv/if_hvn.c +++ b/sys/dev/pv/if_hvn.c @@ -268,7 +268,7 @@ hvn_attach(struct device *parent, struct device *self, void *aux) } DPRINTF("%s", sc->sc_dev.dv_xname); - printf(": channel %u, address %s\n", sc->sc_chan->ch_relid, + printf(": channel %u, address %s\n", sc->sc_chan->ch_id, ether_sprintf(sc->sc_ac.ac_enaddr)); ether_ifattach(ifp); @@ -721,7 +721,7 @@ void hvn_nvsp_intr(void *arg) { struct hvn_softc *sc = arg; - struct hv_pktdesc *d; + struct vmbus_chanpkt_hdr *cph; struct nvsp *pkt; uint64_t rid; uint32_t rlen; @@ -736,10 +736,10 @@ hvn_nvsp_intr(void *arg) "packet\n", sc->sc_dev.dv_xname); break; } - d = (struct hv_pktdesc *)sc->sc_nvspbuf; - pkt = (struct nvsp *)((char *)d + (d->offset << 3)); + cph = (struct vmbus_chanpkt_hdr *)sc->sc_nvspbuf; + pkt = (struct nvsp *)VMBUS_CHANPKT_CONST_DATA(cph); - if (d->type == HV_PKT_COMPLETION) { + if (cph->cph_type == VMBUS_CHANPKT_TYPE_COMP) { switch (pkt->msg_type) { case nvsp_type_init_comp: case nvsp_type_send_rx_buf_comp: @@ -750,17 +750,17 @@ hvn_nvsp_intr(void *arg) wakeup_one(&sc->sc_nvsp); break; case nvsp_type_send_rndis_pkt_comp: - hvn_txeof(sc, d->tid); + hvn_txeof(sc, cph->cph_tid); break; default: printf("%s: unhandled NVSP packet type %d " "on completion\n", sc->sc_dev.dv_xname, pkt->msg_type); } - } else if (d->type == HV_PKT_DATA_USING_TRANSFER_PAGES) { + } else if (cph->cph_type == VMBUS_CHANPKT_TYPE_RXBUF) { switch (pkt->msg_type) { case nvsp_type_send_rndis_pkt: - hvn_rndis_filter(sc, d->tid, d + 1); + hvn_rndis_filter(sc, cph->cph_tid, cph); break; default: printf("%s: unhandled NVSP packet type %d " @@ -769,7 +769,7 @@ hvn_nvsp_intr(void *arg) } } else printf("%s: unknown NVSP packet type %u\n", - sc->sc_dev.dv_xname, d->type); + sc->sc_dev.dv_xname, cph->cph_type); } } @@ -781,8 +781,8 @@ hvn_nvsp_output(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid, int timo) do { rv = hv_channel_send(sc->sc_chan, pkt, sizeof(*pkt), - tid, HV_PKT_DATA_IN_BAND, - timo ? HV_PKTFLAG_COMPLETION_REQUESTED : 0); + tid, VMBUS_CHANPKT_TYPE_INBAND, + timo ? VMBUS_CHANPKT_FLAG_RC : 0); if (rv == EAGAIN) { if (timo) tsleep(pkt, PRIBIO, "hvnsend", timo / 10); @@ -822,7 +822,7 @@ hvn_nvsp_ack(struct hvn_softc *sc, struct nvsp *pkt, uint64_t tid) do { rv = hv_channel_send(sc->sc_chan, pkt, sizeof(*pkt), - tid, HV_PKT_COMPLETION, 0); + tid, VMBUS_CHANPKT_TYPE_COMP, 0); if (rv == EAGAIN) delay(100); else if (rv) { @@ -1015,7 +1015,7 @@ int hvn_rndis_ctloutput(struct hvn_softc *sc, struct rndis_cmd *rc, int timo) { struct nvsp_send_rndis_pkt *msg; - struct hv_page_buffer pb[2]; + struct vmbus_gpa sgl[1]; int tries = 10; int rv; @@ -1026,14 +1026,14 @@ hvn_rndis_ctloutput(struct hvn_softc *sc, struct rndis_cmd *rc, int timo) msg->chan_type = 1; /* control */ msg->send_buf_section_idx = NVSP_INVALID_SECTION_INDEX; - pb[0].pfn = rc->rc_pfn; - pb[0].length = rc->rc_req->msg_len; - pb[0].offset = 0; + sgl[0].gpa_page = rc->rc_pfn; + sgl[0].gpa_len = rc->rc_req->msg_len; + sgl[0].gpa_ofs = 0; hvn_submit_cmd(sc, rc); do { - rv = hv_channel_sendbuf(sc->sc_chan, pb, 1, &rc->rc_nvsp, + rv = hv_channel_send_sgl(sc->sc_chan, sgl, 1, &rc->rc_nvsp, sizeof(struct nvsp), rc->rc_id); if (rv == EAGAIN) tsleep(rc, PRIBIO, "hvnsendbuf", timo / 10); @@ -1079,23 +1079,18 @@ hvn_rndis_filter(struct hvn_softc *sc, uint64_t tid, void *arg) struct ifnet *ifp = &sc->sc_ac.ac_if; struct mbuf_list ml = MBUF_LIST_INITIALIZER(); struct nvsp pkt; - struct hv_transfer_page_header *hdr = arg; + struct vmbus_chanpkt_prplist *cp = arg; struct nvsp_send_rndis_pkt_comp *cmp; uint32_t off, len, type, status = 0; int i; - if (hdr->set_id != HVN_RX_BUFID) { - DPRINTF("%s: transfer page invalid set id %#x\n", - sc->sc_dev.dv_xname, hdr->set_id); - return; - } if (sc->sc_rx_ring == NULL) { DPRINTF("%s: invalid rx ring\n", sc->sc_dev.dv_xname); return; } - for (i = 0; i < hdr->range_count; i++) { - off = hdr->range[i].byte_offset; - len = hdr->range[i].byte_count; + for (i = 0; i < cp->cp_range_cnt; i++) { + off = cp->cp_range[i].gpa_ofs; + len = cp->cp_range[i].gpa_len; KASSERT(off + len <= sc->sc_rx_size); KASSERT(len >= RNDIS_HEADER_SIZE + 4); |