Merge tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyper...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Sep 2019 19:36:31 +0000 (12:36 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Sep 2019 19:36:31 +0000 (12:36 -0700)
Pull Hyper-V updates from Sasha Levin:

 - first round of vmbus hibernation support (Dexuan Cui)

 - remove dependencies on PAGE_SIZE (Maya Nakamura)

 - move the hyper-v tools/ code into the tools build system (Andy
   Shevchenko)

 - hyper-v balloon cleanups (Dexuan Cui)

* tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  Drivers: hv: vmbus: Resume after fixing up old primary channels
  Drivers: hv: vmbus: Suspend after cleaning up hv_sock and sub channels
  Drivers: hv: vmbus: Clean up hv_sock channels by force upon suspend
  Drivers: hv: vmbus: Suspend/resume the vmbus itself for hibernation
  Drivers: hv: vmbus: Ignore the offers when resuming from hibernation
  Drivers: hv: vmbus: Implement suspend/resume for VSC drivers for hibernation
  Drivers: hv: vmbus: Add a helper function is_sub_channel()
  Drivers: hv: vmbus: Suspend/resume the synic for hibernation
  Drivers: hv: vmbus: Break out synic enable and disable operations
  HID: hv: Remove dependencies on PAGE_SIZE for ring buffer
  Tools: hv: move to tools buildsystem
  hv_balloon: Reorganize the probe function
  hv_balloon: Use a static page for the balloon_up send buffer

1  2 
drivers/hv/hyperv_vmbus.h
include/linux/hyperv.h

index 50eaa1fd6e4599b43bf07dfa3408eff0b9f4562b,f7a5f5615f34cb47b116fbcc2e5f82b40b40d8bd..af9379a3bf8990fa5ee68f5f0fbddd9391eab3c2
@@@ -146,6 -146,8 +146,6 @@@ struct hv_context 
         */
        u64 guestid;
  
 -      void *tsc_page;
 -
        struct hv_per_cpu_context __percpu *cpu_context;
  
        /*
@@@ -169,8 -171,10 +169,10 @@@ extern int hv_synic_alloc(void)
  
  extern void hv_synic_free(void);
  
+ extern void hv_synic_enable_regs(unsigned int cpu);
  extern int hv_synic_init(unsigned int cpu);
  
+ extern void hv_synic_disable_regs(unsigned int cpu);
  extern int hv_synic_cleanup(unsigned int cpu);
  
  /* Interface */
@@@ -190,11 -194,11 +192,11 @@@ int hv_ringbuffer_read(struct vmbus_cha
                       u64 *requestid, bool raw);
  
  /*
 - * 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
 + * The Maximum number of channels (16348) is determined by the size of the
 + * interrupt page, which is HV_HYP_PAGE_SIZE. 1/2 of HV_HYP_PAGE_SIZE is to
 + * send endpoint interrupts, and the other is to receive endpoint interrupts.
   */
 -#define MAX_NUM_CHANNELS      ((PAGE_SIZE >> 1) << 3) /* 16348 channels */
 +#define MAX_NUM_CHANNELS      ((HV_HYP_PAGE_SIZE >> 1) << 3)
  
  /* The value here must be in multiple of 32 */
  /* TODO: Need to make this configurable */
@@@ -256,6 -260,32 +258,32 @@@ struct vmbus_connection 
        struct workqueue_struct *work_queue;
        struct workqueue_struct *handle_primary_chan_wq;
        struct workqueue_struct *handle_sub_chan_wq;
+       /*
+        * The number of sub-channels and hv_sock channels that should be
+        * cleaned up upon suspend: sub-channels will be re-created upon
+        * resume, and hv_sock channels should not survive suspend.
+        */
+       atomic_t nr_chan_close_on_suspend;
+       /*
+        * vmbus_bus_suspend() waits for "nr_chan_close_on_suspend" to
+        * drop to zero.
+        */
+       struct completion ready_for_suspend_event;
+       /*
+        * The number of primary channels that should be "fixed up"
+        * upon resume: these channels are re-offered upon resume, and some
+        * fields of the channel offers (i.e. child_relid and connection_id)
+        * can change, so the old offermsg must be fixed up, before the resume
+        * callbacks of the VSC drivers start to further touch the channels.
+        */
+       atomic_t nr_chan_fixup_on_resume;
+       /*
+        * vmbus_bus_resume() waits for "nr_chan_fixup_on_resume" to
+        * drop to zero.
+        */
+       struct completion ready_for_resume_event;
  };
  
  
