diff mbox

pci: force minimum mem bar alignment of 64K for board-qemu

Message ID 1488329895-11305-1-git-send-email-mdroth@linux.vnet.ibm.com
State Superseded
Headers show

Commit Message

Michael Roth March 1, 2017, 12:58 a.m. UTC
This is needed to ensure VFIO passthrough devices are able to
offload MMIO accesses to KVM.

Cc: Segher Boessenkool <segher@kernel.crashing.org>
Cc: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 board-qemu/slof/pci-phb.fs |  6 ++++++
 slof/fs/pci-properties.fs  | 32 ++++++++++++++++++++++++++------
 slof/fs/pci-scan.fs        |  3 +++
 3 files changed, 35 insertions(+), 6 deletions(-)

Comments

Segher Boessenkool March 1, 2017, 1:23 a.m. UTC | #1
On Tue, Feb 28, 2017 at 06:58:15PM -0600, Michael Roth wrote:
> +: assign-var-min-align ( size var min-align -- al-mem )
> +        swap >r                         \ ( size min-align )
> +        over                            \ ( size min-align size )
> +        max                             \ ( size align )

Why did you change the UMAX to MAX ?  They are not the same.  Sizes
(and alignments) are unsigned numbers.


Segher
Michael Roth March 2, 2017, 4:42 a.m. UTC | #2
Quoting Segher Boessenkool (2017-02-28 19:23:18)
> On Tue, Feb 28, 2017 at 06:58:15PM -0600, Michael Roth wrote:
> > +: assign-var-min-align ( size var min-align -- al-mem )
> > +        swap >r                         \ ( size min-align )
> > +        over                            \ ( size min-align size )
> > +        max                             \ ( size align )
> 
> Why did you change the UMAX to MAX ?  They are not the same.  Sizes
> (and alignments) are unsigned numbers.

umax wasn't defined in the SLOF environment, and with 64-bit signed values
it didn't seem likely that min-align/size would overflow. But yah,
that's a bit sloppy...

Does the following umax implementation seem reasonable?

0 > : same-sign 0< swap 0< = ;   ok
0 > : umax 2dup same-sign IF max ELSE dup 0< IF swap THEN drop THEN ; ok
0 > 0 0 umax .  0  ok
0 > 0 1 umax .  1  ok
0 > 1 0 umax .  1  ok
0 > 1 1 umax .  1  ok
0 > 70000000 70000000 umax .  70000000  ok
0 > 70000000 80000000 umax .  80000000  ok
0 > 80000000 70000000 umax .  80000000  ok
0 > 80000000 80000000 umax .  80000000  ok
0 > 7000000000000000 7000000000000000 umax .  7000000000000000  ok
0 > 7000000000000000 8000000000000000 umax .  -8000000000000000  ok
0 > 8000000000000000 7000000000000000 umax .  -8000000000000000  ok
0 > 8000000000000000 8000000000000000 umax .  -8000000000000000  ok
0 > ffffffffffffffff fffffffffffffffe umax .  -1  ok
0 > fffffffffffffffe ffffffffffffffff umax .  -1  ok

> 
> 
> Segher
>
Segher Boessenkool March 2, 2017, 9:24 a.m. UTC | #3
On Wed, Mar 01, 2017 at 10:42:13PM -0600, Michael Roth wrote:
> Quoting Segher Boessenkool (2017-02-28 19:23:18)
> > On Tue, Feb 28, 2017 at 06:58:15PM -0600, Michael Roth wrote:
> > > +: assign-var-min-align ( size var min-align -- al-mem )
> > > +        swap >r                         \ ( size min-align )
> > > +        over                            \ ( size min-align size )
> > > +        max                             \ ( size align )
> > 
> > Why did you change the UMAX to MAX ?  They are not the same.  Sizes
> > (and alignments) are unsigned numbers.
> 
> umax wasn't defined in the SLOF environment, and with 64-bit signed values
> it didn't seem likely that min-align/size would overflow. But yah,
> that's a bit sloppy...

Yeah exactly :-)

> Does the following umax implementation seem reasonable?
> 
> 0 > : same-sign 0< swap 0< = ;   ok
> 0 > : umax 2dup same-sign IF max ELSE dup 0< IF swap THEN drop THEN ; ok

Well you can just use  u<  of course.

We have (in engine.in)

: max  2dup < IF swap THEN drop ;

so analogous you get

: umax  2dup u< IF swap THEN drop ;

Cheers,


Segher
diff mbox

Patch

