Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150680475
D6744.id17374.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D6744.id17374.diff
View Options
Index: sys/dev/hyperv/vmbus/hv_channel.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_channel.c
+++ sys/dev/hyperv/vmbus/hv_channel.c
@@ -62,17 +62,16 @@
static void
vmbus_channel_set_event(hv_vmbus_channel *channel)
{
- hv_vmbus_monitor_page *monitor_page;
-
if (channel->offer_msg.monitor_allocated) {
+ struct vmbus_softc *sc = vmbus_get_softc();
+ hv_vmbus_monitor_page *monitor_page;
+
/* Each uint32_t represents 32 channels */
synch_set_bit((channel->offer_msg.child_rel_id & 31),
- ((uint32_t *)hv_vmbus_g_connection.send_interrupt_page
+ ((uint32_t *)sc->vmbus_tx_evtflags
+ ((channel->offer_msg.child_rel_id >> 5))));
- monitor_page = (hv_vmbus_monitor_page *)
- hv_vmbus_g_connection.monitor_page_2;
-
+ monitor_page = sc->vmbus_mnf2;
synch_set_bit(channel->monitor_bit,
(uint32_t *)&monitor_page->
trigger_group[channel->monitor_group].u.pending);
Index: sys/dev/hyperv/vmbus/hv_connection.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_connection.c
+++ sys/dev/hyperv/vmbus/hv_connection.c
@@ -74,8 +74,8 @@
* Negotiate the highest supported hypervisor version.
*/
static int
-hv_vmbus_negotiate_version(hv_vmbus_channel_msg_info *msg_info,
- uint32_t version)
+hv_vmbus_negotiate_version(struct vmbus_softc *sc,
+ hv_vmbus_channel_msg_info *msg_info, uint32_t version)
{
int ret = 0;
hv_vmbus_channel_initiate_contact *msg;
@@ -86,14 +86,9 @@
msg->header.message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT;
msg->vmbus_version_requested = version;
- msg->interrupt_page = hv_get_phys_addr(
- hv_vmbus_g_connection.interrupt_page);
-
- msg->monitor_page_1 = hv_get_phys_addr(
- hv_vmbus_g_connection.monitor_page_1);
-
- msg->monitor_page_2 = hv_get_phys_addr(
- hv_vmbus_g_connection.monitor_page_2);
+ msg->interrupt_page = sc->vmbus_evtflags_dma.hv_paddr;
+ msg->monitor_page_1 = sc->vmbus_mnf1_dma.hv_paddr;
+ msg->monitor_page_2 = sc->vmbus_mnf2_dma.hv_paddr;
/**
* Add to list before we send the request since we may receive the
@@ -150,7 +145,7 @@
* Send a connect request on the partition service connection
*/
int
-hv_vmbus_connect(void)
+hv_vmbus_connect(struct vmbus_softc *sc)
{
int ret = 0;
uint32_t version;
@@ -176,34 +171,6 @@
mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel",
NULL, MTX_DEF);
- /**
- * Setup the vmbus event connection for channel interrupt abstraction
- * stuff
- */
- hv_vmbus_g_connection.interrupt_page = malloc(
- PAGE_SIZE, M_DEVBUF,
- M_WAITOK | M_ZERO);
-
- hv_vmbus_g_connection.recv_interrupt_page =
- hv_vmbus_g_connection.interrupt_page;
-
- hv_vmbus_g_connection.send_interrupt_page =
- ((uint8_t *) hv_vmbus_g_connection.interrupt_page +
- (PAGE_SIZE >> 1));
-
- /**
- * Set up the monitor notification facility. The 1st page for
- * parent->child and the 2nd page for child->parent
- */
- hv_vmbus_g_connection.monitor_page_1 = malloc(
- PAGE_SIZE,
- M_DEVBUF,
- M_WAITOK | M_ZERO);
- hv_vmbus_g_connection.monitor_page_2 = malloc(
- PAGE_SIZE,
- M_DEVBUF,
- M_WAITOK | M_ZERO);
-
msg_info = (hv_vmbus_channel_msg_info*)
malloc(sizeof(hv_vmbus_channel_msg_info) +
sizeof(hv_vmbus_channel_initiate_contact),
@@ -217,7 +184,7 @@
version = HV_VMBUS_VERSION_CURRENT;
do {
- ret = hv_vmbus_negotiate_version(msg_info, version);
+ ret = hv_vmbus_negotiate_version(sc, msg_info, version);
if (ret == EWOULDBLOCK) {
/*
* We timed out.
@@ -251,14 +218,6 @@
mtx_destroy(&hv_vmbus_g_connection.channel_lock);
mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock);
- if (hv_vmbus_g_connection.interrupt_page != NULL) {
- free(hv_vmbus_g_connection.interrupt_page, M_DEVBUF);
- hv_vmbus_g_connection.interrupt_page = NULL;
- }
-
- free(hv_vmbus_g_connection.monitor_page_1, M_DEVBUF);
- free(hv_vmbus_g_connection.monitor_page_2, M_DEVBUF);
-
if (msg_info) {
sema_destroy(&msg_info->wait_sema);
free(msg_info, M_DEVBUF);
@@ -281,8 +240,6 @@
ret = hv_vmbus_post_message(&msg, sizeof(hv_vmbus_channel_unload));
- free(hv_vmbus_g_connection.interrupt_page, M_DEVBUF);
-
mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock);
free(hv_vmbus_g_connection.channels, M_DEVBUF);
@@ -343,14 +300,13 @@
}
void
-vmbus_event_proc_compat(struct vmbus_softc *sc __unused, int cpu)
+vmbus_event_proc_compat(struct vmbus_softc *sc, int cpu)
{
struct vmbus_evtflags *eventf;
eventf = VMBUS_PCPU_GET(sc, event_flags, cpu) + VMBUS_SINT_MESSAGE;
if (atomic_testandclear_long(&eventf->evt_flags[0], 0)) {
- vmbus_event_flags_proc(
- hv_vmbus_g_connection.recv_interrupt_page,
+ vmbus_event_flags_proc(sc->vmbus_rx_evtflags,
VMBUS_CHAN_MAX_COMPAT >> VMBUS_EVTFLAG_SHIFT);
}
}
@@ -395,14 +351,14 @@
int
hv_vmbus_set_event(hv_vmbus_channel *channel)
{
+ struct vmbus_softc *sc = vmbus_get_softc();
int ret = 0;
uint32_t child_rel_id = channel->offer_msg.child_rel_id;
/* Each uint32_t represents 32 channels */
synch_set_bit(child_rel_id & 31,
- (((uint32_t *)hv_vmbus_g_connection.send_interrupt_page
- + (child_rel_id >> 5))));
+ (((uint32_t *)sc->vmbus_tx_evtflags + (child_rel_id >> 5))));
ret = hv_vmbus_signal_event(channel->signal_event_param);
return (ret);
Index: sys/dev/hyperv/vmbus/hv_vmbus_priv.h
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -244,25 +244,7 @@
typedef struct {
hv_vmbus_connect_state connect_state;
uint32_t next_gpadl_handle;
- /**
- * Represents channel interrupts. Each bit position
- * represents a channel.
- * When a channel sends an interrupt via VMBUS, it
- * finds its bit in the send_interrupt_page, set it and
- * calls Hv to generate a port event. The other end
- * receives the port event and parse the
- * recv_interrupt_page to see which bit is set
- */
- void *interrupt_page;
- void *send_interrupt_page;
- void *recv_interrupt_page;
- /*
- * 2 pages - 1st page for parent->child
- * notification and 2nd is child->parent
- * notification
- */
- void *monitor_page_1;
- void *monitor_page_2;
+
TAILQ_HEAD(, hv_vmbus_channel_msg_info) channel_msg_anchor;
struct mtx channel_msg_lock;
/**
@@ -440,7 +422,8 @@
/**
* Connection interfaces
*/
-int hv_vmbus_connect(void);
+struct vmbus_softc;
+int hv_vmbus_connect(struct vmbus_softc *);
int hv_vmbus_disconnect(void);
int hv_vmbus_post_message(void *buffer, size_t buf_size);
int hv_vmbus_set_event(hv_vmbus_channel *channel);
Index: sys/dev/hyperv/vmbus/vmbus.c
===================================================================
--- sys/dev/hyperv/vmbus/vmbus.c
+++ sys/dev/hyperv/vmbus/vmbus.c
@@ -309,30 +309,50 @@
static int
vmbus_dma_alloc(struct vmbus_softc *sc)
{
+ bus_dma_tag_t parent_dtag;
+ uint8_t *evtflags;
int cpu;
+ parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
CPU_FOREACH(cpu) {
void *ptr;
/*
* Per-cpu messages and event flags.
*/
- ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
- PAGE_SIZE, 0, PAGE_SIZE,
- VMBUS_PCPU_PTR(sc, message_dma, cpu),
+ ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
+ PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
BUS_DMA_WAITOK | BUS_DMA_ZERO);
if (ptr == NULL)
return ENOMEM;
VMBUS_PCPU_GET(sc, message, cpu) = ptr;
- ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
- PAGE_SIZE, 0, PAGE_SIZE,
- VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
+ ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
+ PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
BUS_DMA_WAITOK | BUS_DMA_ZERO);
if (ptr == NULL)
return ENOMEM;
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
}
+
+ evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
+ PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+ if (evtflags == NULL)
+ return ENOMEM;
+ sc->vmbus_rx_evtflags = (u_long *)evtflags;
+ sc->vmbus_tx_evtflags = evtflags + (PAGE_SIZE / 2);
+ sc->vmbus_evtflags = evtflags;
+
+ sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
+ PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+ if (sc->vmbus_mnf1 == NULL)
+ return ENOMEM;
+
+ sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
+ PAGE_SIZE, &sc->vmbus_mnf2_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+ if (sc->vmbus_mnf2 == NULL)
+ return ENOMEM;
+
return 0;
}
@@ -341,6 +361,21 @@
{
int cpu;
+ if (sc->vmbus_evtflags != NULL) {
+ hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
+ sc->vmbus_evtflags = NULL;
+ sc->vmbus_rx_evtflags = NULL;
+ sc->vmbus_tx_evtflags = NULL;
+ }
+ if (sc->vmbus_mnf1 != NULL) {
+ hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
+ sc->vmbus_mnf1 = NULL;
+ }
+ if (sc->vmbus_mnf2 != NULL) {
+ hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
+ sc->vmbus_mnf2 = NULL;
+ }
+
CPU_FOREACH(cpu) {
if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
hyperv_dmamem_free(
@@ -609,8 +644,7 @@
/*
* Connect to VMBus in the root partition
*/
- ret = hv_vmbus_connect();
-
+ ret = hv_vmbus_connect(sc);
if (ret != 0)
goto cleanup;
Index: sys/dev/hyperv/vmbus/vmbus_var.h
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_var.h
+++ sys/dev/hyperv/vmbus/vmbus_var.h
@@ -51,7 +51,7 @@
struct vmbus_message *message; /* shared messages */
uint32_t vcpuid; /* virtual cpuid */
int event_flags_cnt;/* # of event flags */
- struct vmbus_evtflags *event_flags; /* shared event flags */
+ struct vmbus_evtflags *event_flags; /* event flags from host */
/* Rarely used fields */
struct hyperv_dma message_dma; /* busdma glue */
@@ -63,12 +63,26 @@
struct vmbus_softc {
void (*vmbus_event_proc)(struct vmbus_softc *, int);
+ void *vmbus_tx_evtflags;
+ /* event flags to host */
+ void *vmbus_mnf2; /* monitored by host */
+
+ u_long *vmbus_rx_evtflags;
+ /* compat evtflgs from host */
struct vmbus_pcpu_data vmbus_pcpu[MAXCPU];
/* Rarely used fields */
device_t vmbus_dev;
int vmbus_idtvec;
uint32_t vmbus_flags; /* see VMBUS_FLAG_ */
+
+ /* Shared memory for vmbus_{rx,tx}_evtflags */
+ void *vmbus_evtflags;
+ struct hyperv_dma vmbus_evtflags_dma;
+
+ void *vmbus_mnf1; /* monitored by VM, unused */
+ struct hyperv_dma vmbus_mnf1_dma;
+ struct hyperv_dma vmbus_mnf2_dma;
};
#define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 7:53 AM (6 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30790011
Default Alt Text
D6744.id17374.diff (10 KB)
Attached To
Mode
D6744: hyperv/vmbus: Busdma-fy MNF and event flags.
Attached
Detach File
Event Timeline
Log In to Comment