@@@ -270,6 -300,8 +298,8 @@@ struct vmbus_msginfo 
  
  extern struct vmbus_connection vmbus_connection;
  
+ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version);
  static inline void vmbus_send_interrupt(u32 relid)
  {
        sync_set_bit(relid, vmbus_connection.send_int_page);
diff --combined include/linux/hyperv.h
index 2afe6fdc1ddadc9e5b9b91bf75921d015d85f51c,a3aa9e9ef6f23d6c491b169b8f6a4fc445ebbe7f..b4a017093b697e615b6850860f9d58a8ed65193c
@@@ -245,7 -245,10 +245,10 @@@ struct vmbus_channel_offer 
                } pipe;
        } u;
        /*
-        * The sub_channel_index is defined in win8.
+        * The sub_channel_index is defined in Win8: a value of zero means a
+        * primary channel and a value of non-zero means a sub-channel.
+        *
+        * Before Win8, the field is reserved, meaning it's always zero.
         */
        u16 sub_channel_index;
        u16 reserved3;
@@@ -423,6 -426,9 +426,9 @@@ enum vmbus_channel_message_type 
        CHANNELMSG_COUNT
  };
  
+ /* Hyper-V supports about 2048 channels, and the RELIDs start with 1. */
+ #define INVALID_RELID U32_MAX
  struct vmbus_channel_message_header {
        enum vmbus_channel_message_type msgtype;
        u32 padding;
@@@ -934,6 -940,11 +940,11 @@@ static inline bool is_hvsock_channel(co
                  VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER);
  }
  
+ static inline bool is_sub_channel(const struct vmbus_channel *c)
+ {
+       return c->offermsg.offer.sub_channel_index != 0;
+ }
  static inline void set_channel_affinity_state(struct vmbus_channel *c,
                                              enum hv_numa_policy policy)
  {
@@@ -1149,6 -1160,9 +1160,9 @@@ struct hv_driver 
        int (*remove)(struct hv_device *);
        void (*shutdown)(struct hv_device *);
  
+       int (*suspend)(struct hv_device *);
+       int (*resume)(struct hv_device *);
  };
  
  /* Base device object */
@@@ -1578,33 -1592,4 +1592,33 @@@ hv_pkt_iter_next(struct vmbus_channel *
        for (pkt = hv_pkt_iter_first(channel); pkt; \
            pkt = hv_pkt_iter_next(channel, pkt))
  
 +/*
 + * Interface for passing data between SR-IOV PF and VF drivers. The VF driver
 + * sends requests to read and write blocks. Each block must be 128 bytes or
 + * smaller. Optionally, the VF driver can register a callback function which
 + * will be invoked when the host says that one or more of the first 64 block
 + * IDs is "invalid" which means that the VF driver should reread them.
 + */
 +#define HV_CONFIG_BLOCK_SIZE_MAX 128
 +
 +int hyperv_read_cfg_blk(struct pci_dev *dev, void *buf, unsigned int buf_len,
 +                      unsigned int block_id, unsigned int *bytes_returned);
 +int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len,
 +                       unsigned int block_id);
 +int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context,
 +                              void (*block_invalidate)(void *context,
 +                                                       u64 block_mask));
 +
 +struct hyperv_pci_block_ops {
 +      int (*read_block)(struct pci_dev *dev, void *buf, unsigned int buf_len,
 +                        unsigned int block_id, unsigned int *bytes_returned);
 +      int (*write_block)(struct pci_dev *dev, void *buf, unsigned int len,
 +                         unsigned int block_id);
 +      int (*reg_blk_invalidate)(struct pci_dev *dev, void *context,
 +                                void (*block_invalidate)(void *context,
 +                                                         u64 block_mask));
 +};
 +
 +extern struct hyperv_pci_block_ops hvpci_block_ops;
 +
  #endif /* _HYPERV_H */