36
2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation

xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

  • Upload
    others

  • View
    6

  • Download
    1

Embed Size (px)

Citation preview

Page 1: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

2016-11-30 @ BitVisor Summit 5

Ake Koomsin

xHCI Driver Implementation

Page 2: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Agenda

xHCI Overview

Relationship between BitVisor’s host controller

drivers and USB drivers

Implementation Walkthrough

– Changes in BitVisor

2Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 3: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

xHCI Overview

3

Capability

Registers

Operational

Registers

Ext. Capability

Registers 1

Runtime Registers

Doorbell Registers

MMIO Host memory

Event Ring

segment table

Device

ctx base

addr

array

Device ctxTransfer

Ring

Data

buffer

Command ring

Device ctxData

buffer

Data

buffer

Event ring

Transfer

Ring

Page 4: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

xHCI Overview

4

Host memory

Event Ring

segment table

Device ctxTransfer

Ring

Data

buffer

Command ring

Device ctxData

buffer

Data

buffer

Event ring

Transfer

Ring

Index Point to

0 Scratchpad

1 Dev Slot ID 1

2 Dev Slot ID 2

N Dev Slot ID N

Device

ctx base

addr

array

Page 5: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Device ctx

Device ctx

xHCI Overview

5

Host memory

Event Ring

segment table

Device

ctx base

addr

array

Transfer

Ring

Data

buffer

Command ring

Data

buffer

Data

buffer

Event ring

Transfer

Ring

Slot Context

EP 0 BiDir Context

EP 1 OUT Context

EP 1 IN Context

EP 15 Out Context

EP 15 IN Context

Page 6: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Transfer

Ring

Transfer

Ring

xHCI Overview

6

Host memory

Event Ring

segment table

Data

buffer

Data

buffer

Data

buffer

Event ring

TRB

TRB

TRB

TRB

TRB

TRB

Link TRB

TRB

TRB

TRB

TRB

TRB

TRB

Link TRB

Transfer Ring

Segment 0

Transfer Ring

Segment 1

TRB = Transfer Request Block

Page 7: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Event Ring

segment table

Transfer

Ring

Transfer

Ring

xHCI Overview

7

Host memory

Data

buffer

Data

buffer

Data

buffer

Event ring

Ring Segment Base Addr LOW

Ring Segment Base Addr HIGH

Ring Segment Size

051531

En

try 0

Page 8: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

USB Device Initialization

8

Host xHC USB Device1. Attach

2. Port Status

Change Event

3. Enable Command

CMD Comp. EV

4. Addr Dev Command

(BSR = 1)

CMD Comp. EV

5. Prepare TRBs for

GetDescriptor()

Transfer EV

6. Ring the Doorbell Send the request

Response

Block SetAddress() Request

Enabled → Default

Page 9: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

USB Device Initialization

9

Host xHC USB Device

7. Addr Dev Command

(BSR = 0)

CMD Comp. EV

8. Prepare TRBs for

more requests

Transfer EV

9. Ring the Doorbell Send the request

Response

SetAddress()

Default → Addressed

Page 10: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

USB Device Initialization

10

Host xHC USB Device

10. Config Dev Command

CMD Comp. EV

11. Prepare TRBs for

SetConfigure()

Transfer EV

12. Ring the Doorbell Send the request

Response

13. Detach14. Port Status

Change Event

15. Disable Command

CMD Comp. EV

Addressed → Configured

Page 11: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

*HCI Driver & USB Driver

11

USB Driver

USB Driver*HC Driver *HC Driver

Device

Guest OS BitVisor

1

2 3

45

Intercept MMIO Create URBs

+

Process request hooks

Determine URB completion

+

Process reply hooks

Page 12: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

*HCI Driver & USB Driver

*HCI Driver main responsibilities

– Call usb_register_host() and initialize USB drivers

– Construct USB Request Blocks (URBs) from data the guest

OS submits

– Pass URBs to USB Drivers by calling usb_hook_process()

– Host Controller state synchronization

– Provide a method for data shadowing

• Not only data buffer, but also data structures used by the host

controller

12Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 13: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Implementation

13

Capability

Registers

Operational

Registers

Ext. Capability

Registers 1

Runtime Registers

Doorbell Registers

Intercept

MMIO

Shadow

Host memory

Event Ring

segment table

Device

ctx base

addr

array

Device ctxTransfer

Ring

Data

buffer

Command ring

Device ctxData

buffer

Data

buffer

Event ring

Transfer

Ring

Page 14: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Implementation Outline

Intercept Operational Regs and Runtime Regs

– Write : Replace the guest physical addresses

with the host ones

– Read : Return the guest physical addresses

Intercept Doorbell Regs

– Commands (Index 0)

– USB Requests (Index 1 onwards)

Synchronize states when there is an event

14Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 15: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