diff --git a/board-qemu/slof/pci-phb.fs b/board-qemu/slof/pci-phb.fs
index 667514e..5289e25 100644
--- a/board-qemu/slof/pci-phb.fs
+++ b/board-qemu/slof/pci-phb.fs
@@ -331,6 +331,12 @@  setup-puid
    my-puid TO puid                  \ Set current puid
    phb-parse-ranges
    1 TO pci-hotplug-enabled
+   s" qemu,mem-bar-min-align" get-node get-property 0<> IF
+       10000 TO pci-mem-bar-min-align   \ Force 64k alignment for all mem BARs
+   ELSE
+       decode-int TO pci-mem-bar-min-align
+       2drop
+   THEN
    s" qemu,phb-enumerated" get-node get-property 0<> IF
        1 0 (probe-pci-host-bridge)
    ELSE
diff --git a/slof/fs/pci-properties.fs b/slof/fs/pci-properties.fs
index 7faa714..01fbc85 100644
--- a/slof/fs/pci-properties.fs
+++ b/slof/fs/pci-properties.fs
@@ -91,16 +91,35 @@ 
 \ ***************************************************************************************
 \ align the current mem and set var to next mem
 \ align with a size of 0 returns 0 !!!
+: assign-var-min-align ( size var min-align -- al-mem )
+        swap >r                         \ ( size min-align )
+        over                            \ ( size min-align size )
+        max                             \ ( size align )
+        r@ @                            \ ( size align cur-mem )  read current free mem
+        swap #aligned                   \ ( size al-mem )         align the mem
+        tuck +                          \ ( al-mem new-mem )      add size to aligned mem
+        r> !                            \ ( al-mem )              set variable to new mem
+;
+
 : assign-var ( size var -- al-mem )
-        2dup @                          \ ( size var size cur-mem ) read current free mem
-        swap #aligned                   \ ( size var al-mem )       align the mem to the size
-        dup 2swap -rot +                \ ( al-mem var new-mem )    add size to aligned mem
-        swap !                          \ ( al-mem )                set variable to new mem
+        0 assign-var-min-align
 ;
 
 \ set bar to current free mem ( in variable ) and set variable to next free mem
 : assign-bar-value32 ( bar size var -- 4 )
         over IF                         \ IF size > 0
+                pci-mem-bar-min-align
+                assign-var-min-align    \ | ( bar al-mem ) set variable to next mem
+                swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
+        ELSE                            \ ELSE
+                2drop drop              \ | clear stack
+        THEN                            \ FI
+        4                               \ size of the base-address-register
+;
+
+\ set bar to current free mem ( in variable ) and set variable to next free mem
+: assign-io-bar-value32 ( bar size var -- 4 )
+        over IF                         \ IF size > 0
                 assign-var              \ | ( bar al-mem ) set variable to next mem
                 swap rtas-config-l!     \ | ( -- )         set the bar to al-mem
         ELSE                            \ ELSE
@@ -112,7 +131,8 @@ 
 \ set bar to current free mem ( in variable ) and set variable to next free mem
 : assign-bar-value64 ( bar size var -- 8 )
         over IF                         \ IF size > 0
-                assign-var              \ | ( bar al-mem ) set variable to next mem
+                pci-mem-bar-min-align
+                assign-var-min-align    \ | ( bar al-mem ) set variable to next mem
                 swap                    \ | ( al-mem addr ) calc config-addr of this bar
                 2dup rtas-config-l!     \ | ( al-mem addr ) set the Lower part of the bar to al-mem
                 4 + swap 20 rshift      \ | ( al-mem>>32 addr ) prepare the upper part of the al-mem
@@ -163,7 +183,7 @@ 
 : assign-io-bar ( bar-addr -- 4 )
         dup pci-bar-size-io             \ fetch size
         pci-next-io                     \ var to change
-        assign-bar-value32              \ and set it all
+        assign-io-bar-value32           \ and set it all
 ;
 
 \ Setup an Expansion ROM bar
diff --git a/slof/fs/pci-scan.fs b/slof/fs/pci-scan.fs
index a528c8e..bd8cc0d 100644
--- a/slof/fs/pci-scan.fs
+++ b/slof/fs/pci-scan.fs
@@ -24,6 +24,9 @@  VARIABLE pci-max-io
 VARIABLE pci-next-mem64           \ prefetchable 64-bit memory mapped
 VARIABLE pci-max-mem64
 
+\ 0 to default to natural alignment
+0 VALUE pci-mem-bar-min-align
+
 \ Counter of busses found
 0 VALUE pci-bus-number
 \ Counter of devices found