diff --git a/drivers/virtio.cc b/drivers/virtio.cc
index cb31bb80838db90f8be4db9b14844c328612425c..3de066c112ed68005d9f2f6083bccec8fce245ab 100644
--- a/drivers/virtio.cc
+++ b/drivers/virtio.cc
@@ -35,6 +35,12 @@ Virtio::Init(Device* dev) {
     _bars[0]->write(VIRTIO_PCI_STATUS, (u8)(VIRTIO_CONFIG_S_ACKNOWLEDGE |
             VIRTIO_CONFIG_S_DRIVER));
 
+    probe_virt_queues();
+
+    for (int i=0;i<32;i++)
+        debug(fmt("%d:%d ") % i % get_device_feature_bit(i), false);
+    debug(fmt("\n"), false);
+
     _bars[0]->write(VIRTIO_PCI_STATUS, (u8)(VIRTIO_CONFIG_S_DRIVER_OK));
 
     return true;
@@ -75,3 +81,50 @@ Virtio::vring_need_event(u16 event_idx, u16 new_idx, u16 old) {
     return (u16)(new_idx - event_idx - 1) < (u16)(new_idx - old);
 }
 
+bool
+Virtio::get_device_feature_bit(int bit) {
+    u32 features = _bars[0]->read(VIRTIO_PCI_HOST_FEATURES);
+    return bool(features & (1 << bit));
+}
+
+void
+Virtio::set_guest_feature_bit(int bit, bool on) {
+    u32 features = _bars[0]->read(VIRTIO_PCI_GUEST_FEATURES);
+    features = (on)? features | (1 << bit) : features & ~(1 << bit);
+    _bars[0]->write(VIRTIO_PCI_GUEST_FEATURES, features);
+}
+
+void
+Virtio::set_guest_features(u32 features) {
+    _bars[0]->write(VIRTIO_PCI_GUEST_FEATURES, features);
+}
+
+void
+Virtio::pci_conf_write(int offset, void* buf, int length) {
+    u8* ptr = reinterpret_cast<u8*>(buf);
+    for (int i=0;i<length;i++)
+        _bars[0]->write(offset, ptr[i]);
+}
+
+void
+Virtio::pci_conf_read(int offset, void* buf, int length) {
+    unsigned char* ptr = reinterpret_cast<unsigned char*>(buf);
+    for (int i=0;i<length;i++)
+        ptr[i] = _bars[0]->readb(offset);
+
+}
+
+void
+Virtio::probe_virt_queues() {
+    u16 queuesel = 0;
+    u16 qsize;
+
+    do {
+        pci_conf_write(VIRTIO_PCI_QUEUE_SEL, &queuesel, sizeof(queuesel));
+        pci_conf_read(VIRTIO_PCI_QUEUE_NUM, &qsize, sizeof(qsize));
+        debug(fmt("queue %d, size %d") % queuesel % qsize);
+
+        if (!qsize) break;
+        queuesel++;
+    } while (1);
+}
diff --git a/drivers/virtio.hh b/drivers/virtio.hh
index ece9f9c3b796beddba4003185fff378d83780a86..b794dc80b1a147794d714d880423a7ae8c3f9b1f 100644
--- a/drivers/virtio.hh
+++ b/drivers/virtio.hh
@@ -194,6 +194,14 @@ protected:
     unsigned vring_size(unsigned int num, unsigned long align);
     int vring_need_event(u16 event_idx, u16 new_idx, u16 old);
 
+    virtual bool get_device_feature_bit(int bit);
+    virtual void set_guest_feature_bit(int bit, bool on);
+    virtual void set_guest_features(u32 features);
+    void pci_conf_read(int offset, void* buf, int length);
+    void pci_conf_write(int offset, void* buf, int length);
+
+    void probe_virt_queues();
+
 private:
 };