15

Pointer or data lower bits

Pointer or data upper bits

Status

Type

I

O

C

C

H

I

S

P

C

01531

Type

1. Normal TRB

2. Setup Stage TRB

3. Data Stage TRB

4. Status Stage TRB

5. Isoch TRB

6. Link TRB

7. Event TRB

Data transfer related TRB

Page 16: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

16

Link

Link

TD 1TD 0 TD 2

CH = 1

ISP = 1

TD 3

TD 5TD 4

CH = 1

ISP = 1

CH = 0

IOC = 1

CH = 0

IOC = 1

CH = 1

ISP = 1

CH = 0

IOC = 1

CH = 0

IOC = 0

CH = 1

ISP = 0

CH = 0

IOC = 1

CH = 1

ISP = 1

CH = 1 CH = 0

IOC = 1

Transfer Descriptor (TD)

Page 17: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

URB Construction

One TD = One URB, with exceptions

– USB Request TRBs, (3 TDs, 2 URBs in this example)

– First TRB with not buffer

17Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Setup Data (optional) Status

CH = 0 CH = 0 CH = 0

Link TRB Normal TRB Normal TRB

CH = 0 CH = 1 CH = 0

Page 18: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

18

struct xhci_urb_private {u32 slot_id;u32 ep_no; /* Start from 0 */

u32 start_idx;u32 end_idx;u32 next_td_idx;

u32 start_seg;u32 end_seg;u32 next_td_seg;

u8 start_toggle;u8 end_toggle;u8 next_td_toggle;

u8 event_data_exist;

u32 total_buf_size;

struct usb_buffer_list *ub_tail;

/* For URB completion */struct xhci_trb_meta *intr_tail;struct xhci_trb_meta *intr_list;

/* For TR cloning */struct xhci_trb_meta *link_trb_tail;struct xhci_trb_meta *link_trb_list;

struct xhci_trb *not_success_ev_trb;};

Page 19: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

19

static u8handle_slot_write(...){

...struct usb_request_block *g_urb = construct_gurbs(host,

slot_id, ep_no);

while (g_urb) {struct usb_request_block *h_urb = shadow_g_urb(g_urb);

u8 ret = usb_hook_process(host->usb_host, h_urb,USB_HOOK_REQUEST);

if (ret == USB_HOOK_DISCARD) {...

}

append_h_urb_to_ep(h_urb, host, slot_id, ep_no);...g_urb = g_urb->link_next;

}...return 1;

}

Page 20: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

URB Construction

We don’t know the number of TR segments and TR

segment size at the beginning

– We know only the base address of the first TR segment from

Configure Device Command

– Have to identify TR segment size and number of TR

segments while traversing

– Treat the Link TRB as the end of TR segments

20Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 21: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

21

struct usb_request_block *construct_gurbs(struct xhci_host *host, uint slot_id, uint ep_no){

...do {

...for (i_trb = current_idx; i_trb < n_trbs; i_trb++) {

...switch (type) {

case XHCI_TRB_TYPE_LINK:next_seg = get_next_seg(&g_trbs[i_trb], current_seg,

h_ep_tr, g_ep_tr);... /* Preparing for traversing the next segment */break;

...}...

}} while (!stop);...

}

Page 22: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

URB Construction

22

struct usb_request_block *construct_gurbs(struct xhci_host *host, uint slot_id, uint ep_no){

...do {

...for (i_trb = current_idx; i_trb < n_trbs; i_trb++) {

...if (type == XHCI_TRB_TYPE_LINK) {

/* Stop current scanning to start at the next segment */break;

}

if (i_trb + 1 == n_trbs && type != XHCI_TRB_TYPE_LINK) {g_ep_tr->tr_segs[current_seg].n_trbs *= 2;h_ep_tr->tr_segs[current_seg].n_trbs *= 2;g_ep_tr->current_idx = n_trbs;h_ep_tr->current_idx = n_trbs;

}}

} while (!stop);...

}

Page 23: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

EP Ownership

23

Slot Context

EP 0 BiDir Context

EP 1 OUT Context

EP 1 IN Context

EP 15 Out Context

EP 15 IN Context

Device Context

Transfer

Ring

Transfer

Ring

Problems

– BitVisor needs to

obtain device info

during devive

initialization

– Not all USB drivers

need shadowing

Page 24: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

EP Ownership

BitVisor need to obtain device info during device

initialization

– It needs to own Endpoint 0 to do its job properly

– For xHCI, there is no SetAddress() to intercept for USB

address

• xHC does this for us after receiving the Set Address Command

(BSR = 0)

– Current usb_device_init_monitor() implementation

relies on intercepting SetAddress() response

• This assumption is not valid anymore

– The last interrupter in Runtime Registers is reserved for

BitVisor

• Polling the Event Rings for events

24Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 25: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Changes in BitVisor (1)

Changes in usb_device_init_monitor()

– *HCI drivers are responsible for creating USB hooks for

device monitoring from now

• xHC does this for us after receiving

the Address Device Command (BSR = 0)

Changes in struct usb_hook– Introduce before_callback, after_callback to struct

usb_hook

– Introduce exec_once flag to struct usb_hook

• If exec_once is set, the hook is removed after its execution

25Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 26: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

EP0 Ownership

26

Guest TRB Shadow TRB BitVisor TRB

Guest TR

Shadow TR

If we put our TRBs into the shadow TR, it will make

synchronization much harder

Page 27: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

EP0 Ownership

27

Link

Link

BitVisor TR

Jump to a dedicated TR owned BitVisor only, and

jump back the original position

Page 28: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

EP Ownership

Not all USB drivers need shadowing

– Let BitVisor owns all EPs at the beginning

– A USB Driver must tell xHCI driver that it is going to own the

device

– If no USB driver claims the slot, put a Link TRB pointing to the

guest Transfer Ring when the guest starts sending a request

that is not EP 0

28Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

EP 1 IN Context

Link

Shadow TRB

Guest TRB

Page 29: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Changes in BitVisor (2)

Changes in struct usb_operations– Implement will_take_ctrl()

• It takes a USB host object, and a USB device object as its

arguments

USB Drivers

– Need to explicitly tells *HCI drivers if it needs to take control

a device by calling usbhc->op->will_take_control()

29Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 30: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

State Synchronization

Two things to do

– Device Context copyback

• Both Slot Context and EP contexts

• Replace the host pointer addresses with the guest ones

– Event Ring copyback

30Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 31: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

State Synchronization

31

voidclone_er_trbs_to_guest(struct xhci_host *host){

...for (i = 0; i < host->usable_intrs; i++) {

...do {

...for (i_trb = start_idx; i_trb < n_trbs; i_trb++) {

toggle = XHCI_TRB_GET_C(&h_trbs[i_trb]);if (toggle == current_toggle) {

handle_ev_trb(host, &h_trbs[i_trb]);} else {

...}

}...memcpy(&g_trbs[start_idx], &h_trbs[start_idx],

(i_trb - start_idx + 1) * XHCI_TRB_NBYTES);} while (!stop);

}}

Page 32: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

State Synchronization

32

static voidhandle_ev_trb(struct xhci_host *host, struct xhci_trb *h_ev_trb){

...switch (type) {

...case XHCI_TRB_TYPE_TX_EV:

slot_id = XHCI_EV_GET_SLOT_ID(h_ev_trb);ep_no = XHCI_EV_GET_EP_NO(h_ev_trb);

process_tx_ev(host, h_ev_trb);

if (ep_no != 0 &&host->slot_meta[slot_id].host_ctrl == HOST_CTRL_NO) {break;

}

patch_tx_ev_trb(host, h_ev_trb);break;

...}

}

Page 33: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

State Synchronization

33

static voidprocess_tx_ev(struct xhci_host *host, struct xhci_trb *h_ev_trb){

... /* Get h_urb list to find the target h_urb */

... /* Process all h_urbs that exist before */u8 is_last_intr = check_last_intr(h_urb, h_ev_trb, &trb_code);...if (is_last_intr) {

if (h_urb->shadow->buffers) {int res = usb_hook_process(host->usb_host,

h_urb, USB_HOOK_REPLY);

if (res == USB_HOOK_DISCARD) {...

}}

remove_h_urb_head_from_ep(host, slot_id, ep_no);

delete_urb_xhci(h_urb->shadow);delete_urb_xhci(h_urb);

}}

Page 34: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

State Synchronization

When to synchronize status?

– It is possible to check for OPR.USBSTS access for events

– Unfortunately, it is not a requirement. Linux writes to this

register, but Windows occasionally reads it only

– We have to intercept interrupts

34Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 35: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Changes in BitVisor (3)

Intercepting interrupts

– Every external interrupts cause VM_EXIT events

– Implement exint_pass_intr_register_callback()

– Implement pci_register_intr_callback()

• It calls exint_pass_intr_register_callback() internally

– xHCI driver calls pci_register_intr_callback() for

registering its state synchronization callback

35Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.

Page 36: xHCI Driver Implementation - bitvisor.org · 2016-11-30 @ BitVisor Summit 5 Ake Koomsin xHCI Driver Implementation. Agenda xHCI Overview Relationship between BitVisor’shost controller

Summary

xHCI Overview

– Registers, data structures, and operational model

Relationship between BitVisor’s host controller

drivers and USB Drivers

– *HCI driver responsibilities

xHCI Driver implementation

– Implementation walkthrough

– Changes in BitVisor

36Copyright© 2016 IGEL Co., Ltd. All Rights Reserved.