On 21/09/2018 10:22, Roman Kagan wrote: > +typedef struct HvSintStagedMesage { > + /* message content staged by hyperv_post_msg */ > + struct hyperv_message msg; > + /* callback + data (r/o) to complete the processing in a BH */ > + HvSintMsgCb cb; > + void *cb_data; > + /* message posting status filled by cpu_post_msg */ > + int status; > + /* passing the buck: */ > + enum { > + /* initial state */ > + HV_STAGED_MSG_FREE, > + /* > + * hyperv_post_msg (e.g. in main loop) grabs the staged area (FREE -> > + * BUSY), copies msg, and schedules cpu_post_msg on the assigned cpu > + */ > + HV_STAGED_MSG_BUSY, > + /* > + * cpu_post_msg (vcpu thread) tries to copy staged msg to msg slot, > + * notify the guest, records the status, marks the posting done (BUSY > + * -> POSTED), and schedules sint_msg_bh BH > + */ > + HV_STAGED_MSG_POSTED, > + /* > + * sint_msg_bh (BH) verifies that the posting is done, runs the > + * callback, and starts over (POSTED -> FREE) > + */ > + } state; > +} HvSintStagedMesage;
s/Mesage/Message/ > + if (atomic_read(&staged_msg->state) != HV_STAGED_MSG_POSTED) { > + /* status nor ready yet (spurious ack from guest?), ignore */ > + return; > + } > + Can this actually happen? It seems scary... Paolo