RE: [PATCH net 1/2] r8152: fix the sw rx checksum is unavailable

2017-01-08 Thread Hayes Wang
Ansis Atteka [mailto:aatt...@nicira.com]
> Sent: Tuesday, January 03, 2017 8:41 AM
[...]
> Hayes, in your iperf reproduction environment did you
> 1) connect sender and receiver directly with an Ethernet cable?
> 2) use iperf's TCP mode instead of UDP mode, because I believe that
> with UDP mode packets are more likely to be sparsely distributed?
> Also, this bug is way easier to reproduce when IP fragmentation kicks
> in because IP fragments are typically sent out very close to each
> other.
> 3) were you plugging your USB Ethernet dongle in USB 3.0 port or
> whatever Mark was using? It seems that each USB mode has different
> coalesce parameters and yours might have work "out of box"?

Yes. I connect them directly and use iperf's TCP mode. However,
I test the RTL8152 which only support USB 2.0. Therefore, I don't
think it occurs with different coalesce parameters.

> While I would not call this a proper fix, because it simply reduces
> coalescing timeouts by order of 10X and most likely does not eliminate
> security aspects of the bug, it at least made my system functionally
> stable and I don't see either of those two bugs in my setup anymore:

Do you try commit a59e6d815226 ("r8152: correct the rx early size"),
or you have used it?

Best Regards,
Hayes



Re: Linux 4.4.41

2017-01-08 Thread Greg KH
diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 092ee9fbaf2b..df8ab4fc240a 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1991,6 +1991,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TM_VSCR   | 32
   PPC   | KVM_REG_PPC_TM_DSCR   | 64
   PPC   | KVM_REG_PPC_TM_TAR| 64
+  PPC   | KVM_REG_PPC_TM_XER| 64
 |   |
   MIPS  | KVM_REG_MIPS_R0   | 64
   ...
diff --git a/Makefile b/Makefile
index 5b5937780408..855e71066174 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 40
+SUBLEVEL = 41
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
diff --git a/arch/arc/include/asm/cacheflush.h 
b/arch/arc/include/asm/cacheflush.h
index fbe3587c4f36..56aeb5efe604 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma,
  */
 #define PG_dc_cleanPG_arch_1
 
+#define CACHE_COLORS_NUM   4
+#define CACHE_COLORS_MSK   (CACHE_COLORS_NUM - 1)
+#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 
CACHE_COLORS_MSK)
+
 /*
  * Simple wrapper over config option
  * Bootup code ensures that hardware matches kernel configuration
@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void)
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
 }
 
-#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
-
 /*
  * checks if two addresses (after page aligning) index into same cache set
  */
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index aaf1e2d1d900..d81b6d7e11e7 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -960,11 +960,16 @@ void arc_cache_init(void)
/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
if (is_isa_arcompact()) {
int handled = 
IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
-
-   if (dc->alias && !handled)
-   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
-   else if (!dc->alias && handled)
+   int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE);
+
+   if (dc->alias) {
+   if (!handled)
+   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   if (CACHE_COLORS_NUM != num_colors)
+   panic("CACHE_COLORS_NUM not optimized 
for config\n");
+   } else if (!dc->alias && handled) {
panic("Disable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   }
}
}
 
diff --git a/arch/powerpc/boot/ps3-head.S b/arch/powerpc/boot/ps3-head.S
index b6fcbaf5027b..3dc44b05fb97 100644
--- a/arch/powerpc/boot/ps3-head.S
+++ b/arch/powerpc/boot/ps3-head.S
@@ -57,11 +57,6 @@ __system_reset_overlay:
bctr
 
 1:
-   /* Save the value at addr zero for a null pointer write check later. */
-
-   li  r4, 0
-   lwz r3, 0(r4)
-
/* Primary delays then goes to _zimage_start in wrapper. */
 
or  31, 31, 31 /* db16cyc */
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c
index 4ec2d86d3c50..a05558a7e51a 100644
--- a/arch/powerpc/boot/ps3.c
+++ b/arch/powerpc/boot/ps3.c
@@ -119,13 +119,12 @@ void ps3_copy_vectors(void)
flush_cache((void *)0x100, 512);
 }
 
-void platform_init(unsigned long null_check)
+void platform_init(void)
 {
const u32 heapsize = 0x100 - (u32)_end; /* 16MiB */
void *chosen;
unsigned long ft_addr;
u64 rm_size;
-   unsigned long val;
 
console_ops.write = ps3_console_write;
platform_ops.exit = ps3_exit;
@@ -153,11 +152,6 @@ void platform_init(unsigned long null_check)
 
printf(" flat tree at 0x%lx\n\r", ft_addr);
 
-   val = *(unsigned long *)0;
-
-   if (val != null_check)
-   printf("null check failed: %lx != %lx\n\r", val, null_check);
-
((kernel_entry_t)0)(ft_addr, 0, NULL);
 
ps3_exit();
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index cfa758c6b4f6..a92d95aee42d 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -545,6 +545,7 @@ struct kvm_vcpu_arch {
u64 tfiar;
 
u32 cr_tm;
+   u64 xer_tm;
u64 lr_tm;
u64 ctr_tm;
u64 amr_tm;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h 
b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d4732c492..720b71a636c8 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -587,6 +587,7 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_TM_VSCR(KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)

Re: Linux 4.8.17

2017-01-08 Thread Greg KH
diff --git a/Documentation/sphinx/rstFlatTable.py 
b/Documentation/sphinx/rstFlatTable.py
index 26db852e3c74..99163598f18b 100644
--- a/Documentation/sphinx/rstFlatTable.py
+++ b/Documentation/sphinx/rstFlatTable.py
@@ -151,6 +151,11 @@ class ListTableBuilder(object):
 def buildTableNode(self):
 
 colwidths= self.directive.get_column_widths(self.max_cols)
+if isinstance(colwidths, tuple):
+# Since docutils 0.13, get_column_widths returns a (widths,
+# colwidths) tuple, where widths is a string (i.e. 'auto').
+# See https://sourceforge.net/p/docutils/patches/120/.
+colwidths = colwidths[1]
 stub_columns = self.directive.options.get('stub-columns', 0)
 header_rows  = self.directive.options.get('header-rows', 0)
 
diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 739db9ab16b2..a7596e9fdf06 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2039,6 +2039,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TM_VSCR   | 32
   PPC   | KVM_REG_PPC_TM_DSCR   | 64
   PPC   | KVM_REG_PPC_TM_TAR| 64
+  PPC   | KVM_REG_PPC_TM_XER| 64
 |   |
   MIPS  | KVM_REG_MIPS_R0   | 64
   ...
diff --git a/Makefile b/Makefile
index 50f68648a79a..ace32d3bac4b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 8
-SUBLEVEL = 16
+SUBLEVEL = 17
 EXTRAVERSION =
 NAME = Psychotic Stoned Sheep
 
diff --git a/arch/arc/include/asm/cacheflush.h 
b/arch/arc/include/asm/cacheflush.h
index a093adbdb017..fc662f49c55a 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma,
  */
 #define PG_dc_cleanPG_arch_1
 
+#define CACHE_COLORS_NUM   4
+#define CACHE_COLORS_MSK   (CACHE_COLORS_NUM - 1)
+#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 
CACHE_COLORS_MSK)
+
 /*
  * Simple wrapper over config option
  * Bootup code ensures that hardware matches kernel configuration
@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void)
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
 }
 
-#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
-
 /*
  * checks if two addresses (after page aligning) index into same cache set
  */
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index 0b10efe3a6a7..ab1aaf2a28c8 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -967,11 +967,16 @@ void arc_cache_init(void)
/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
if (is_isa_arcompact()) {
int handled = 
IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
-
-   if (dc->alias && !handled)
-   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
-   else if (!dc->alias && handled)
+   int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE);
+
+   if (dc->alias) {
+   if (!handled)
+   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   if (CACHE_COLORS_NUM != num_colors)
+   panic("CACHE_COLORS_NUM not optimized 
for config\n");
+   } else if (!dc->alias && handled) {
panic("Disable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   }
}
}
 
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
index 5fda583351d7..906fb836d241 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
@@ -21,6 +21,10 @@
reg = <0x0 0x8000 0x1 0x0>;
};
 
+   gpu@5700 {
+   vdd-supply = <&vdd_gpu>;
+   };
+
/* debug port */
serial@70006000 {
status = "okay";
@@ -291,4 +295,18 @@
clock-frequency = <32768>;
};
};
+
+   regulators {
+   vdd_gpu: regulator@100 {
+   compatible = "pwm-regulator";
+   reg = <100>;
+   pwms = <&pwm 1 4880>;
+   regulator-name = "VDD_GPU";
+   regulator-min-microvolt = <71>;
+   regulator-max-microvolt = <132>;
+   enable-gpios = <&pmic 6 GPIO_ACTIVE_HIGH>;
+   regulator-ramp-delay = <80>;
+   regulator-enable-ramp-delay = <1000>;
+   };
+   };
 };
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 5a84b4562603..03498c8f0cf7 100644
--- a/a

Linux 4.4.41

2017-01-08 Thread Greg KH
I'm announcing the release of the 4.4.41 kernel.

All users of the 4.4 kernel series must upgrade.

The updated 4.4.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 
linux-4.4.y
and can be browsed at the normal kernel.org git web browser:

http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary

thanks,

greg k-h



 Documentation/virtual/kvm/api.txt  |1 
 Makefile   |2 
 arch/arc/include/asm/cacheflush.h  |6 -
 arch/arc/mm/cache.c|   13 ++-
 arch/powerpc/boot/ps3-head.S   |5 -
 arch/powerpc/boot/ps3.c|8 -
 arch/powerpc/include/asm/kvm_host.h|1 
 arch/powerpc/include/uapi/asm/kvm.h|1 
 arch/powerpc/kernel/asm-offsets.c  |1 
 arch/powerpc/kernel/idle_power7.S  |2 
 arch/powerpc/kvm/book3s_hv.c   |6 +
 arch/powerpc/kvm/book3s_hv_rm_mmu.c|2 
 arch/powerpc/kvm/book3s_hv_rmhandlers.S|4 
 arch/x86/entry/entry_32.S  |4 
 arch/x86/kvm/vmx.c |   11 +-
 block/bsg.c|3 
 drivers/acpi/video_detect.c|   20 
 drivers/base/firmware_class.c  |7 -
 drivers/clk/bcm/clk-bcm2835.c  |4 
 drivers/gpu/drm/ast/ast_main.c |7 +
 drivers/gpu/drm/gma500/psb_drv.c   |3 
 drivers/gpu/drm/nouveau/nouveau_bios.c |3 
 drivers/gpu/drm/nouveau/nvkm/engine/device/base.c  |4 
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c |9 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c |8 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h|1 
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c  |7 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c  |1 
 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c |2 
 drivers/gpu/drm/radeon/radeon_cursor.c |   69 +++--
 drivers/gpu/drm/radeon/radeon_mode.h   |1 
 drivers/gpu/drm/radeon/si_dpm.c|1 
 drivers/infiniband/core/mad.c  |2 
 drivers/infiniband/core/multicast.c|7 +
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |7 +
 drivers/input/misc/drv260x.c   |1 
 drivers/md/raid5.c |9 ++
 drivers/media/pci/solo6x10/solo6x10.h  |3 
 drivers/misc/mei/client.c  |2 
 drivers/mmc/host/sdhci.c   |   20 
 drivers/net/ethernet/marvell/mvpp2.c   |   59 +++---
 drivers/net/wireless/ath/ath9k/pci.c   |7 +
 drivers/net/wireless/realtek/rtlwifi/base.c|8 -
 drivers/net/wireless/realtek/rtlwifi/core.c|9 --
 drivers/net/wireless/realtek/rtlwifi/pci.c |   14 +--
 drivers/net/wireless/realtek/rtlwifi/ps.c  |   36 ++--
 drivers/pci/pci.c  |4 
 drivers/platform/x86/asus-nb-wmi.c |9 ++
 drivers/regulator/stw481x-vmmc.c   |3 
 drivers/s390/char/vmlogrdr.c   |2 
 drivers/s390/scsi/zfcp_dbf.c   |   17 +++-
 drivers/s390/scsi/zfcp_dbf.h   |   41 +-
 drivers/s390/scsi/zfcp_erp.c   |   61 ++-
 drivers/s390/scsi/zfcp_ext.h   |4 
 drivers/s390/scsi/zfcp_fsf.h   |3 
 drivers/s390/scsi/zfcp_reqlist.h   |   30 +++
 drivers/s390/scsi/zfcp_scsi.c  |   61 +--
 drivers/scsi/megaraid/megaraid_sas_fusion.c|9 +-
 drivers/scsi/scsi_sysfs.c  |4 
 drivers/scsi/sg.c  |3 
 drivers/ssb/pci.c  |1 
 drivers/staging/comedi/drivers/ni_mio_common.c |8 -
 drivers/target/target_core_user.c  |2 
 drivers/thermal/thermal_hwmon.c|2 
 drivers/tty/serial/sc16is7xx.c |2 
 drivers/tty/vt/keyboard.c  |2 
 fs/block_dev.c |7 +
 fs/nfs/file.c  |2 
 include/net/cfg80211.h |   11 ++
 include/rdma/ib_addr.h 

Linux 4.8.17

2017-01-08 Thread Greg KH
I'm announcing the release of the 4.8.17 kernel.

--
NOTE, this is the LAST 4.8-stable kernel to be released.  This tree is
now end-of-life.  Please move to the 4.9-stable tree.  If there are any
reasons preventing you from doing this, please let me know.
--

All users of the 4.8 kernel series must upgrade.

The updated 4.8.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 
linux-4.8.y
and can be browsed at the normal kernel.org git web browser:

http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary

thanks,

greg k-h



 Documentation/sphinx/rstFlatTable.py   |5 +
 Documentation/virtual/kvm/api.txt  |1 
 Makefile   |2 
 arch/arc/include/asm/cacheflush.h  |6 -
 arch/arc/mm/cache.c|   13 ++-
 arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi |   18 
 arch/arm64/kvm/hyp/switch.c|8 +
 arch/powerpc/boot/ps3-head.S   |5 -
 arch/powerpc/boot/ps3.c|8 -
 arch/powerpc/include/asm/kvm_host.h|1 
 arch/powerpc/include/uapi/asm/kvm.h|1 
 arch/powerpc/kernel/asm-offsets.c  |1 
 arch/powerpc/kernel/head_64.S  |8 -
 arch/powerpc/kvm/book3s_hv.c   |6 +
 arch/powerpc/kvm/book3s_hv_rm_mmu.c|2 
 arch/powerpc/kvm/book3s_hv_rmhandlers.S|4 
 arch/s390/kernel/setup.c   |2 
 arch/x86/entry/entry_32.S  |4 
 arch/x86/events/core.c |8 +
 arch/x86/events/intel/cstate.c |   14 +--
 arch/x86/events/perf_event.h   |2 
 arch/x86/kvm/vmx.c |   11 +-
 block/bsg.c|3 
 drivers/acpi/video_detect.c|   20 
 drivers/base/firmware_class.c  |7 -
 drivers/clk/bcm/clk-bcm2835.c  |4 
 drivers/gpio/gpiolib.c |5 -
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c  |   26 +++---
 drivers/gpu/drm/ast/ast_main.c |7 +
 drivers/gpu/drm/gma500/psb_drv.c   |3 
 drivers/gpu/drm/i915/i915_gem_stolen.c |5 -
 drivers/gpu/drm/i915/intel_display.c   |9 +-
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |3 
 drivers/gpu/drm/i915/intel_runtime_pm.c|   13 ++-
 drivers/gpu/drm/nouveau/nouveau_bios.c |3 
 drivers/gpu/drm/nouveau/nouveau_bo.c   |1 
 drivers/gpu/drm/nouveau/nvkm/engine/device/base.c  |6 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c |9 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c |8 +
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c |   50 +++-
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h|1 
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c  |7 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c  |1 
 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c |2 
 drivers/gpu/drm/radeon/radeon_cursor.c |   69 +++--
 drivers/gpu/drm/radeon/radeon_mode.h   |1 
 drivers/gpu/drm/radeon/si.c|1 
 drivers/gpu/drm/radeon/si_dpm.c|1 
 drivers/hv/channel_mgmt.c  |2 
 drivers/hwtracing/stm/core.c   |8 +
 drivers/infiniband/core/mad.c  |2 
 drivers/infiniband/core/multicast.c|7 +
 drivers/infiniband/hw/i40iw/i40iw_verbs.c  |2 
 drivers/infiniband/sw/rxe/rxe_qp.c |1 
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |7 +
 drivers/input/misc/drv260x.c   |1 
 drivers/md/raid5.c |9 ++
 drivers/media/dvb-frontends/mn88472.c  |   24 ++---
 drivers/media/dvb-frontends/mn88473.c  |   24 ++---
 drivers/media/i2c/tvp5150.c|1 
 drivers/media/pci/solo6x10/solo6x10.h  |3 
 drivers/media/platform/s5p-mfc/s5p_mfc.c   |1 
 drivers/misc/mei/client.c  |2 
 drivers/misc/mei/hw-me-regs.h  |2 
 drivers/misc/mei/pci-me.c  |1 
 drivers/mmc/host/sdhci.c   |   20 
 drivers/net/ethernet/marv

Re: Linux 4.9.2

2017-01-08 Thread Greg KH
diff --git a/Documentation/sphinx/rstFlatTable.py 
b/Documentation/sphinx/rstFlatTable.py
index 55f275793028..25feb0d35e7a 100755
--- a/Documentation/sphinx/rstFlatTable.py
+++ b/Documentation/sphinx/rstFlatTable.py
@@ -157,6 +157,11 @@ class ListTableBuilder(object):
 def buildTableNode(self):
 
 colwidths= self.directive.get_column_widths(self.max_cols)
+if isinstance(colwidths, tuple):
+# Since docutils 0.13, get_column_widths returns a (widths,
+# colwidths) tuple, where widths is a string (i.e. 'auto').
+# See https://sourceforge.net/p/docutils/patches/120/.
+colwidths = colwidths[1]
 stub_columns = self.directive.options.get('stub-columns', 0)
 header_rows  = self.directive.options.get('header-rows', 0)
 
diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 6bbceb9a3a19..1f5eab4ef88f 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2050,6 +2050,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_TM_VSCR   | 32
   PPC   | KVM_REG_PPC_TM_DSCR   | 64
   PPC   | KVM_REG_PPC_TM_TAR| 64
+  PPC   | KVM_REG_PPC_TM_XER| 64
 |   |
   MIPS  | KVM_REG_MIPS_R0   | 64
   ...
diff --git a/Makefile b/Makefile
index ab3cd5128889..c9ce897465c5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 1
+SUBLEVEL = 2
 EXTRAVERSION =
 NAME = Roaring Lionus
 
diff --git a/arch/arc/include/asm/cacheflush.h 
b/arch/arc/include/asm/cacheflush.h
index a093adbdb017..fc662f49c55a 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma,
  */
 #define PG_dc_cleanPG_arch_1
 
+#define CACHE_COLORS_NUM   4
+#define CACHE_COLORS_MSK   (CACHE_COLORS_NUM - 1)
+#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 
CACHE_COLORS_MSK)
+
 /*
  * Simple wrapper over config option
  * Bootup code ensures that hardware matches kernel configuration
@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void)
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
 }
 
-#define CACHE_COLOR(addr)  (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
-
 /*
  * checks if two addresses (after page aligning) index into same cache set
  */
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index 50d71695cd4e..8147583c4434 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -979,11 +979,16 @@ void arc_cache_init(void)
/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
if (is_isa_arcompact()) {
int handled = 
IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
-
-   if (dc->alias && !handled)
-   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
-   else if (!dc->alias && handled)
+   int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE);
+
+   if (dc->alias) {
+   if (!handled)
+   panic("Enable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   if (CACHE_COLORS_NUM != num_colors)
+   panic("CACHE_COLORS_NUM not optimized 
for config\n");
+   } else if (!dc->alias && handled) {
panic("Disable 
CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+   }
}
}
 
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
index 5fda583351d7..906fb836d241 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
@@ -21,6 +21,10 @@
reg = <0x0 0x8000 0x1 0x0>;
};
 
+   gpu@5700 {
+   vdd-supply = <&vdd_gpu>;
+   };
+
/* debug port */
serial@70006000 {
status = "okay";
@@ -291,4 +295,18 @@
clock-frequency = <32768>;
};
};
+
+   regulators {
+   vdd_gpu: regulator@100 {
+   compatible = "pwm-regulator";
+   reg = <100>;
+   pwms = <&pwm 1 4880>;
+   regulator-name = "VDD_GPU";
+   regulator-min-microvolt = <71>;
+   regulator-max-microvolt = <132>;
+   enable-gpios = <&pmic 6 GPIO_ACTIVE_HIGH>;
+   regulator-ramp-delay = <80>;
+   regulator-enable-ramp-delay = <1000>;
+   };
+   };
 };
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 83037cd62d01..0c848c18ca44 100644
--- a/arch/arm64/

Linux 4.9.2

2017-01-08 Thread Greg KH
I'm announcing the release of the 4.9.2 kernel.

All users of the 4.9 kernel series must upgrade.

The updated 4.9.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 
linux-4.9.y
and can be browsed at the normal kernel.org git web browser:

http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary

thanks,

greg k-h



 Documentation/sphinx/rstFlatTable.py   |5 +
 Documentation/virtual/kvm/api.txt  |1 
 Makefile   |2 
 arch/arc/include/asm/cacheflush.h  |6 -
 arch/arc/mm/cache.c|   13 ++-
 arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi |   18 
 arch/arm64/kvm/hyp/switch.c|8 +
 arch/powerpc/boot/ps3-head.S   |5 -
 arch/powerpc/boot/ps3.c|8 -
 arch/powerpc/boot/wrapper  |   24 +
 arch/powerpc/include/asm/kvm_host.h|1 
 arch/powerpc/include/uapi/asm/kvm.h|1 
 arch/powerpc/kernel/asm-offsets.c  |1 
 arch/powerpc/kernel/head_64.S  |8 -
 arch/powerpc/kvm/book3s_hv.c   |6 +
 arch/powerpc/kvm/book3s_hv_rm_mmu.c|2 
 arch/powerpc/kvm/book3s_hv_rmhandlers.S|4 
 arch/s390/kernel/setup.c   |2 
 arch/x86/entry/entry_32.S  |4 
 arch/x86/events/core.c |8 +
 arch/x86/events/intel/cstate.c |   14 +--
 arch/x86/events/perf_event.h   |2 
 arch/x86/kernel/apic/apic.c|   15 ---
 arch/x86/kernel/cpu/common.c   |   24 +
 arch/x86/kernel/smpboot.c  |   51 
 arch/x86/kvm/vmx.c |   11 +-
 arch/x86/xen/smp.c |6 -
 block/bsg.c|3 
 drivers/acpi/video_detect.c|   20 
 drivers/base/firmware_class.c  |7 -
 drivers/clk/bcm/clk-bcm2835.c  |4 
 drivers/gpio/gpio-stmpe.c  |2 
 drivers/gpio/gpiolib.c |5 -
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c |   15 +--
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c |   15 +--
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c  |   14 +--
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c  |   15 +--
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c  |   28 +++---
 drivers/gpu/drm/amd/amdgpu/si_dpm.c|2 
 drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c|6 +
 drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c |6 +
 drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c   |6 +
 drivers/gpu/drm/amd/powerplay/smumgr/tonga_smc.c   |6 +
 drivers/gpu/drm/ast/ast_main.c |7 +
 drivers/gpu/drm/gma500/psb_drv.c   |3 
 drivers/gpu/drm/i915/i915_gem_stolen.c |5 -
 drivers/gpu/drm/i915/i915_sysfs.c  |2 
 drivers/gpu/drm/i915/intel_display.c   |9 +-
 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |3 
 drivers/gpu/drm/i915/intel_runtime_pm.c|   13 ++-
 drivers/gpu/drm/nouveau/nouveau_bios.c |3 
 drivers/gpu/drm/nouveau/nouveau_bo.c   |1 
 drivers/gpu/drm/nouveau/nvkm/engine/device/base.c  |6 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c |9 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c |8 +
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c |   50 +++-
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h|1 
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c  |7 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c  |1 
 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c |2 
 drivers/gpu/drm/radeon/radeon_cursor.c |   69 +++--
 drivers/gpu/drm/radeon/radeon_mode.h   |1 
 drivers/gpu/drm/radeon/si.c|1 
 drivers/gpu/drm/radeon/si_dpm.c|1 
 drivers/hv/channel_mgmt.c  |2 
 drivers/hwtracing/stm/core.c   |8 +
 drivers/infiniband/core/mad.c  |2 
 drivers/infiniband/core/multicast.c|7 +
 drivers/infiniband/hw/i40iw/i40iw_verbs.c  |2 
 drivers/infiniband/sw/rxe/rxe_qp.c 

[PATCH v2] ipv4: make tcp_notsent_lowat sysctl knob behave as true unsigned int

2017-01-08 Thread Pavel Tikhomirov
> cat /proc/sys/net/ipv4/tcp_notsent_lowat
-1
> echo 4294967295 > /proc/sys/net/ipv4/tcp_notsent_lowat
-bash: echo: write error: Invalid argument
> echo -2147483648 > /proc/sys/net/ipv4/tcp_notsent_lowat
> cat /proc/sys/net/ipv4/tcp_notsent_lowat
-2147483648

but in documentation we have "tcp_notsent_lowat - UNSIGNED INTEGER"

v2: simplify to just proc_douintvec
Signed-off-by: Pavel Tikhomirov 
---
 net/ipv4/sysctl_net_ipv4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 80bc36b..566cfc5 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -958,7 +958,7 @@ static struct ctl_table ipv4_net_table[] = {
.data   = &init_net.ipv4.sysctl_tcp_notsent_lowat,
.maxlen = sizeof(unsigned int),
.mode   = 0644,
-   .proc_handler   = proc_dointvec,
+   .proc_handler   = proc_douintvec,
},
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
{
-- 
2.9.3



Re: [alsa-devel] [PATCH] Revert "ASoC: core: replace aux_comp_list to component_dev_list"

2017-01-08 Thread Nikita Yushchenko
>>> I run into same issue and posted a patch:
>>
>>> "ASoC: Fix binding and probing of auxiliary components".
>>
>> Which I applied so I guess things are fine now without the revert?  I'm
>> still working through backlog from the holidays so didn't check
>> properly yet.
> 
> This fixes the Allwinner H3 codec analog controls aux_device for me.
> Thanks.

But this is not yet in 4.10-rc3 ?


Re: [PATCH v7 3/4] drm/panel: Add support for S6E3HA2 panel driver on TM2 board

2017-01-08 Thread Andrzej Hajda
On 06.01.2017 09:36, Inki Dae wrote:
>
> 2017년 01월 06일 17:18에 Andi Shyti 이(가) 쓴 글:
>> Hi Inki,
>>
>> Thanks for the reply, but...
>>
> +static const struct drm_display_mode default_mode = {
> + .clock = 222372,
> + .hdisplay = 1440,
> + .hsync_start = 1440 + 1,
> + .hsync_end = 1440 + 1 + 1,
> + .htotal = 1440 + 1 + 1 + 1,
> + .vdisplay = 2560,
> + .vsync_start = 2560 + 1,
> + .vsync_end = 2560 + 1 + 1,
> + .vtotal = 2560 + 1 + 1 + 15,
> + .vrefresh = 60,
> + .flags = 0,
> +};
 how is this working with tm2e? Are these values valid for both
 the boards?
>>> We don't need to consider tm2e board with two reasones,
>>> 1. there is no tm2e board support in mainline
>>> 2. the panel on tm2 would be a little bit different from one on tm2e
>> ... this display in the Tizen Kernel is supported by both:
>> tm2 [1] and tm2e [2]. The only differences are:
> Why tm2e dts file is in mainline? Seems communication miss with Chanwoo. :( 
>
>> TM2:
>>clock-frequency = <1487>;
>>hactive = <1440>;
>>
>> TM2E:
>>clock-frequency = <16523724>;
>>hactive = <1600>;
>>
>> I don't know much about the differences you mention in point 2,
>> but it's a pity to drop support only because we don't want to put
>> in the dts the 'hactive', and 'clock-frequency' properties.
> Anyway, tm2e board is already in mainline so Panel driver may need to 
> identify what kinds of panel is probed to decide porch values. I think there 
> are relevant registers in MCU of the Panel device to check version or similar 
> thing.

I think we can safely use different compatible string for tm2e - it uses
different display IC controller - s6e3hf2, driver will provide timings
based on it.
As far as I examined available specs/docs there is no reliable register
which can be used to safely distinguish it on runtime, but the docs I
have are far from completeness.

Regards
Andrzej

>
> Thanks.
>
>> Andi
>>
>> [1] 
>> https://git.tizen.org/cgit/platform/kernel/linux-exynos/tree/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts?h=tizen#n1284
>> [2] 
>> https://git.tizen.org/cgit/platform/kernel/linux-exynos/tree/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts?h=tizen#n1270
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> .
>>
>



Re: eMMC boot problem: switch to bus width 8 ddr failed

2017-01-08 Thread Shawn Lin

On 2017/1/7 0:07, Clemens Gruber wrote:

On Fri, Jan 06, 2017 at 10:54:35AM +0800, Shawn Lin wrote:

On 2017/1/6 8:41, Clemens Gruber wrote:

Hi,

with the current mainline 4.10-rc2 kernel, I can no longer boot from
the eMMC on my i.MX6Q board.

Details:
The eMMC is a Micron MTFC4GACAJCN-1M WT but as the i.MX6Q only supports
eMMC 4.41 features and we did not implement voltage switching from 3.3V
to 1.8V or lower, I did add no-1-8-v; (but none of the mmc-ddr or mmc-hs
options) to the device tree. The bus-width is 8.

With 4.9 the board booted fine, now with the current mainline 4.10 tree,
I get the following (repeating) errors at boot:

[4.326834] Waiting for root device /dev/mmcblk0p2...
[   14.563861] mmc0: Timeout waiting for hardware cmd interrupt.
[   14.569619] sdhci: === REGISTER DUMP (mmc0)===
[   14.575461] sdhci: Sys addr: 0x4e726000 | Version:  0x0002
[   14.581300] sdhci: Blk size: 0x0200 | Blk cnt:  0x0001
[   14.587140] sdhci: Argument: 0x0001 | Trn mode: 0x0013
[   14.592979] sdhci: Present:  0x01fd8009 | Host ctl: 0x0031
[   14.598816] sdhci: Power:0x0002 | Blk gap:  0x0080
[   14.604654] sdhci: Wake-up:  0x0008 | Clock:0x001f
[   14.610493] sdhci: Timeout:  0x008f | Int stat: 0x
[   14.616332] sdhci: Int enab: 0x107f100b | Sig enab: 0x107f100b
[   14.622168] sdhci: AC12 err: 0x | Slot int: 0x0003
[   14.628007] sdhci: Caps: 0x07eb | Caps_1:   0xa007
[   14.633845] sdhci: Cmd:  0x0d1a | Max curr: 0x00ff
[   14.639682] sdhci: Host ctl2: 0x
[   14.643611] sdhci: ADMA Err: 0x | ADMA Ptr: 0x4e6f7208
[   14.649447] sdhci: ===

This repeats a few times, then more information is shown at the bottom:

[   86.893859] mmc0: Timeout waiting for hardware cmd interrupt.
[   86.899615] sdhci: === REGISTER DUMP (mmc0)===
[   86.905453] sdhci: Sys addr: 0x | Version:  0x0002
[   86.911291] sdhci: Blk size: 0x0200 | Blk cnt:  0x0001
[   86.917129] sdhci: Argument: 0x0001 | Trn mode: 0x0013
[   86.922967] sdhci: Present:  0x01fd8009 | Host ctl: 0x0031
[   86.928804] sdhci: Power:0x0002 | Blk gap:  0x0080
[   86.934642] sdhci: Wake-up:  0x0008 | Clock:0x001f
[   86.940479] sdhci: Timeout:  0x008f | Int stat: 0x
[   86.946316] sdhci: Int enab: 0x107f100b | Sig enab: 0x107f100b
[   86.952154] sdhci: AC12 err: 0x | Slot int: 0x0003
[   86.957992] sdhci: Caps: 0x07eb | Caps_1:   0xa007
[   86.963830] sdhci: Cmd:  0x0d1a | Max curr: 0x00ff
[   86.969668] sdhci: Host ctl2: 0x
[   86.973596] sdhci: ADMA Err: 0x | ADMA Ptr: 0x
[   86.979433] sdhci: ===
[   86.986356] mmc0: switch to bus width 8 ddr failed
[   86.991163] mmc0: error -110 whilst initialising MMC card
[   97.773859] mmc0: Timeout waiting for hardware cmd interrupt.

--

After looking through the latest commits to mmc/core, I found the
culprit:
Commit e173f8911f091fa50ccf8cc1fa316dd5569bc470 ("mmc: core: Update
CMD13 polling policy when switch to HS DDR mode")

Reverting it fixes the problem. But I am unsure if that's the right
course of action?

Feel free to send me patches for testing!



I just look into both of sdhci and sdhci-esdhc-imx again, and seems the
code miss a bit, so could you also try this one?

drivers/mmc/core/mmc_ops.c
@@ -486,7 +486,8 @@ static int mmc_poll_for_busy(struct mmc_card *card,
unsigned int timeout_ms,
busy = host->ops->card_busy(host);
} else {
err = mmc_send_status(card, &status);
-   if (retry_crc_err && err == -EILSEQ) {
+   if (retry_crc_err && (err == -EILSEQ ||
+   err == -ETIMEDOUT)) {
busy = true;
} else if (err) {
return err;



Hi,

this patch (alone) does not solve the problem. The error message is the
same as before.

But applying both your first patch and this one does work. Is this one
beneficial anyway, even if it does not fix my problem?


I think so. It always assumed that if the card was not ready after
finishing switching the mode, we should got a CRC, namely -EILSEQ, from
the hosts. But the fact is if the host is in higher speed mode but the
eMMC havn't finished the switch, so the host could fail to sample the
resp of CMD13 due to the mismatch timing in between. Could it is
possible that response timeout was generated instaed of -EILSEQ? It's
quite IP specificed. So I don't think we should take the risk of relying
that. In another word, we don't expect to bail out early for any errors
bounced from hosts when polling the status, no just for explicit CRC.






Regards,
Clemens






--
Best Regards
Shawn Lin



Re: [PATCH net-next v2] net: dsa: make "label" property optional for dsa2

2017-01-08 Thread Jiri Pirko
Mon, Jan 09, 2017 at 12:15:52AM CET, vivien.dide...@savoirfairelinux.com wrote:
>In the new DTS bindings for DSA (dsa2), the "ethernet" and "link"
>phandles are respectively mandatory and exclusive to CPU port and DSA
>link device tree nodes.
>
>Simplify dsa2.c a bit by checking the presence of such phandle instead
>of checking the redundant "label" property.
>
>Then the Linux philosophy for Ethernet switch ports is to expose them to
>userspace as standard NICs by default. Thus use the standard enumerated
>"eth%d" device name if no "label" property is provided for a user port.
>This allows to save DTS files from subjective net device names.
>
>Here's an example on a ZII Dev Rev B board without "label" properties:
>
># ip link | grep ': ' | cut -d: -f2
> lo
> eth0
> eth1
> eth2@eth1
> eth3@eth1
> eth4@eth1
> eth5@eth1
> eth6@eth1
> eth7@eth1
> eth8@eth1
> eth9@eth1
> eth10@eth1
> eth11@eth1
> eth12@eth1
>
>If one wants to rename an interface, udev rules can be used as usual, as
>suggested in the switchdev documentation:
>
># cat /etc/udev/rules.d/90-net-dsa.rules
>SUBSYSTEM=="net", ACTION=="add", ENV{DEVTYPE}=="dsa", 
> NAME="sw$attr{phys_switch_id}p$attr{phys_port_id}"
>
># ip link | awk '/@eth/ { split($2,a,"@"); print a[1]; }'
>swp00
>swp01
>swp02
>sw0100p00
>sw0100p01
>sw0100p02
>sw0200p00
>sw0200p01
>sw0200p02
>sw0200p03
>sw0200p04
>
>Until the printing of netdev_phys_item_id structures is fixed in
>net/core/net-sysfs.c, an external helper can be used like this:
>
># cat /etc/udev/rules.d/90-net-dsa.rules
>SUBSYSTEM=="net", ACTION=="add", ENV{DEVTYPE}=="dsa", 
> PROGRAM="/lib/udev/dsanitizer $attr{phys_switch_id} $attr{phys_port_id}", 
> NAME="$result"

I know this is kind of confusing, but phys_port_id is to be used to
indicate same physical port that is shared by multiple netdevices- for
example sr-iov usecase. For switchdev usecase, you should use
phys_port_name.

I will add some documentation to kernel regarding this. But I see that
net/dsa/slave.c already implements .ndo_get_phys_port_id :(

I recently made changes in udev so it names the switch ports according
to phys_port_name, out of the box, without need for any rules:
https://github.com/systemd/systemd/pull/4506/commits/c960caa0c2a620fc506c6f0f7b6c40eeace48e4d

I guess that it should be enough for you to implement
ndo_get_phys_port_name.





>
># cat /lib/udev/dsanitizer
>#!/bin/sh
>echo $1 | sed -e 's,^0*,,' -e 's,0*$,,' | xargs printf sw%d
>echo $2 | sed -e 's,^0*,,' | xargs printf p%d
>
># ip link | awk '/@eth/ { split($2,a,"@"); print a[1]; }'
>sw0p0
>sw0p1
>sw0p2
>sw1p0
>sw1p1
>sw1p2
>sw2p0
>sw2p1
>sw2p2
>sw2p3
>sw2p4
>
>Of course the current behavior is unchanged, and the optional "label"
>property for user ports has precedence over the enumerated name.
>
>Signed-off-by: Vivien Didelot 
>Acked-by: Uwe Kleine-König 
>---
> Documentation/devicetree/bindings/net/dsa/dsa.txt | 20 ---
> net/dsa/dsa2.c| 24 ---
> 2 files changed, 12 insertions(+), 32 deletions(-)
>
>diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt 
>b/Documentation/devicetree/bindings/net/dsa/dsa.txt
>index a4a570fb2494..cfe8f64eca4f 100644
>--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
>+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
>@@ -34,13 +34,9 @@ Required properties:
> 
> Each port children node must have the following mandatory properties:
> - reg : Describes the port address in the switch
>-- label   : Describes the label associated with this 
>port, which
>-  will become the netdev name. Special labels are
>-"cpu" to indicate a CPU port and "dsa" to
>-indicate an uplink/downlink port between switches in
>-the cluster.
> 
>-A port labelled "dsa" has the following mandatory property:
>+An uplink/downlink port between switches in the cluster has the following
>+mandatory property:
> 
> - link: Should be a list of phandles to other 
> switch's DSA
> port. This port is used as the outgoing port
>@@ -48,12 +44,17 @@ A port labelled "dsa" has the following mandatory property:
> information must be given, not just the one hop
> routes to neighbouring switches.
> 
>-A port labelled "cpu" has the following mandatory property:
>+A CPU port has the following mandatory property:
> 
> - ethernet: Should be a phandle to a valid Ethernet device node.
>   This host device is what the switch port is
> connected to.
> 
>+A user port has the following optional 

Re: [PATCH v6 3/3] arm64: dts: exynos: Add tm2 touchkey node

2017-01-08 Thread Chanwoo Choi
Hi Jaechul,

I tested this patch on TM2 board. It is well working
with platform.

Reviewed-by: Chanwoo Choi 
Tested-by: Chanwoo Choi 

Best Regards,
Chanwoo Choi

On 2017년 01월 09일 16:22, Jaechul Lee wrote:
> Add DT node support for TM2 touchkey device.
> 
> Signed-off-by: Beomho Seo 
> Signed-off-by: Jaechul Lee 
> Signed-off-by: Andi Shyti 
> Reviewed-by: Javier Martinez Canillas 
> ---
>  arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts 
> b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> index 2449266..ddba2f8 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> @@ -18,6 +18,19 @@
>   compatible = "samsung,tm2", "samsung,exynos5433";
>  };
>  
> +&hsi2c_9 {
> + status = "okay";
> +
> + touchkey@20 {
> + compatible = "cypress,tm2-touchkey";
> + reg = <0x20>;
> + interrupt-parent = <&gpa3>;
> + interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
> + vcc-supply = <&ldo32_reg>;
> + vdd-supply = <&ldo33_reg>;
> + };
> +};
> +
>  &ldo31_reg {
>   regulator-name = "TSP_VDD_1.85V_AP";
>   regulator-min-microvolt = <185>;
> 



[PATCH v2] arm64: do not set dma masks that device connection can't handle

2017-01-08 Thread Nikita Yushchenko
It is possible that device is capable of 64-bit DMA addresses, and
device driver tries to set wide DMA mask, but bridge or bus used to
connect device to the system can't handle wide addresses.

With swiotlb, memory above 4G still can be used by drivers for streaming
DMA, but *dev->mask and dev->dma_coherent_mask must still keep values
that hardware handles physically.

This patch enforces that. Based on original version by
Arnd Bergmann , extended with coherent mask hadnling.

Signed-off-by: Nikita Yushchenko 
CC: Arnd Bergmann 
---
Changes since v1:
- fixed issues noted by Sergei Shtylyov 
  - save mask, not size
  - remove doube empty line

 arch/arm64/Kconfig  |  3 +++
 arch/arm64/include/asm/device.h |  1 +
 arch/arm64/mm/dma-mapping.c | 51 +
 3 files changed, 55 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1117421..afb2c08 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -216,6 +216,9 @@ config NEED_DMA_MAP_STATE
 config NEED_SG_DMA_LENGTH
def_bool y
 
+config ARCH_HAS_DMA_SET_COHERENT_MASK
+   def_bool y
+
 config SMP
def_bool y
 
diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
index 243ef25..a57e7bb 100644
--- a/arch/arm64/include/asm/device.h
+++ b/arch/arm64/include/asm/device.h
@@ -22,6 +22,7 @@ struct dev_archdata {
void *iommu;/* private IOMMU data */
 #endif
bool dma_coherent;
+   u64 parent_dma_mask;
 };
 
 struct pdev_archdata {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index e040827..5ab15ce 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -352,6 +352,30 @@ static int __swiotlb_dma_supported(struct device *hwdev, 
u64 mask)
return 1;
 }
 
+static int __swiotlb_set_dma_mask(struct device *dev, u64 mask)
+{
+   /* device is not DMA capable */
+   if (!dev->dma_mask)
+   return -EIO;
+
+   /* mask is below swiotlb bounce buffer, so fail */
+   if (!swiotlb_dma_supported(dev, mask))
+   return -EIO;
+
+   /*
+* because of the swiotlb, we can return success for
+* larger masks, but need to ensure that bounce buffers
+* are used above parent_dma_mask, so set that as
+* the effective mask.
+*/
+   if (mask > dev->archdata.parent_dma_mask)
+   mask = dev->archdata.parent_dma_mask;
+
+   *dev->dma_mask = mask;
+
+   return 0;
+}
+
 static struct dma_map_ops swiotlb_dma_ops = {
.alloc = __dma_alloc,
.free = __dma_free,
@@ -367,8 +391,23 @@ static struct dma_map_ops swiotlb_dma_ops = {
.sync_sg_for_device = __swiotlb_sync_sg_for_device,
.dma_supported = __swiotlb_dma_supported,
.mapping_error = swiotlb_dma_mapping_error,
+   .set_dma_mask = __swiotlb_set_dma_mask,
 };
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+   if (!dma_supported(dev, mask))
+   return -EIO;
+
+   if (get_dma_ops(dev) == &swiotlb_dma_ops &&
+   mask > dev->archdata.parent_dma_mask)
+   mask = dev->archdata.parent_dma_mask;
+
+   dev->coherent_dma_mask = mask;
+   return 0;
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
 static int __init atomic_pool_init(void)
 {
pgprot_t prot = __pgprot(PROT_NORMAL_NC);
@@ -958,6 +997,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
if (!dev->archdata.dma_ops)
dev->archdata.dma_ops = &swiotlb_dma_ops;
 
+   /*
+* we don't yet support buses that have a non-zero mapping.
+*  Let's hope we won't need it
+*/
+   WARN_ON(dma_base != 0);
+
+   /*
+* Whatever the parent bus can set. A device must not set
+* a DMA mask larger than this.
+*/
+   dev->archdata.parent_dma_mask = size - 1;
+
dev->archdata.dma_coherent = coherent;
__iommu_setup_dma_ops(dev, dma_base, size, iommu);
 }
-- 
2.1.4



Re: [PATCH v6 2/3] input: tm2-touchkey: Add touchkey driver support for TM2

2017-01-08 Thread Chanwoo Choi
Hi Jaechul,

Looks good to me. I tested this patch on TM2 board.
It is well working.

Reviewed-by: Chanwoo Choi 
Tested-by: Chanwoo Choi 

Best Regards,
Chanwoo Choi

On 2017년 01월 09일 16:22, Jaechul Lee wrote:
> This patch adds support for the TM2 touch key and led
> functionality.
> 
> The driver interfaces with userspace through an input device and
> reports KEY_PHONE and KEY_BACK event types. LED brightness can be
> controlled by "/sys/class/leds/tm2-touchkey/brightness".
> 
> Signed-off-by: Beomho Seo 
> Signed-off-by: Jaechul Lee 
> Reviewed-by: Javier Martinez Canillas 
> Reviewed-by: Andi Shyti 
> Acked-by: Krzysztof Kozlowski 
> ---
>  drivers/input/keyboard/Kconfig|  11 ++
>  drivers/input/keyboard/Makefile   |   1 +
>  drivers/input/keyboard/tm2-touchkey.c | 287 
> ++
>  3 files changed, 299 insertions(+)
>  create mode 100644 drivers/input/keyboard/tm2-touchkey.c
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index cbd75cf..97acd65 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
> To compile this driver as a module, choose M here: the
> module will be called tc3589x-keypad.
>  
> +config KEYBOARD_TM2_TOUCHKEY
> + tristate "TM2 touchkey support"
> + depends on I2C
> + depends on LEDS_CLASS
> + help
> +   Say Y here to enable device driver for tm2-touchkey with
> +   LED control for the Exynos5433 TM2 board.
> +
> +   To compile this driver as a module, choose M here.
> +   module will be called tm2-touchkey.
> +
>  config KEYBOARD_TWL4030
>   tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
>   depends on TWL4030_CORE
> diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
> index d9f4cfc..7d9acff 100644
> --- a/drivers/input/keyboard/Makefile
> +++ b/drivers/input/keyboard/Makefile
> @@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC)  += sun4i-lradc-keys.o
>  obj-$(CONFIG_KEYBOARD_SUNKBD)+= sunkbd.o
>  obj-$(CONFIG_KEYBOARD_TC3589X)   += tc3589x-keypad.o
>  obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
> +obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)  += tm2-touchkey.o
>  obj-$(CONFIG_KEYBOARD_TWL4030)   += twl4030_keypad.o
>  obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
>  obj-$(CONFIG_KEYBOARD_W90P910)   += w90p910_keypad.o
> diff --git a/drivers/input/keyboard/tm2-touchkey.c 
> b/drivers/input/keyboard/tm2-touchkey.c
> new file mode 100644
> index 000..e927d06
> --- /dev/null
> +++ b/drivers/input/keyboard/tm2-touchkey.c
> @@ -0,0 +1,287 @@
> +/*
> + * TM2 touchkey device driver
> + *
> + * Copyright 2005 Phil Blundell
> + * Copyright 2016 Samsung Electronics Co., Ltd.
> + *
> + * Author: Beomho Seo 
> + * Author: Jaechul Lee 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define TM2_TOUCHKEY_DEV_NAME"tm2-touchkey"
> +#define TM2_TOUCHKEY_KEYCODE_REG 0x03
> +#define TM2_TOUCHKEY_BASE_REG0x00
> +#define TM2_TOUCHKEY_CMD_LED_ON  0x10
> +#define TM2_TOUCHKEY_CMD_LED_OFF 0x20
> +#define TM2_TOUCHKEY_BIT_PRESS_EVBIT(3)
> +#define TM2_TOUCHKEY_BIT_KEYCODE GENMASK(2, 0)
> +#define TM2_TOUCHKEY_LED_VOLTAGE_MIN 250
> +#define TM2_TOUCHKEY_LED_VOLTAGE_MAX 330
> +
> +enum {
> + TM2_TOUCHKEY_KEY_MENU = 0x1,
> + TM2_TOUCHKEY_KEY_BACK,
> +};
> +
> +enum {
> + TM2_TOUCHKEY_SUPPLIES_VCC,
> + TM2_TOUCHKEY_SUPPLIES_VDD,
> +};
> +
> +struct tm2_touchkey_data {
> + struct i2c_client *client;
> + struct input_dev *input_dev;
> + struct led_classdev led_dev;
> + struct regulator_bulk_data regulators[2];
> +
> + u8 keycode_type;
> + u8 pressed;
> +};
> +
> +static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
> + enum led_brightness brightness)
> +{
> + struct tm2_touchkey_data *touchkey =
> + container_of(led_dev, struct tm2_touchkey_data, led_dev);
> + u32 volt;
> + u8 data;
> +
> + if (brightness == LED_OFF) {
> + volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
> + data = TM2_TOUCHKEY_CMD_LED_OFF;
> + } else {
> + volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
> + data = TM2_TOUCHKEY_CMD_LED_ON;
> + }
> +
> + regulator_set_voltage(
> + touchkey->regulators[TM2_TOUCHKEY_SUPPLIES_VDD].consumer,
> + volt, volt);
> + i2c_smbus_write_byte_data(touchkey->client,
> + TM2_TOUCHKEY_BASE_REG, d

[PATCH v6 3/3] arm64: dts: exynos: Add tm2 touchkey node

2017-01-08 Thread Jaechul Lee
Add DT node support for TM2 touchkey device.

Signed-off-by: Beomho Seo 
Signed-off-by: Jaechul Lee 
Signed-off-by: Andi Shyti 
Reviewed-by: Javier Martinez Canillas 
---
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts 
b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index 2449266..ddba2f8 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -18,6 +18,19 @@
compatible = "samsung,tm2", "samsung,exynos5433";
 };
 
+&hsi2c_9 {
+   status = "okay";
+
+   touchkey@20 {
+   compatible = "cypress,tm2-touchkey";
+   reg = <0x20>;
+   interrupt-parent = <&gpa3>;
+   interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+   vcc-supply = <&ldo32_reg>;
+   vdd-supply = <&ldo33_reg>;
+   };
+};
+
 &ldo31_reg {
regulator-name = "TSP_VDD_1.85V_AP";
regulator-min-microvolt = <185>;
-- 
2.7.4



[PATCH v6 1/3] input: Add support for the tm2 touchkey device driver

2017-01-08 Thread Jaechul Lee
This patch adds the binding description of the tm2 touchkey
device driver.

Signed-off-by: Jaechul Lee 
Reviewed-by: Javier Martinez Canillas 
Reviewed-by: Andi Shyti 
Reviewed-by: Chanwoo Choi 
Acked-by: Rob Herring 
Acked-by: Krzysztof Kozlowski 
---
 .../bindings/input/cypress,tm2-touchkey.txt| 27 ++
 1 file changed, 27 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt

diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt 
b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
new file mode 100644
index 000..635f62c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
@@ -0,0 +1,27 @@
+Samsung tm2-touchkey
+
+Required properties:
+- compatible: must be "cypress,tm2-touchkey"
+- reg: I2C address of the chip.
+- interrupt-parent: a phandle for the interrupt controller (see interrupt
+   binding[0]).
+- interrupts: interrupt to which the chip is connected (see interrupt
+   binding[0]).
+- vcc-supply : internal regulator output. 1.8V
+- vdd-supply : power supply for IC 3.3V
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example:
+   &i2c0 {
+   /* ... */
+
+   touchkey@20 {
+   compatible = "cypress,tm2-touchkey";
+   reg = <0x20>;
+   interrupt-parent = <&gpa3>;
+   interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+   vcc-supply=<&ldo32_reg>;
+   vdd-supply=<&ldo33_reg>;
+   };
+   };
-- 
2.7.4



[PATCH v6 2/3] input: tm2-touchkey: Add touchkey driver support for TM2

2017-01-08 Thread Jaechul Lee
This patch adds support for the TM2 touch key and led
functionality.

The driver interfaces with userspace through an input device and
reports KEY_PHONE and KEY_BACK event types. LED brightness can be
controlled by "/sys/class/leds/tm2-touchkey/brightness".

Signed-off-by: Beomho Seo 
Signed-off-by: Jaechul Lee 
Reviewed-by: Javier Martinez Canillas 
Reviewed-by: Andi Shyti 
Acked-by: Krzysztof Kozlowski 
---
 drivers/input/keyboard/Kconfig|  11 ++
 drivers/input/keyboard/Makefile   |   1 +
 drivers/input/keyboard/tm2-touchkey.c | 287 ++
 3 files changed, 299 insertions(+)
 create mode 100644 drivers/input/keyboard/tm2-touchkey.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index cbd75cf..97acd65 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
  To compile this driver as a module, choose M here: the
  module will be called tc3589x-keypad.
 
+config KEYBOARD_TM2_TOUCHKEY
+   tristate "TM2 touchkey support"
+   depends on I2C
+   depends on LEDS_CLASS
+   help
+ Say Y here to enable device driver for tm2-touchkey with
+ LED control for the Exynos5433 TM2 board.
+
+ To compile this driver as a module, choose M here.
+ module will be called tm2-touchkey.
+
 config KEYBOARD_TWL4030
tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index d9f4cfc..7d9acff 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC)+= sun4i-lradc-keys.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)  += sunkbd.o
 obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
 obj-$(CONFIG_KEYBOARD_TEGRA)   += tegra-kbc.o
+obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)+= tm2-touchkey.o
 obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)   += xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
diff --git a/drivers/input/keyboard/tm2-touchkey.c 
b/drivers/input/keyboard/tm2-touchkey.c
new file mode 100644
index 000..e927d06
--- /dev/null
+++ b/drivers/input/keyboard/tm2-touchkey.c
@@ -0,0 +1,287 @@
+/*
+ * TM2 touchkey device driver
+ *
+ * Copyright 2005 Phil Blundell
+ * Copyright 2016 Samsung Electronics Co., Ltd.
+ *
+ * Author: Beomho Seo 
+ * Author: Jaechul Lee 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TM2_TOUCHKEY_DEV_NAME  "tm2-touchkey"
+#define TM2_TOUCHKEY_KEYCODE_REG   0x03
+#define TM2_TOUCHKEY_BASE_REG  0x00
+#define TM2_TOUCHKEY_CMD_LED_ON0x10
+#define TM2_TOUCHKEY_CMD_LED_OFF   0x20
+#define TM2_TOUCHKEY_BIT_PRESS_EV  BIT(3)
+#define TM2_TOUCHKEY_BIT_KEYCODE   GENMASK(2, 0)
+#define TM2_TOUCHKEY_LED_VOLTAGE_MIN   250
+#define TM2_TOUCHKEY_LED_VOLTAGE_MAX   330
+
+enum {
+   TM2_TOUCHKEY_KEY_MENU = 0x1,
+   TM2_TOUCHKEY_KEY_BACK,
+};
+
+enum {
+   TM2_TOUCHKEY_SUPPLIES_VCC,
+   TM2_TOUCHKEY_SUPPLIES_VDD,
+};
+
+struct tm2_touchkey_data {
+   struct i2c_client *client;
+   struct input_dev *input_dev;
+   struct led_classdev led_dev;
+   struct regulator_bulk_data regulators[2];
+
+   u8 keycode_type;
+   u8 pressed;
+};
+
+static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
+   enum led_brightness brightness)
+{
+   struct tm2_touchkey_data *touchkey =
+   container_of(led_dev, struct tm2_touchkey_data, led_dev);
+   u32 volt;
+   u8 data;
+
+   if (brightness == LED_OFF) {
+   volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
+   data = TM2_TOUCHKEY_CMD_LED_OFF;
+   } else {
+   volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
+   data = TM2_TOUCHKEY_CMD_LED_ON;
+   }
+
+   regulator_set_voltage(
+   touchkey->regulators[TM2_TOUCHKEY_SUPPLIES_VDD].consumer,
+   volt, volt);
+   i2c_smbus_write_byte_data(touchkey->client,
+   TM2_TOUCHKEY_BASE_REG, data);
+}
+
+static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey)
+{
+   int ret = 0;
+
+   ret = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators),
+   touchkey->regulators);
+   if (ret)
+   return ret;
+
+   /* waiting for device initialization, at least 150ms */
+   msleep(150);
+
+   return 0;
+}
+
+static void tm2

[PATCH v6 0/3] Add touch key driver support for TM2

2017-01-08 Thread Jaechul Lee
Hi,

This patch is last three patch from https://lkml.org/lkml/2017/1/6/277.
because 1 and 2 patches have already been merged by Krzysztof.

This patchset adds support for the tm2 touchkey device.

The driver has been ported from Tizen Kernel, originally written
by Beomho. I ported it to the latest mainline Kernel.

Best Regard,
Jaechul

Changes in v6:
 - changed compatible name from samsaung to cypress. 
 - updated commit tags.
 - removed first two patches from the original patchset.
 
Changes in v5:
 - patch 1: removed a spurious regulator-always-off inherited from
   a different patch. Thanks Krzysztof.
 - patch 2: fixed a slip on  the model, thanks Javier (this patch
   confuses me quite a lot, this was all right some patches ago
   and re appeared on this one).
 - patch 2: removed 'regulator' label and used the original ldo3x
   labels. Krzysztof: it looks better indeed.
 - added Javier's reviews and Krzysztof's acks on the related
   patches.

Changes in v4:
 - patch 1 has been rebased on top of 7c294e002641 (arm64: dts:
   exynos: Remove unsupported regulator-always-off property from
   TM2E)
 - patch 2 has been generated with -B50% diff option using git
   2.11

Changes in v3:
 - Changed the commit ordering, the tm2-touchkey related patches
   are the last 3.
 - Added Chanwoo's patch which fixes the wrong voltage of ldo23
   and ldo25.
 - Andi (patch 3) moves the ldo31 and ldo38 in the tm2 and tm2e
   files as they have different values.

Changes in v2:
 - fixed reviews from Javier, Dmitry
 - refactored power enable/disable functions.
 - reordered signed-offs in patch 2, while patch 4 is left as it
   was as Andi copy pasted the node to the new tm2.dts file
 - added Jarvier's (patch 1,2,4) and Krzysztof's (patch 4)
   reviews
   and Rob's Ack
 - patch 3 diff has been generated with -B50%

Jaechul Lee (3):
  input: Add support for the tm2 touchkey device driver
  input: tm2-touchkey: Add touchkey driver support for TM2
  arm64: dts: exynos: Add tm2 touchkey node

 .../bindings/input/cypress,tm2-touchkey.txt|  27 ++
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts  |  13 +
 drivers/input/keyboard/Kconfig |  11 +
 drivers/input/keyboard/Makefile|   1 +
 drivers/input/keyboard/tm2-touchkey.c  | 287 +
 5 files changed, 339 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
 create mode 100644 drivers/input/keyboard/tm2-touchkey.c

-- 
2.7.4



Re: [PATCH 2/3] xen: modify xenstore watch event interface

2017-01-08 Thread Juergen Gross
On 06/01/17 22:57, Boris Ostrovsky wrote:
> On 01/06/2017 10:05 AM, Juergen Gross wrote:
>> Today a Xenstore watch event is delivered via a callback function
>> declared as:
>>
>> void (*callback)(struct xenbus_watch *,
>>  const char **vec, unsigned int len);
>>
>> As all watch events only ever come with two parameters (path and token)
>> changing the prototype to:
>>
>> void (*callback)(struct xenbus_watch *,
>>  const char *path, const char *token);
>>
>> is the natural thing to do.
>>
>> Apply this change and adapt all users.
>>
>> Cc: konrad.w...@oracle.com
>> Cc: roger@citrix.com
>> Cc: wei.l...@citrix.com
>> Cc: paul.durr...@citrix.com
>> Cc: net...@vger.kernel.org
>>
>> Signed-off-by: Juergen Gross 
> 
> 
>>  
>> @@ -903,24 +902,24 @@ static int process_msg(void)
>>  body[msg->hdr.len] = '\0';
>>  
>>  if (msg->hdr.type == XS_WATCH_EVENT) {
>> -msg->u.watch.vec = split(body, msg->hdr.len,
>> - &msg->u.watch.vec_size);
>> -if (IS_ERR(msg->u.watch.vec)) {
>> -err = PTR_ERR(msg->u.watch.vec);
>> +if (count_strings(body, msg->hdr.len) != 2) {
>> +err = -EINVAL;
> 
> xenbus_write_watch() returns -EILSEQ when this type of error is
> encountered so perhaps for we should return the same error here.

Not since 9a6161fe73bdd3ae4a1e18421b0b20cb7141f680. :-)

> 
> Either way
> 
> Reviewed-by: Boris Ostrovsky 

Thanks,

Juergen



Re: eMMC boot problem: switch to bus width 8 ddr failed

2017-01-08 Thread Shawn Lin

On 2017/1/6 23:56, Clemens Gruber wrote:

On Fri, Jan 06, 2017 at 10:33:49AM +0800, Shawn Lin wrote:

On 2017/1/6 8:41, Clemens Gruber wrote:

Hi,

with the current mainline 4.10-rc2 kernel, I can no longer boot from
the eMMC on my i.MX6Q board.

Details:
The eMMC is a Micron MTFC4GACAJCN-1M WT but as the i.MX6Q only supports
eMMC 4.41 features and we did not implement voltage switching from 3.3V
to 1.8V or lower, I did add no-1-8-v; (but none of the mmc-ddr or mmc-hs
options) to the device tree. The bus-width is 8.

With 4.9 the board booted fine, now with the current mainline 4.10 tree,
I get the following (repeating) errors at boot:

[4.326834] Waiting for root device /dev/mmcblk0p2...
[   14.563861] mmc0: Timeout waiting for hardware cmd interrupt.
[   14.569619] sdhci: === REGISTER DUMP (mmc0)===
[   14.575461] sdhci: Sys addr: 0x4e726000 | Version:  0x0002
[   14.581300] sdhci: Blk size: 0x0200 | Blk cnt:  0x0001
[   14.587140] sdhci: Argument: 0x0001 | Trn mode: 0x0013
[   14.592979] sdhci: Present:  0x01fd8009 | Host ctl: 0x0031
[   14.598816] sdhci: Power:0x0002 | Blk gap:  0x0080
[   14.604654] sdhci: Wake-up:  0x0008 | Clock:0x001f
[   14.610493] sdhci: Timeout:  0x008f | Int stat: 0x
[   14.616332] sdhci: Int enab: 0x107f100b | Sig enab: 0x107f100b
[   14.622168] sdhci: AC12 err: 0x | Slot int: 0x0003
[   14.628007] sdhci: Caps: 0x07eb | Caps_1:   0xa007
[   14.633845] sdhci: Cmd:  0x0d1a | Max curr: 0x00ff


it shows you always fail to get resp of sending status within the
expected period of time.



[   14.639682] sdhci: Host ctl2: 0x
[   14.643611] sdhci: ADMA Err: 0x | ADMA Ptr: 0x4e6f7208
[   14.649447] sdhci: ===

This repeats a few times, then more information is shown at the bottom:

[   86.893859] mmc0: Timeout waiting for hardware cmd interrupt.
[   86.899615] sdhci: === REGISTER DUMP (mmc0)===
[   86.905453] sdhci: Sys addr: 0x | Version:  0x0002
[   86.911291] sdhci: Blk size: 0x0200 | Blk cnt:  0x0001
[   86.917129] sdhci: Argument: 0x0001 | Trn mode: 0x0013
[   86.922967] sdhci: Present:  0x01fd8009 | Host ctl: 0x0031
[   86.928804] sdhci: Power:0x0002 | Blk gap:  0x0080
[   86.934642] sdhci: Wake-up:  0x0008 | Clock:0x001f
[   86.940479] sdhci: Timeout:  0x008f | Int stat: 0x
[   86.946316] sdhci: Int enab: 0x107f100b | Sig enab: 0x107f100b
[   86.952154] sdhci: AC12 err: 0x | Slot int: 0x0003
[   86.957992] sdhci: Caps: 0x07eb | Caps_1:   0xa007
[   86.963830] sdhci: Cmd:  0x0d1a | Max curr: 0x00ff
[   86.969668] sdhci: Host ctl2: 0x
[   86.973596] sdhci: ADMA Err: 0x | ADMA Ptr: 0x
[   86.979433] sdhci: ===
[   86.986356] mmc0: switch to bus width 8 ddr failed
[   86.991163] mmc0: error -110 whilst initialising MMC card
[   97.773859] mmc0: Timeout waiting for hardware cmd interrupt.

--

After looking through the latest commits to mmc/core, I found the
culprit:
Commit e173f8911f091fa50ccf8cc1fa316dd5569bc470 ("mmc: core: Update
CMD13 polling policy when switch to HS DDR mode")

Reverting it fixes the problem. But I am unsure if that's the right
course of action?

Feel free to send me patches for testing!


By looking the changes itself, it should be good from the view of spec.
Maybe you could try the patch below, but don't beat me if that doesn't
help at all. :)

--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1074,7 +1074,7 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
   EXT_CSD_BUS_WIDTH,
   ext_csd_bits,
   card->ext_csd.generic_cmd6_time,
-  MMC_TIMING_MMC_DDR52,
+  0,
   true, true, true);
if (err) {
pr_err("%s: switch to bus width %d ddr failed\n",
@@ -1118,6 +1118,9 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
if (err)
err = __mmc_set_signal_voltage(host,
MMC_SIGNAL_VOLTAGE_330);

+   if (!err)
+   mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
+




Hi,

thank you. This patch solves the problem! :)


Again, from the view of spec, the code is fine.

So I *guess* that seems your host driver doesn't work fine under
DDR52 when it's in 3V3 vccq. But I don't have a real hardware to debug
it.  Could freescale guys help to check it?





Tested-by: Clemens Gruber 

Regards,
Clemens
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
Best Regards
Shawn Lin



Re: [PATCH 1/3] xen: clean up xenbus internal headers

2017-01-08 Thread Juergen Gross
On 06/01/17 21:52, Boris Ostrovsky wrote:
> On 01/06/2017 10:05 AM, Juergen Gross wrote:
>> The xenbus driver has an awful mixture of internal and global visible
>> headers: some of the internal used only stuff is defined in the
>> global header include/xen/xenbus.h while some stuff defined in internal
>> headers is used by other drivers, too.
>>
>> Clean this up by moving the external used symbols to
>> include/xen/xenbus.h and the symbols used internal only to a new
> 
> I think
> 
> s/external/externally/
> s/internal/internally/

Hmm, yes.

>> header drivers/xen/xenbus/xenbus.h
> 
> ... and remove xenbus_comms.h

and xenbus_probe.h.

> 
>>
>> Signed-off-by: Juergen Gross 
>> ---
>>  drivers/xen/xenbus/{xenbus_probe.h => xenbus.h} | 64 
>> ++---
>>  drivers/xen/xenbus/xenbus_client.c  |  2 +-
>>  drivers/xen/xenbus/xenbus_comms.c   |  2 +-
>>  drivers/xen/xenbus/xenbus_comms.h   | 51 
>>  drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
>>  drivers/xen/xenbus/xenbus_dev_frontend.c|  4 +-
>>  drivers/xen/xenbus/xenbus_probe.c   |  3 +-
>>  drivers/xen/xenbus/xenbus_probe_backend.c   |  3 +-
>>  drivers/xen/xenbus/xenbus_probe_frontend.c  |  3 +-
>>  drivers/xen/xenbus/xenbus_xs.c  |  3 +-
>>  drivers/xen/xenfs/super.c   |  2 +-
>>  drivers/xen/xenfs/xenstored.c   |  2 +-
>>  include/xen/xenbus.h| 12 ++---
>>  13 files changed, 52 insertions(+), 101 deletions(-)
>>  rename drivers/xen/xenbus/{xenbus_probe.h => xenbus.h} (58%)
>>  delete mode 100644 drivers/xen/xenbus/xenbus_comms.h
>>
>> diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus.h
>> similarity index 58%
>> rename from drivers/xen/xenbus/xenbus_probe.h
>> rename to drivers/xen/xenbus/xenbus.h
>> index c9ec7ca..6a80c1e 100644
>> --- a/drivers/xen/xenbus/xenbus_probe.h
>> +++ b/drivers/xen/xenbus/xenbus.h
>> @@ -1,10 +1,7 @@
>> -/**
>> - * xenbus_probe.h
>> - *
>> - * Talks to Xen Store to figure out what devices we have.
>> +/*
>> + * Private include for xenbus communications.
>>   *
>>   * Copyright (C) 2005 Rusty Russell, IBM Corporation
>> - * Copyright (C) 2005 XenSource Ltd.
> 
> Why is this?

Result of merging two header files. Will re-add.


Juergen


[PATCH v2] arm64: dts: rockchip: add "rockchip,grf" property for RK3399 PMUCRU/CRU

2017-01-08 Thread Xing Zheng
The structure rockchip_clk_provider needs to refer the GRF regmap
in somewhere, if the CRU node has not "rockchip,grf" property,
calling syscon_regmap_lookup_by_phandle will return an invalid GRF
regmap, and the MUXGRF type clock will be not supported.

Therefore, we need to add them.

Signed-off-by: Xing Zheng 
---

Changes in v2:
- referring pmugrf for PMUGRU
- fix the typo "invaild" in COMMIT message

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 92b731f..a40e6d0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1090,6 +1090,7 @@
pmucru: pmu-clock-controller@ff75 {
compatible = "rockchip,rk3399-pmucru";
reg = <0x0 0xff75 0x0 0x1000>;
+   rockchip,grf = <&pmugrf>;
#clock-cells = <1>;
#reset-cells = <1>;
assigned-clocks = <&pmucru PLL_PPLL>;
@@ -1099,6 +1100,7 @@
cru: clock-controller@ff76 {
compatible = "rockchip,rk3399-cru";
reg = <0x0 0xff76 0x0 0x1000>;
+   rockchip,grf = <&grf>;
#clock-cells = <1>;
#reset-cells = <1>;
assigned-clocks =
-- 
2.7.4




Re: [PATCH] arm64: do not set dma masks that device connection can't handle

2017-01-08 Thread Nikita Yushchenko
>> +if (mask > dev->archdata.parent_dma_mask)
>> +mask = dev->archdata.parent_dma_mask;
>> +
>> +
> 
>One empty line is enough...

Ok

>> +/*
>> + * Whatever the parent bus can set. A device must not set
>> + * a DMA mask larger than this.
>> + */
>> +dev->archdata.parent_dma_mask = size;
> 
>Not 'size - 1'?

Good question.

Indeed of_dma_configure() calls arch_setup_dma_ops() with size, not
mask. Which implies '-1' is needed here. Although better fix may be to
change caller side - to make DMA_BIT_MASK(64) case cleaner.

Will repost path.

Nikita


Re: [PATCH] ACPI/IORT: Fix iort_node_get_id() mapping entries indexing

2017-01-08 Thread Hanjun Guo

On 2017/1/9 14:34, Hanjun Guo wrote:

Hi Sinan,

On 2017/1/8 5:09, Sinan Kaya wrote:

On 1/5/2017 1:29 PM, Lorenzo Pieralisi wrote:

Commit 618f535a6062 ("ACPI/IORT: Add single mapping function")
introduced a function (iort_node_get_id()) to retrieve ids for IORT
named components.

iort_node_get_id() takes an index as input to refer to a specific
mapping entry in the mapping array to retrieve the id at a specific
index provided the index is below the total mapping count; currently the
index is used to retrieve the mapping value from the correct entry but
not to dereference the correct entry while retrieving the mapping
output_reference (ie IORT parent pointer), which consequently always
resolves to the output_reference of the first entry in the mapping
array.

Update the map array entry pointer computation in iort_node_get_id() to
take into account the index value, fixing the issue.

Fixes: 618f535a6062 ("ACPI/IORT: Add single mapping function")
Reported-by: Hanjun Guo 
Signed-off-by: Lorenzo Pieralisi 
Cc: Hanjun Guo 
Cc: Sinan Kaya 
Cc: Tomasz Nowicki 
Cc: Nate Watterson 
Cc: "Rafael J. Wysocki" 
---
 drivers/acpi/arm64/iort.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e0d2e6e..ba156c5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -333,7 +333,7 @@ struct acpi_iort_node *iort_node_get_id(struct
acpi_iort_node *node,
 return NULL;

 map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
-   node->mapping_offset);
+   node->mapping_offset + index * sizeof(*map));


What does this give us that the previous code didn't do?


Fir example, if you have multi mappings ids under platform device:

|-|
|  SMMU  2|<---
|-|   |
  |
  |
|-|   |
|  SMMU 1 |<  |
|-||  |
   |  |
   |  |
|-||  |
|  platform   ||  |
|  device ||  |
|-||  |
| stream id   ||  |
| 1   ||  |
| parent--||  |
|-|   |
|  stream id  |   |
|  2  |   |
|  parent-|---|
|-|

For now, we just use the first entry in the mapping entry to get
the parent, and always point to the same parent, as above, we will
always map to SMMU 1 even if you connect to different SMMUs. (Although
we may don't have such device topology yet)




You are using map as a pointer and returning the offset of the first
map entry above
and then accessing the map at the indexed offset with map[index]

The new code is using map as a plain pointer, calculating the pointer
location with ACPI_ADD_PTR
instead and then collecting the output parameter with map->output_base.



 /* Firmware bug! */
 if (!map->output_reference) {
@@ -348,10 +348,10 @@ struct acpi_iort_node *iort_node_get_id(struct
acpi_iort_node *node,
 if (!(IORT_TYPE_MASK(parent->type) & type_mask))
 return NULL;

-if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
 if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
 node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
-*id_out = map[index].output_base;
+*id_out = map->output_base;


You are claiming that the existing code is collecting the output
parameter from the first mapping.
I don't see this happening above.

What am I missing?


It's not about the output id but it's about the parent returned
by this function, it always return the first entry's parent in the
mapping entry.


And as Lorenzo said in the commit message:
"always resolves to the output_reference of the first entry in the
mapping array."

Then always judge the same entry for:

if (!map->output_reference)
pr_err();

...

Thanks
Hanjun


[tip:efi/urgent] x86/efi: Don't allocate memmap through memblock after mm_init()

2017-01-08 Thread tip-bot for Nicolai Stange
Commit-ID:  20b1e22d01a4b0b11d3a1066e9feb04be38607ec
Gitweb: http://git.kernel.org/tip/20b1e22d01a4b0b11d3a1066e9feb04be38607ec
Author: Nicolai Stange 
AuthorDate: Thu, 5 Jan 2017 13:51:29 +0100
Committer:  Ingo Molnar 
CommitDate: Sat, 7 Jan 2017 08:58:07 +0100

x86/efi: Don't allocate memmap through memblock after mm_init()

With the following commit:

  4bc9f92e64c8 ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image 
data")

...  efi_bgrt_init() calls into the memblock allocator through
efi_mem_reserve() => efi_arch_mem_reserve() *after* mm_init() has been called.

Indeed, KASAN reports a bad read access later on in efi_free_boot_services():

  BUG: KASAN: use-after-free in efi_free_boot_services+0xae/0x24c
at addr 88022de12740
  Read of size 4 by task swapper/0/0
  page:ea0008b78480 count:0 mapcount:-127
  mapping:  (null) index:0x1 flags: 0x5fff80()
  [...]
  Call Trace:
   dump_stack+0x68/0x9f
   kasan_report_error+0x4c8/0x500
   kasan_report+0x58/0x60
   __asan_load4+0x61/0x80
   efi_free_boot_services+0xae/0x24c
   start_kernel+0x527/0x562
   x86_64_start_reservations+0x24/0x26
   x86_64_start_kernel+0x157/0x17a
   start_cpu+0x5/0x14

The instruction at the given address is the first read from the memmap's
memory, i.e. the read of md->type in efi_free_boot_services().

Note that the writes earlier in efi_arch_mem_reserve() don't splat because
they're done through early_memremap()ed addresses.

So, after memblock is gone, allocations should be done through the "normal"
page allocator. Introduce a helper, efi_memmap_alloc() for this. Use
it from efi_arch_mem_reserve(), efi_free_boot_services() and, for the sake
of consistency, from efi_fake_memmap() as well.

Note that for the latter, the memmap allocations cease to be page aligned.
This isn't needed though.

Tested-by: Dan Williams 
Signed-off-by: Nicolai Stange 
Reviewed-by: Ard Biesheuvel 
Cc:  # v4.9
Cc: Dave Young 
Cc: Linus Torvalds 
Cc: Matt Fleming 
Cc: Mika Penttilä 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: linux-...@vger.kernel.org
Fixes: 4bc9f92e64c8 ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying 
image data")
Link: http://lkml.kernel.org/r/20170105125130.2815-1-nicsta...@gmail.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/platform/efi/quirks.c  |  4 ++--
 drivers/firmware/efi/fake_mem.c |  3 +--
 drivers/firmware/efi/memmap.c   | 38 ++
 include/linux/efi.h |  1 +
 4 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 10aca63..30031d5 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -214,7 +214,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
 
new_size = efi.memmap.desc_size * num_entries;
 
-   new_phys = memblock_alloc(new_size, 0);
+   new_phys = efi_memmap_alloc(num_entries);
if (!new_phys) {
pr_err("Could not allocate boot services memmap\n");
return;
@@ -355,7 +355,7 @@ void __init efi_free_boot_services(void)
}
 
new_size = efi.memmap.desc_size * num_entries;
-   new_phys = memblock_alloc(new_size, 0);
+   new_phys = efi_memmap_alloc(num_entries);
if (!new_phys) {
pr_err("Failed to allocate new EFI memmap\n");
return;
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
index 520a40e..6c7d60c 100644
--- a/drivers/firmware/efi/fake_mem.c
+++ b/drivers/firmware/efi/fake_mem.c
@@ -71,8 +71,7 @@ void __init efi_fake_memmap(void)
}
 
/* allocate memory for new EFI memmap */
-   new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map,
-   PAGE_SIZE);
+   new_memmap_phy = efi_memmap_alloc(new_nr_map);
if (!new_memmap_phy)
return;
 
diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c
index f03ddec..7868644 100644
--- a/drivers/firmware/efi/memmap.c
+++ b/drivers/firmware/efi/memmap.c
@@ -9,6 +9,44 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+
+static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
+{
+   return memblock_alloc(size, 0);
+}
+
+static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
+{
+   unsigned int order = get_order(size);
+   struct page *p = alloc_pages(GFP_KERNEL, order);
+
+   if (!p)
+   return 0;
+
+   return PFN_PHYS(page_to_pfn(p));
+}
+
+/**
+ * efi_memmap_alloc - Allocate memory for the EFI memory map
+ * @num_entries: Number of entries in the allocated map.
+ *
+ * Depending on whether mm_init() has already been invoked or not,
+ * either memblock or "normal" page allocation is used.
+ *
+ * Returns the physical address of the allocated memory map on
+ * success, zero on failure.
+ */
+phys_addr_t __init efi_memmap_alloc(unsigned int num

[tip:perf/urgent] perf/x86/intel/uncore: Fix hardcoded socket 0 assumption in the Haswell init code

2017-01-08 Thread tip-bot for Prarit Bhargava
Commit-ID:  fa37361e291bfe528872b9aef5c8644a3fc7ff20
Gitweb: http://git.kernel.org/tip/fa37361e291bfe528872b9aef5c8644a3fc7ff20
Author: Prarit Bhargava 
AuthorDate: Thu, 5 Jan 2017 10:09:25 -0500
Committer:  Ingo Molnar 
CommitDate: Sat, 7 Jan 2017 08:54:38 +0100

perf/x86/intel/uncore: Fix hardcoded socket 0 assumption in the Haswell init 
code

On multi-socket Intel v3 processor systems (aka Haswell), kdump can crash
in hswep_uncore_cpu_init():

  BUG: unable to handle kernel paging request at 006563a1
  IP: [] hswep_uncore_cpu_init+0x52/0xa0

The crash was introduced by the following commit:

  9d85eb9119f4 ("x86/smpboot: Make logical package management more robust")

... which patch corrected the physical ID to logical ID mapping of the
threads if the kdumped panic occurs on any socket other than socket 0.

But hswep_uncore_cpu_init() is hard coded for physical socket 0 and if the
system is kdump'ing on any other socket the logical package value will be
incorrect - crashing the kdump kernel.

The code should not use 0 as the physical ID, and should use the boot
CPU's logical package ID in this calculation.

Signed-off-by: Prarit Bhargava 
Cc: Alexander Shishkin 
Cc: Arnaldo Carvalho de Melo 
Cc: Borislav Petkov 
Cc: H. Peter Anvin 
Cc: Harish Chegondi 
Cc: Jiri Olsa 
Cc: Kan Liang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Stephane Eranian 
Cc: Thomas Gleixner 
Cc: Vince Weaver 
Link: 
http://lkml.kernel.org/r/1483628965-2890-1-git-send-email-pra...@redhat.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/events/intel/uncore_snbep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/uncore_snbep.c 
b/arch/x86/events/intel/uncore_snbep.c
index e6832be..dae2fed 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -2686,7 +2686,7 @@ static struct intel_uncore_type *hswep_msr_uncores[] = {
 
 void hswep_uncore_cpu_init(void)
 {
-   int pkg = topology_phys_to_logical_pkg(0);
+   int pkg = boot_cpu_data.logical_proc_id;
 
if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;


[RFC 01/55] arm64: Add missing TCR hw defines

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Some bits of the TCR weren't defined and since we're about to use these
in KVM, add these defines.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/pgtable-hwdef.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h 
b/arch/arm64/include/asm/pgtable-hwdef.h
index eb0c2bd..d26cab7 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -272,9 +272,15 @@
 #define TCR_TG1_4K (UL(2) << TCR_TG1_SHIFT)
 #define TCR_TG1_64K(UL(3) << TCR_TG1_SHIFT)
 
+#define TCR_IPS_SHIFT  32
+#define TCR_IPS_MASK   (UL(7) << TCR_IPS_SHIFT)
+
 #define TCR_ASID16 (UL(1) << 36)
 #define TCR_TBI0   (UL(1) << 37)
 #define TCR_HA (UL(1) << 39)
 #define TCR_HD (UL(1) << 40)
 
+#define TCR_EPD1   (UL(1) << 23)
+#define TCR_EPD0   (UL(1) << 7)
+
 #endif
-- 
1.9.1




Re: [PATCH v4] mmc: dw_mmc: force setup bus if active slots exist

2017-01-08 Thread Shawn Lin

On 2017/1/9 13:41, Jaehoon Chung wrote:

On 01/09/2017 12:39 PM, Ziyuan wrote:



On 01/05/2017 03:34 PM, Shawn Lin wrote:

On 2017/1/5 15:23, Ziyuan Xu wrote:

It's necessary to setup bus if any slots are present.
- update clock after ctrl reset
- if the host has genpd node, we can guarantee the clock is available
before starting request. Otherwies, the clock register is reset once
power off the pd, and host can't output the active clock during
communication.

fixes: e9ed8835e990 ("mmc: dw_mmc: add runtime PM callback")
Reported-by: Randy Li 
Signed-off-by: Ziyuan Xu 

---
Hi guys,

I found a similar issue on rk3399 platform, which has a genpd node for
SD card host. Power off-on pd will reset the registers to a default
value (ie. CLKENA), so that the host can't output the active clock
during communication.



Indeed, Caesar recently introduced all the genpd for rk3399 platform,
so we need to restore them.


So we need to setup bus in rpm resume. It also wraps the update clock
behaviour which I did in V3.

Thanks,
Ziyuan Xu


Changes in v4:
- update commit message
- fix SD host rpm resume can't work

Changes in v3:
- only reset host with active slot.

Changes in v2:
- update the commit message
- use dw_mci_reset instead of dw_mci_ctrl_reset

 drivers/mmc/host/dw_mmc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b44306b..b6053b3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -3354,10 +3354,10 @@ int dw_mci_runtime_resume(struct device *dev)

 if (!slot)
 continue;
-if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
+if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
 dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
-dw_mci_setup_bus(slot, true);
-}
+/* Force setup bus to guarantee available clock output */
+dw_mci_setup_bus(slot, true);


So the spamming message about

"Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n"

will always be there, right? So you could append a new patch to shut
up it as I think it's useless no matter for system pm or rpm to print
it.  How about?


Fine, it's favourable with dev_vdbg if the dw_mmc rpm is enabled.
Hi Jaehoon,
What's your opinion? If you think this patch and shawn's advice are acceptable, 
I will send the v5 patch.


I don't agreed to use dev_vdbg()..but it needs not to display at everytime.
Hmm..It needs to consider more..because we needs to see the clock value when 
it's initialized.



A very stright-forward way is to pass a flag to shut up the spamming
log when it's called from the PM context?


Best Regards,
Jaehoon Chung



BR
Ziyuan Xu




 }

 /* Now that slots are all setup, we can enable card detect */


















--
Best Regards
Shawn Lin



[RFC 03/55] KVM: arm64: Add KVM nesting feature

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Set the initial exception level of the guest to EL2 if nested
virtualization feature is enabled.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_host.h | 2 +-
 arch/arm64/include/uapi/asm/kvm.h | 1 +
 arch/arm64/kvm/reset.c| 8 
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e505038..c0c8b02 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -41,7 +41,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 4
+#define KVM_VCPU_MAX_FEATURES 5
 
 #define KVM_REQ_VCPU_EXIT  8
 
diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index 3051f86..78117bf 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -97,6 +97,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
 #define KVM_ARM_VCPU_PSCI_0_2  2 /* CPU uses PSCI v0.2 */
 #define KVM_ARM_VCPU_PMU_V33 /* Support guest PMUv3 */
+#define KVM_ARM_VCPU_NESTED_VIRT   4 /* Support nested virtual EL2 */
 
 struct kvm_vcpu_init {
__u32 target;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 74322c2..e6b0b20 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -41,6 +41,11 @@
PSR_F_BIT | PSR_D_BIT),
 };
 
+static const struct kvm_regs default_regs_reset_el2 = {
+   .regs.pstate = (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT |
+   PSR_F_BIT | PSR_D_BIT),
+};
+
 static const struct kvm_regs default_regs_reset32 = {
.regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT |
COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
@@ -124,6 +129,9 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
if (!cpu_has_32bit_el1())
return -EINVAL;
cpu_reset = &default_regs_reset32;
+   } else if (test_bit(KVM_ARM_VCPU_NESTED_VIRT,
+   vcpu->arch.features)) {
+   cpu_reset = &default_regs_reset_el2;
} else {
cpu_reset = &default_regs_reset;
}
-- 
1.9.1




[RFC 02/55] KVM: arm64: Add nesting config option

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Add an option that allows nested hypervisor support.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/Kconfig | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c..37263ff 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -57,6 +57,12 @@ config KVM_ARM_PMU
  Adds support for a virtual Performance Monitoring Unit (PMU) in
  virtual machines.
 
+config KVM_ARM_NESTED_HYP
+   bool "Nested Virtualization"
+   depends on KVM
+   ---help---
+ Support nested hypervisors in VMs.
+
 source drivers/vhost/Kconfig
 
 endif # VIRTUALIZATION
-- 
1.9.1




[RFC 10/55] KVM: arm64: Synchronize EL1 system registers on virtual EL2 entry and exit

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When running in virtual EL2 we use the shadow EL1 systerm register array
for the save/restore process, so that hardware and especially the memory
subsystem behaves as code written for EL2 expects while really running
in EL1.

This works great for EL1 system register accesses that we trap, because
these accesses will be written into the virtual state for the EL1 system
registers used when eventually switching the VCPU mode to EL1.

However, there was a collection of EL1 system registers which we do not
trap, and as a consequence all save/restore operations of these
registers were happening locally in the shadow array, with no benefit to
software actually running in virtual EL1 at all.

To fix this, simply synchronize the shadow and real EL1 state for these
registers on entry/exit to/from virtual EL2 state.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 2e9e386..0025dd9 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -88,6 +88,51 @@ static void create_shadow_el1_sysregs(struct kvm_vcpu *vcpu)
s_sys_regs[CPACR_EL1] = cptr_el2_to_cpacr_el1(el2_regs[CPTR_EL2]);
 }
 
+/*
+ * List of EL1 registers which we allow the virtual EL2 mode to access
+ * directly without trapping and which haven't been paravirtualized.
+ *
+ * Probably CNTKCTL_EL1 should not be copied but be accessed via trap. Because,
+ * the guest hypervisor running in EL1 can be affected by event streams
+ * configured via CNTKCTL_EL1, which it does not expect. We don't have a
+ * mechanism to trap on CNTKCTL_EL1 as of now (v8.3), keep it in here instead.
+ */
+static const int el1_non_trap_regs[] = {
+   CNTKCTL_EL1,
+   CSSELR_EL1,
+   PAR_EL1,
+   TPIDR_EL0,
+   TPIDR_EL1,
+   TPIDRRO_EL0
+};
+
+/**
+ * sync_shadow_el1_state - Going to/from the virtual EL2 state, sync state
+ * @vcpu:  The VCPU pointer
+ * @setup: True, if on the way to the guest (called from setup)
+ * False, if returning form the guet (calld from restore)
+ *
+ * Some EL1 registers are accessed directly by the virtual EL2 mode because
+ * they in no way affect execution state in virtual EL2.   However, we must
+ * still ensure that virtual EL2 observes the same state of the EL1 registers
+ * as the normal VM's EL1 mode, so copy this state as needed on setup/restore.
+ */
+static void sync_shadow_el1_state(struct kvm_vcpu *vcpu, bool setup)
+{
+   u64 *sys_regs = vcpu->arch.ctxt.sys_regs;
+   u64 *s_sys_regs = vcpu->arch.ctxt.shadow_sys_regs;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(el1_non_trap_regs); i++) {
+   const int sr = el1_non_trap_regs[i];
+
+   if (setup)
+   s_sys_regs[sr] = sys_regs[sr];
+   else
+   sys_regs[sr] = s_sys_regs[sr];
+   }
+}
+
 /**
  * kvm_arm_setup_shadow_state -- prepare shadow state based on emulated mode
  * @vcpu: The VCPU pointer
@@ -107,6 +152,7 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
else
ctxt->hw_pstate |= PSR_MODE_EL1t;
 
+   sync_shadow_el1_state(vcpu, true);
create_shadow_el1_sysregs(vcpu);
ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
@@ -125,6 +171,7 @@ void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
if (unlikely(vcpu_mode_el2(vcpu))) {
+   sync_shadow_el1_state(vcpu, false);
*vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
*vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
-- 
1.9.1




[RFC 05/55] KVM: arm64: Add vcpu_mode_el2 primitive to support nesting

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When running a nested hypervisor we occasionally have to figure out if
the mode we are switching into is the virtual EL2 mode or a regular
EL0/1 mode.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   |  6 ++
 arch/arm64/include/asm/kvm_emulate.h | 12 
 2 files changed, 18 insertions(+)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 9a8a45a..399cd75e 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -77,6 +77,12 @@ static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu 
*vcpu)
return 1;
 }
 
+/* We don't support nesting on arm */
+static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
+{
+   return false;
+}
+
 static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
 {
return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_pc;
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index f5ea0ba..830be2e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -143,6 +143,18 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu 
*vcpu)
return mode != PSR_MODE_EL0t;
 }
 
+static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
+{
+   u32 mode;
+
+   if (vcpu_mode_is_32bit(vcpu))
+   return false;
+
+   mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
+
+   return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;
+}
+
 static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
 {
return vcpu->arch.fault.esr_el2;
-- 
1.9.1




[RFC 04/55] KVM: arm64: Allow userspace to set PSR_MODE_EL2x

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

We were not allowing userspace to set a more privileged mode for the VCPU
than EL1, but now that we support nesting with a virtual EL2 mode, do
allow this!

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/guest.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 3f9e157..6b9f38a 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -117,6 +117,8 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct 
kvm_one_reg *reg)
case PSR_MODE_EL0t:
case PSR_MODE_EL1t:
case PSR_MODE_EL1h:
+   case PSR_MODE_EL2h:
+   case PSR_MODE_EL2t:
break;
default:
err = -EINVAL;
-- 
1.9.1




[RFC 00/55] Nested Virtualization on KVM/ARM

2017-01-08 Thread Jintack Lim
Nested virtualization is the ability to run a virtual machine inside another
virtual machine. In other words, it???s about running a hypervisor (the guest
hypervisor) on top of another hypervisor (the host hypervisor).

This series supports nested virtualization on arm64. ARM recently announced an
extension (ARMv8.3) which has support for nested virtualization[1]. This series
is based on the ARMv8.3 specification.

Supporting nested virtualization means that the hypervisor provides not only
EL0/EL1 execution environment with VMs as it usually does, but also the
virtualization extensions including EL2 execution environment with the VMs.
Once the host hypervisor provides those execution environment with the VMs,
then the guest hypervisor can run its own VMs (nested VMs) naturally.

To support nested virtualization on ARM the hypervisor must emulate a virtual
execution environment consisting of EL2, EL1, and EL0, as the guest hypervisor
will run in a virtual EL2 mode.  Normally KVM/ARM only emulated a VM supporting
EL1/0 running in their respective native CPU modes, but with nested
virtualization we deprivilege the guest hypervisor and emulate a virtual EL2
execution mode in EL1 using the hardware features provided by ARMv8.3 to trap
EL2 operations to EL1. To do that the host hypervisor needs to manage EL2
register state for the guest hypervisor, and shadow EL1 register state that
reflects the EL2 register state to run the guest hypervisor in EL1. See patch 6
through 10 for this.

For memory virtualization, the biggest issue is that we now have more than two
stages of translation when running nested VMs. We choose to merge two stage-2
page tables (one from the guest hypervisor and the other from the host
hypervisor) and create shadow stage-2 page tables, which have mappings from the
nested VM???s physical addresses to the machine physical addresses. Stage-1
translation is done by the hardware as is done for the normal VMs.

To provide VGIC support to the guest hypervisor, we emulate the GIC
virtualization extensions using trap-and-emulate to a virtual GIC Hypervisor
Control Interface.  Furthermore, we can still use the GIC VE hardware features
to deliver virtual interrupts to the nested VM, by directly mapping the GIC
VCPU interface to the nested VM and switching the content of the GIC Hypervisor
Control interface when alternating between a nested VM and a normal VM.  See
patches 25 through 32, and 50 through 52 for more information.

For timer virtualization, the guest hypervisor expects to have access to the
EL2 physical timer, the EL1 physical timer and the virtual timer. So, the host
hypervisor needs to provide all of them. The virtual timer is always available
to VMs. The physical timer is available to VMs via my previous patch series[3].
The EL2 physical timer is not supported yet in this RFC. We plan to support
this as it is required to run other guest hypervisors such as Xen.

Even though this work is not complete (see limitations below), I'd appreciate
early feedback on this RFC. Specifically, I'm interested in:
- Is it better to have a kernel config or to make it configurable at runtime?
- I wonder if the data structure for memory management makes sense.
- What architecture version do we support for the guest hypervisor, and how?
  For example, do we always support all architecture versions or the same
  architecture as the underlying hardware platform? Or is it better
  to make it configurable from the userspace?
- Initial comments on the overall design?

This patch series is based on kvm-arm-for-4.9-rc7 with the patch series to 
provide
VMs with the EL1 physical timer[2].

Git: https://github.com/columbia/nesting-pub/tree/rfc-v1

Testing:
We have tested this on ARMv8.0 (Applied Micro X-Gene)[3] since ARMv8.3 hardware
is not available yet. We have paravirtualized the guest hypervisor to trap to
EL2 as specified in ARMv8.3 specification using hvc instruction. We plan to
test this on ARMv8.3 model, and will post the result and v2 if necessary.

Limitations:
- This patch series only supports arm64, not arm. All the patches compile on
  arm, but I haven't try to boot normal VMs on it.
- The guest hypervisor with VHE (ARMv8.1) is not supported in this RFC. I have
  patches for that, but they need to be cleaned up.
- Recursive nesting (i.e. emulating ARMv8.3 in the VM) is not tested yet.
- Other hypervisors (such as Xen) on KVM are not tested.

TODO:
- Test to boot normal VMs on arm architecture
- Test this on ARMv8.3 model
- Support the guest hypervisor with VHE
- Provide the guest hypervisor with the EL2 physical timer
- Run other hypervisors such as Xen on KVM

[1] 
https://www.community.arm.com/processors/b/blog/posts/armv8-a-architecture-2016-additions
[2] https://lists.cs.columbia.edu/pipermail/kvmarm/2016-December/022825.html
[3] https://www.cloudlab.us/hardware.php#utah

Christoffer Dall (27):
  arm64: Add missing TCR hw defines
  KVM: arm64: Add nesting config option
  KVM: arm64: Add KVM nestin

[RFC 09/55] KVM: arm64: Set shadow EL1 registers for virtual EL2 execution

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When entering virtual EL2, we need to reflect virtual EL2 register
states to corresponding shadow EL1 registers. We can simply copy them if
their formats are identical.  Otherwise, we need to convert EL2 register
state to EL1 register state.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 71 
 1 file changed, 71 insertions(+)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index acb4b1e..2e9e386 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -17,6 +17,76 @@
 
 #include 
 #include 
+#include 
+
+struct el1_el2_map {
+   enum vcpu_sysregel1;
+   enum el2_regs   el2;
+};
+
+/*
+ * List of EL2 registers which can be directly applied to EL1 registers to
+ * emulate running EL2 in EL1.  The EL1 registers here must either be trapped
+ * or paravirtualized in EL1.
+ */
+static const struct el1_el2_map el1_el2_map[] = {
+   { AMAIR_EL1, AMAIR_EL2 },
+   { MAIR_EL1, MAIR_EL2 },
+   { TTBR0_EL1, TTBR0_EL2 },
+   { ACTLR_EL1, ACTLR_EL2 },
+   { AFSR0_EL1, AFSR0_EL2 },
+   { AFSR1_EL1, AFSR1_EL2 },
+   { SCTLR_EL1, SCTLR_EL2 },
+   { VBAR_EL1, VBAR_EL2 },
+};
+
+static inline u64 tcr_el2_ips_to_tcr_el1_ps(u64 tcr_el2)
+{
+   return ((tcr_el2 & TCR_EL2_PS_MASK) >> TCR_EL2_PS_SHIFT)
+   << TCR_IPS_SHIFT;
+}
+
+static inline u64 cptr_el2_to_cpacr_el1(u64 cptr_el2)
+{
+   u64 cpacr_el1 = 0;
+
+   if (!(cptr_el2 & CPTR_EL2_TFP))
+   cpacr_el1 |= CPACR_EL1_FPEN;
+   if (cptr_el2 & CPTR_EL2_TTA)
+   cpacr_el1 |= CPACR_EL1_TTA;
+
+   return cpacr_el1;
+}
+
+static void create_shadow_el1_sysregs(struct kvm_vcpu *vcpu)
+{
+   u64 *s_sys_regs = vcpu->arch.ctxt.shadow_sys_regs;
+   u64 *el2_regs = vcpu->arch.ctxt.el2_regs;
+   u64 tcr_el2;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(el1_el2_map); i++) {
+   const struct el1_el2_map *map = &el1_el2_map[i];
+
+   s_sys_regs[map->el1] = el2_regs[map->el2];
+   }
+
+   tcr_el2 = el2_regs[TCR_EL2];
+   s_sys_regs[TCR_EL1] =
+   TCR_EPD1 |  /* disable TTBR1_EL1 */
+   ((tcr_el2 & TCR_EL2_TBI) ? TCR_TBI0 : 0) |
+   tcr_el2_ips_to_tcr_el1_ps(tcr_el2) |
+   (tcr_el2 & TCR_EL2_TG0_MASK) |
+   (tcr_el2 & TCR_EL2_ORGN0_MASK) |
+   (tcr_el2 & TCR_EL2_IRGN0_MASK) |
+   (tcr_el2 & TCR_EL2_T0SZ_MASK);
+
+   /* Rely on separate VMID for VA context, always use ASID 0 */
+   s_sys_regs[TTBR0_EL1] &= ~GENMASK_ULL(63, 48);
+   s_sys_regs[TTBR1_EL1] = 0;
+
+   s_sys_regs[CPACR_EL1] = cptr_el2_to_cpacr_el1(el2_regs[CPTR_EL2]);
+}
 
 /**
  * kvm_arm_setup_shadow_state -- prepare shadow state based on emulated mode
@@ -37,6 +107,7 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
else
ctxt->hw_pstate |= PSR_MODE_EL1t;
 
+   create_shadow_el1_sysregs(vcpu);
ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
} else {
-- 
1.9.1




[RFC 11/55] KVM: arm64: Emulate taking an exception to the guest hypervisor

2017-01-08 Thread Jintack Lim
Emulate taking an exception to the guest hypervisor running in the
virtual EL2 as described in ARM ARM AArch64.TakeException().

Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   | 14 
 arch/arm64/include/asm/kvm_emulate.h | 19 +++
 arch/arm64/kvm/Makefile  |  2 ++
 arch/arm64/kvm/emulate-nested.c  | 66 
 arch/arm64/kvm/trace.h   | 20 +++
 5 files changed, 121 insertions(+)
 create mode 100644 arch/arm64/kvm/emulate-nested.c

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 0a03b7d..0fa2f5a 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -47,6 +47,20 @@ static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 
reg_num,
 void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
 void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
+static inline int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
+{
+   kvm_err("Unexpected call to %s for the non-nesting configuration\n",
+__func__);
+   return -EINVAL;
+}
+
+static inline int kvm_inject_nested_irq(struct kvm_vcpu *vcpu)
+{
+   kvm_err("Unexpected call to %s for the non-nesting configuration\n",
+__func__);
+   return -EINVAL;
+}
+
 static inline void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu) { };
 static inline void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu) { };
 static inline void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt) { };
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 8892c82..0987ee4 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -42,6 +42,25 @@
 void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
 void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
+int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
+#else
+static inline int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
+{
+   kvm_err("Unexpected call to %s for the non-nesting configuration\n",
+__func__);
+   return -EINVAL;
+}
+
+static inline int kvm_inject_nested_irq(struct kvm_vcpu *vcpu)
+{
+   kvm_err("Unexpected call to %s for the non-nesting configuration\n",
+__func__);
+   return -EINVAL;
+}
+#endif
+
 void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu);
 void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu);
 void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt);
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 7811d27..b342bdd 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -34,3 +34,5 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
 kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
+
+kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += emulate-nested.o
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
new file mode 100644
index 000..59d147f
--- /dev/null
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 - Columbia University
+ * Author: Jintack Lim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "trace.h"
+
+#defineEL2_EXCEPT_SYNC_OFFSET  0x400
+#defineEL2_EXCEPT_ASYNC_OFFSET 0x480
+
+
+/*
+ *  Emulate taking an exception. See ARM ARM J8.1.2 AArch64.TakeException()
+ */
+static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
+int exception_offset)
+{
+   int ret = 1;
+   kvm_cpu_context_t *ctxt = &vcpu->arch.ctxt;
+
+   /* We don't inject an exception recursively to virtual EL2 */
+   if (vcpu_mode_el2(vcpu))
+   BUG();
+
+   ctxt->el2_regs[SPSR_EL2] = *vcpu_cpsr(vcpu);
+   ctxt->el2_regs[ELR_EL2] = *vcpu_pc(vcpu);
+   ctxt->el2_regs[ESR_EL2] = esr_el2;
+
+   /* On an exception, PSTATE.SP = 1 */
+   *vcpu_cpsr(vcpu) = PSR_MODE_EL2h;
+   *vcpu_cpsr(vcpu) |=  (PSR_A_BIT | PSR_F_BIT | PSR_I_BIT | PSR_D_BIT);
+   *vcpu_pc(vcpu) = ctxt->el2_regs[VBAR_EL2] + exception_offset;
+
+   trace_kvm_inject_n

[RFC 13/55] KVM: arm64: Handle eret instruction traps

2017-01-08 Thread Jintack Lim
When HCR.NV bit is set, eret instruction execution in the guest
hypervisor will trap with EC code 0x1A. Let ELR_EL2 and SPSR_EL2 state
from the guest's perspective be restored to the hardware on the next
guest entry.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/esr.h |  1 +
 arch/arm64/kvm/handle_exit.c | 12 
 arch/arm64/kvm/trace.h   | 21 +
 3 files changed, 34 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d14c478..f32e3a7 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -42,6 +42,7 @@
 #define ESR_ELx_EC_HVC64   (0x16)
 #define ESR_ELx_EC_SMC64   (0x17)
 #define ESR_ELx_EC_SYS64   (0x18)
+#define ESR_ELx_EC_ERET(0x1A)
 /* Unallocated EC: 0x19 - 0x1E */
 #define ESR_ELx_EC_IMP_DEF (0x1f)
 #define ESR_ELx_EC_IABT_LOW(0x20)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index a204adf..4e4a915 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -125,6 +125,17 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, 
struct kvm_run *run)
return ret;
 }
 
+static int kvm_handle_eret(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   trace_kvm_nested_eret(vcpu, vcpu_el2_reg(vcpu, ELR_EL2),
+ vcpu_el2_reg(vcpu, SPSR_EL2));
+
+   *vcpu_pc(vcpu) = vcpu_el2_reg(vcpu, ELR_EL2);
+   *vcpu_cpsr(vcpu) = vcpu_el2_reg(vcpu, SPSR_EL2);
+
+   return 1;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_WFx]= kvm_handle_wfx,
[ESR_ELx_EC_CP15_32]= kvm_handle_cp15_32,
@@ -137,6 +148,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, 
struct kvm_run *run)
[ESR_ELx_EC_HVC64]  = handle_hvc,
[ESR_ELx_EC_SMC64]  = handle_smc,
[ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
+   [ESR_ELx_EC_ERET]   = kvm_handle_eret,
[ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
diff --git a/arch/arm64/kvm/trace.h b/arch/arm64/kvm/trace.h
index 7c86cfb..5f40987 100644
--- a/arch/arm64/kvm/trace.h
+++ b/arch/arm64/kvm/trace.h
@@ -187,6 +187,27 @@
TP_printk("vcpu: %p, inject exception to vEL2: ESR_EL2 0x%lx, vector: 
0x%016lx",
  __entry->vcpu, __entry->esr_el2, __entry->pc)
 );
+
+TRACE_EVENT(kvm_nested_eret,
+   TP_PROTO(struct kvm_vcpu *vcpu, unsigned long elr_el2,
+unsigned long spsr_el2),
+   TP_ARGS(vcpu, elr_el2, spsr_el2),
+
+   TP_STRUCT__entry(
+   __field(struct kvm_vcpu *,  vcpu)
+   __field(unsigned long,  elr_el2)
+   __field(unsigned long,  spsr_el2)
+   ),
+
+   TP_fast_assign(
+   __entry->vcpu = vcpu;
+   __entry->elr_el2 = elr_el2;
+   __entry->spsr_el2 = spsr_el2;
+   ),
+
+   TP_printk("vcpu: %p, eret to elr_el2: 0x%016lx, with spsr_el2: 0x%08lx",
+ __entry->vcpu, __entry->elr_el2, __entry->spsr_el2)
+);
 #endif /* _TRACE_ARM64_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
-- 
1.9.1




[RFC 16/55] KVM: arm64: Forward VM reg traps to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward virtual memory register traps to the guest hypervisor
if it has set corresponding bits to the virtual HCR_EL2.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/sys_regs.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index b8e993a..0f5d21b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -90,6 +90,23 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
return true;
 }
 
+static bool forward_vm_traps(struct kvm_vcpu *vcpu, struct sys_reg_params *p)
+{
+   u64 hcr_el2 = vcpu_el2_reg(vcpu, HCR_EL2);
+
+   /* If this is a trap from the virtual EL2, the host handles */
+   if (vcpu_mode_el2(vcpu))
+   return false;
+
+   /* If the guest wants to trap on R/W operation, forward this trap */
+   if ((hcr_el2 & HCR_TVM) && p->is_write)
+   return true;
+   else if ((hcr_el2 & HCR_TRVM) && !p->is_write)
+   return true;
+
+   return false;
+}
+
 /*
  * Generic accessor for VM registers. Only called as long as HCR_TVM
  * is set. If the guest enables the MMU, we stop trapping the VM
@@ -101,6 +118,9 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 {
bool was_enabled = vcpu_has_cache_enabled(vcpu);
 
+   if (forward_vm_traps(vcpu, p))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
BUG_ON(!vcpu_mode_el2(vcpu) && !p->is_write);
 
if (!p->is_write) {
-- 
1.9.1




[RFC 17/55] KVM: arm64: Trap SPSR_EL1, ELR_EL1 and VBAR_EL1 in virtual EL2

2017-01-08 Thread Jintack Lim
For the same reason we trap virtual memory register accesses in virtual
EL2, we need to trap SPSR_EL1, ELR_EL1 and VBAR_EL1 accesses. ARM v8.3
introduces the HCR_EL2.NV1 bit to be able to trap on those register
accesses in EL1. Do not set this bit until the whole nesting support is
complete.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/sys_regs.c | 41 -
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 0f5d21b..19d6a6e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -898,6 +898,38 @@ static bool access_cntp_cval(struct kvm_vcpu *vcpu,
return true;
 }
 
+static inline void access_rw(struct sys_reg_params *p, u64 *sysreg)
+{
+   if (!p->is_write)
+   p->regval = *sysreg;
+   else
+   *sysreg = p->regval;
+}
+
+static bool access_elr(struct kvm_vcpu *vcpu,
+   struct sys_reg_params *p,
+   const struct sys_reg_desc *r)
+{
+   access_rw(p, &vcpu->arch.ctxt.gp_regs.elr_el1);
+   return true;
+}
+
+static bool access_spsr(struct kvm_vcpu *vcpu,
+   struct sys_reg_params *p,
+   const struct sys_reg_desc *r)
+{
+   access_rw(p, &vcpu->arch.ctxt.gp_regs.spsr[KVM_SPSR_EL1]);
+   return true;
+}
+
+static bool access_vbar(struct kvm_vcpu *vcpu,
+   struct sys_reg_params *p,
+   const struct sys_reg_desc *r)
+{
+   access_rw(p, &vcpu_sys_reg(vcpu, r->reg));
+   return true;
+}
+
 static bool trap_el2_reg(struct kvm_vcpu *vcpu,
 struct sys_reg_params *p,
 const struct sys_reg_desc *r)
@@ -1013,6 +1045,13 @@ static bool trap_el2_reg(struct kvm_vcpu *vcpu,
{ Op0(0b11), Op1(0b000), CRn(0b0010), CRm(0b), Op2(0b010),
  access_vm_reg, reset_val, TCR_EL1, 0 },
 
+   /* SPSR_EL1 */
+   { Op0(0b11), Op1(0b000), CRn(0b0100), CRm(0b), Op2(0b000),
+ access_spsr},
+   /* ELR_EL1 */
+   { Op0(0b11), Op1(0b000), CRn(0b0100), CRm(0b), Op2(0b001),
+ access_elr},
+
/* AFSR0_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b0101), CRm(0b0001), Op2(0b000),
  access_vm_reg, reset_unknown, AFSR0_EL1 },
@@ -1045,7 +1084,7 @@ static bool trap_el2_reg(struct kvm_vcpu *vcpu,
 
/* VBAR_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b), Op2(0b000),
- NULL, reset_val, VBAR_EL1, 0 },
+ access_vbar, reset_val, VBAR_EL1, 0 },
 
/* ICC_SGI1R_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1011), Op2(0b101),
-- 
1.9.1




[RFC 18/55] KVM: arm64: Forward traps due to HCR_EL2.NV1 bit to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward ELR_EL1, SPSR_EL1 and VBAR_EL1 traps to the guest hypervisor if
it has set the NV1 bit to the virtual HCR_EL2. The guest hypervisor
would set this NV1 bit to run a hypervisor in its VM (i.e. another level
of nested hypervisor).

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/kvm/sys_regs.c| 17 +
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 2a2752b..feded61 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,7 @@
 #include 
 
 /* Hyp Configuration Register (HCR) bits */
+#define HCR_NV1(UL(1) << 43)
 #define HCR_E2H(UL(1) << 34)
 #define HCR_ID (UL(1) << 33)
 #define HCR_CD (UL(1) << 32)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 19d6a6e..59f9cc6 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -906,10 +906,21 @@ static inline void access_rw(struct sys_reg_params *p, 
u64 *sysreg)
*sysreg = p->regval;
 }
 
+static bool forward_nv1_traps(struct kvm_vcpu *vcpu, struct sys_reg_params *p)
+{
+   if (!vcpu_mode_el2(vcpu) && (vcpu_el2_reg(vcpu, HCR_EL2) & HCR_NV1))
+   return true;
+
+   return false;
+}
+
 static bool access_elr(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
 {
+   if (forward_nv1_traps(vcpu, p))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
access_rw(p, &vcpu->arch.ctxt.gp_regs.elr_el1);
return true;
 }
@@ -918,6 +929,9 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
 {
+   if (forward_nv1_traps(vcpu, p))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
access_rw(p, &vcpu->arch.ctxt.gp_regs.spsr[KVM_SPSR_EL1]);
return true;
 }
@@ -926,6 +940,9 @@ static bool access_vbar(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
 {
+   if (forward_nv1_traps(vcpu, p))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
access_rw(p, &vcpu_sys_reg(vcpu, r->reg));
return true;
 }
-- 
1.9.1




[RFC 19/55] KVM: arm64: Trap CPACR_EL1 access in virtual EL2

2017-01-08 Thread Jintack Lim
For the same reason we trap virtual memory register accesses in virtual
EL2, we trap CPACR_EL1 access too. Basically, we don't want the guest
hypervisor to access the real CPACR_EL1, which is used to emulate
virtual EL2. Instead, we want it to access virtual CPACR_EL1 which is
used to run software in EL0/EL1 from the guest hypervisor's perspective.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/hyp/switch.c | 10 +++---
 arch/arm64/kvm/sys_regs.c   | 10 +-
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index c05c48f..b7c8c30 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -41,7 +41,8 @@ bool __hyp_text __fpsimd_enabled(void)
return __fpsimd_is_enabled()();
 }
 
-static void __hyp_text __activate_traps_vhe(void)
+static void __hyp_text __activate_traps_vhe(struct kvm_vcpu *vcpu)
+
 {
u64 val;
 
@@ -53,12 +54,15 @@ static void __hyp_text __activate_traps_vhe(void)
write_sysreg(__kvm_hyp_vector, vbar_el1);
 }
 
-static void __hyp_text __activate_traps_nvhe(void)
+static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
+
 {
u64 val;
 
val = CPTR_EL2_DEFAULT;
val |= CPTR_EL2_TTA | CPTR_EL2_TFP;
+   if (vcpu_mode_el2(vcpu))
+   val |= CPTR_EL2_TCPAC;
write_sysreg(val, cptr_el2);
 }
 
@@ -90,7 +94,7 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
/* Make sure we trap PMU access from EL0 to EL2 */
write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
-   __activate_traps_arch()();
+   __activate_traps_arch()(vcpu);
 }
 
 static void __hyp_text __deactivate_traps_vhe(void)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 59f9cc6..321ecbc 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -947,6 +947,14 @@ static bool access_vbar(struct kvm_vcpu *vcpu,
return true;
 }
 
+static bool access_cpacr(struct kvm_vcpu *vcpu,
+   struct sys_reg_params *p,
+   const struct sys_reg_desc *r)
+{
+   access_rw(p, &vcpu_sys_reg(vcpu, r->reg));
+   return true;
+}
+
 static bool trap_el2_reg(struct kvm_vcpu *vcpu,
 struct sys_reg_params *p,
 const struct sys_reg_desc *r)
@@ -1051,7 +1059,7 @@ static bool trap_el2_reg(struct kvm_vcpu *vcpu,
  access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 },
/* CPACR_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b), Op2(0b010),
- NULL, reset_val, CPACR_EL1, 0 },
+ access_cpacr, reset_val, CPACR_EL1, 0 },
/* TTBR0_EL1 */
{ Op0(0b11), Op1(0b000), CRn(0b0010), CRm(0b), Op2(0b000),
  access_vm_reg, reset_unknown, TTBR0_EL1 },
-- 
1.9.1




[RFC 15/55] KVM: arm64: Trap EL1 VM register accesses in virtual EL2

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When running in virtual EL2 mode, we actually run the hardware in EL1
and therefore have to use the EL1 registers to ensure correct operation.

By setting the HCR.TVM and HCR.TVRM we ensure that the virtual EL2 mode
doesn't shoot itself in the foot when setting up what it believes to be
a different mode's system register state (for example when preparing to
switch to a VM).

We can leverage the existing sysregs infrastructure to support trapped
accesses to these registers.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/hyp/switch.c | 2 ++
 arch/arm64/kvm/sys_regs.c   | 7 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 83037cd..c05c48f 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -82,6 +82,8 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
write_sysreg(1 << 30, fpexc32_el2);
isb();
}
+   if (vcpu_mode_el2(vcpu))
+   val |= HCR_TVM | HCR_TRVM;
write_sysreg(val, hcr_el2);
/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
write_sysreg(1 << 15, hstr_el2);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 202f64d..b8e993a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -101,7 +101,12 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 {
bool was_enabled = vcpu_has_cache_enabled(vcpu);
 
-   BUG_ON(!p->is_write);
+   BUG_ON(!vcpu_mode_el2(vcpu) && !p->is_write);
+
+   if (!p->is_write) {
+   p->regval = vcpu_sys_reg(vcpu, r->reg);
+   return true;
+   }
 
if (!p->is_aarch32) {
vcpu_sys_reg(vcpu, r->reg) = p->regval;
-- 
1.9.1




[RFC 20/55] KVM: arm64: Forward CPACR_EL1 traps to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward CPACR_EL1 traps to the guest hypervisor if it has configured the
virtual CPTR_EL2 to do so.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/sys_regs.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 321ecbc..e66f40d 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -951,6 +951,11 @@ static bool access_cpacr(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
 {
+   /* Forward this trap to the guest hypervisor if it expects */
+   if (!vcpu_mode_el2(vcpu) &&
+   (vcpu_el2_reg(vcpu, CPTR_EL2) & CPTR_EL2_TCPAC))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
access_rw(p, &vcpu_sys_reg(vcpu, r->reg));
return true;
 }
-- 
1.9.1




[RFC 31/55] KVM: arm/arm64: Inject maintenance interrupts to the guest hypervisor

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

If we exit a nested VM with a pending maintenance interrupt from the
GIC, then we need to forward this to the guest hypervisor so that it can
re-sync the appropriate LRs and sample level triggered interrupts again.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c   |  3 +++
 include/kvm/arm_vgic.h |  2 ++
 virt/kvm/arm/vgic/vgic-v2-nested.c | 16 
 3 files changed, 21 insertions(+)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 7a94c9d..a93ffe4 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -140,6 +140,9 @@ static void sync_shadow_el1_state(struct kvm_vcpu *vcpu, 
bool setup)
 void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+
+   vgic_handle_nested_maint_irq(vcpu);
+
if (unlikely(vcpu_mode_el2(vcpu))) {
ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 484f6b1..fc882d6 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -315,9 +315,11 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, 
unsigned int intid,
 #ifdef CONFIG_KVM_ARM_NESTED_HYP
 void vgic_v2_setup_shadow_state(struct kvm_vcpu *vcpu);
 void vgic_v2_restore_shadow_state(struct kvm_vcpu *vcpu);
+void vgic_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
 #else
 static inline void vgic_v2_setup_shadow_state(struct kvm_vcpu *vcpu) { }
 static inline void vgic_v2_restore_shadow_state(struct kvm_vcpu *vcpu) { }
+static inline void vgic_handle_nested_maint_irq(struct kvm_vcpu *vcpu) { }
 #endif
 
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
diff --git a/virt/kvm/arm/vgic/vgic-v2-nested.c 
b/virt/kvm/arm/vgic/vgic-v2-nested.c
index a992da5..85f646b 100644
--- a/virt/kvm/arm/vgic/vgic-v2-nested.c
+++ b/virt/kvm/arm/vgic/vgic-v2-nested.c
@@ -300,6 +300,22 @@ void vgic_v2_restore_shadow_state(struct kvm_vcpu *vcpu)
vgic_cpu->nested_vgic_v2 = vgic_cpu->shadow_vgic_v2;
 }
 
+void vgic_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
+{
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+
+   /*
+* If we exit a nested VM with a pending maintenance interrupt from the
+* GIC, then we need to forward this to the guest hypervisor so that it
+* can re-sync the appropriate LRs and sample level triggered interrupts
+* again.
+*/
+   if (vcpu_el2_imo_is_set(vcpu) && !vcpu_mode_el2(vcpu) &&
+   (cpu_if->vgic_hcr & GICH_HCR_EN) &&
+   vgic_mmio_read_v2_misr(vcpu, 0, 0))
+   kvm_inject_nested_irq(vcpu);
+}
+
 void vgic_init_nested(struct kvm_vcpu *vcpu)
 {
vgic_v2_setup_shadow_state(vcpu);
-- 
1.9.1




[RFC 22/55] KVM: arm64: Handle PSCI call from the guest

2017-01-08 Thread Jintack Lim
VMs used to execute hvc #0 for the psci call. However, when we come to
provide virtual EL2 to the VM, the host OS inside the VM also calls
kvm_call_hyp which is also hvc #0. So, it's hard to differentiate
between them from the host hypervisor's point of view.

So, let the VM execute smc for the psci call. On ARMv8.3, even if EL3 is
not implemented, a smc instruction executed at non-secure EL1 is trapped
to EL2 if HCR_EL2.TSC==1, rather than being treated as UNDEFINED. So,
the host hypervisor can handle this psci call without any confusion.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/handle_exit.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 208be16..ce6d2ef 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -64,8 +64,27 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run 
*run)
 
 static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-   kvm_inject_undefined(vcpu);
-   return 1;
+   int ret;
+
+   /* If imm is non-zero, it's not defined */
+   if (kvm_vcpu_hvc_get_imm(vcpu)) {
+   kvm_inject_undefined(vcpu);
+   return 1;
+   }
+
+   /*
+* If imm is zero, it's a psci call.
+* Note that on ARMv8.3, even if EL3 is not implemented, SMC executed
+* at Non-secure EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than
+* being treated as UNDEFINED.
+*/
+   ret = kvm_psci_call(vcpu);
+   if (ret < 0) {
+   kvm_inject_undefined(vcpu);
+   return 1;
+   }
+
+   return ret;
 }
 
 /**
-- 
1.9.1




[RFC 21/55] KVM: arm64: Forward HVC instruction to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward exceptions due to hvc instruction to the guest hypervisor.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_nested.h |  5 +
 arch/arm64/kvm/Makefile |  1 +
 arch/arm64/kvm/handle_exit.c| 11 +++
 arch/arm64/kvm/handle_exit_nested.c | 27 +++
 4 files changed, 44 insertions(+)
 create mode 100644 arch/arm64/include/asm/kvm_nested.h
 create mode 100644 arch/arm64/kvm/handle_exit_nested.c

diff --git a/arch/arm64/include/asm/kvm_nested.h 
b/arch/arm64/include/asm/kvm_nested.h
new file mode 100644
index 000..620b4d3
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -0,0 +1,5 @@
+#ifndef __ARM64_KVM_NESTED_H__
+#define __ARM64_KVM_NESTED_H__
+
+int handle_hvc_nested(struct kvm_vcpu *vcpu);
+#endif
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index b342bdd..9c35e9a 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -35,4 +35,5 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
 kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
 
+kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += handle_exit_nested.o
 kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += emulate-nested.o
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index a891684..208be16 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -29,6 +29,10 @@
 #include 
 #include 
 
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+#include 
+#endif
+
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
@@ -42,6 +46,13 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run 
*run)
kvm_vcpu_hvc_get_imm(vcpu));
vcpu->stat.hvc_exit_stat++;
 
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+   ret = handle_hvc_nested(vcpu);
+   if (ret < 0 && ret != -EINVAL)
+   return ret;
+   else if (ret >= 0)
+   return ret;
+#endif
ret = kvm_psci_call(vcpu);
if (ret < 0) {
kvm_inject_undefined(vcpu);
diff --git a/arch/arm64/kvm/handle_exit_nested.c 
b/arch/arm64/kvm/handle_exit_nested.c
new file mode 100644
index 000..a6ce23b
--- /dev/null
+++ b/arch/arm64/kvm/handle_exit_nested.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 - Columbia University
+ * Author: Jintack Lim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include 
+#include 
+
+#include 
+
+/* We forward all hvc instruction to the guest hypervisor. */
+int handle_hvc_nested(struct kvm_vcpu *vcpu)
+{
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+}
-- 
1.9.1




Re: [PATCH v11 3/3] fpga: Add support for Lattice iCE40 FPGAs

2017-01-08 Thread kbuild test robot
Hi Joel,

[auto build test WARNING on next-20170106]
[also build test WARNING on v4.10-rc3]
[cannot apply to linus/master linux/master robh/for-next v4.9-rc8 v4.9-rc7 
v4.9-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Joel-Holdsworth/of-Add-vendor-prefix-for-Lattice-Semiconductor/20170109-134955
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=ia64 

All warnings (new ones prefixed by >>):

   drivers/fpga/ice40-spi.c: In function 'ice40_fpga_probe':
>> drivers/fpga/ice40-spi.c:166:45: warning: format '%ld' expects argument of 
>> type 'long int', but argument 3 has type 'int' [-Wformat=]
  dev_err(dev, "Failed to get CDONE GPIO: %ld\n", ret);
^
   drivers/fpga/ice40-spi.c:173:48: warning: format '%ld' expects argument of 
type 'long int', but argument 3 has type 'int' [-Wformat=]
  dev_err(dev, "Failed to get CRESET_B GPIO: %ld\n", ret);
   ^

vim +166 drivers/fpga/ice40-spi.c

   150  
   151  if (spi->max_speed_hz < ICE40_SPI_MIN_SPEED) {
   152  dev_err(dev, "SPI speed is too low, minimum speed is "
   153  __stringify(ICE40_SPI_MIN_SPEED) "\n");
   154  return -EINVAL;
   155  }
   156  
   157  if (spi->mode & SPI_CPHA) {
   158  dev_err(dev, "Bad SPI mode, CPHA not supported\n");
   159  return -EINVAL;
   160  }
   161  
   162  /* Set up the GPIOs */
   163  priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN);
   164  if (IS_ERR(priv->cdone)) {
   165  ret = PTR_ERR(priv->cdone);
 > 166  dev_err(dev, "Failed to get CDONE GPIO: %ld\n", ret);
   167  return ret;
   168  }
   169  
   170  priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
   171  if (IS_ERR(priv->reset)) {
   172  ret = PTR_ERR(priv->reset);
   173  dev_err(dev, "Failed to get CRESET_B GPIO: %ld\n", ret);
   174  return ret;

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[RFC 35/55] KVM: arm/arm64: Support mmu for the virtual EL2 execution

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When running a guest hypervisor in virtual EL2, the translation context
has to be separate from the rest of the system, including the guest
EL1/0 translation regime, so we allocate a separate VMID for this mode.

Considering that we have two different vttbr values due to separate
VMIDs, it's racy to keep a vttbr value in a struct (kvm_s2_mmu) and
share it between multiple vcpus. So, keep the vttbr value per vcpu.

Hypercalls to flush tlb now have vttbr as a parameter instead of mmu,
since mmu structure does not have vttbr any more.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_asm.h   |  6 ++--
 arch/arm/include/asm/kvm_emulate.h   |  4 +++
 arch/arm/include/asm/kvm_host.h  | 14 ++---
 arch/arm/include/asm/kvm_mmu.h   | 11 +++
 arch/arm/kvm/arm.c   | 60 +++-
 arch/arm/kvm/hyp/switch.c|  4 +--
 arch/arm/kvm/hyp/tlb.c   | 15 -
 arch/arm/kvm/mmu.c   |  9 --
 arch/arm64/include/asm/kvm_asm.h |  6 ++--
 arch/arm64/include/asm/kvm_emulate.h |  8 +
 arch/arm64/include/asm/kvm_host.h| 14 ++---
 arch/arm64/include/asm/kvm_mmu.h | 11 +++
 arch/arm64/kvm/hyp/switch.c  |  4 +--
 arch/arm64/kvm/hyp/tlb.c | 16 --
 14 files changed, 112 insertions(+), 70 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 36e3856..aa214f7 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -65,9 +65,9 @@
 extern char __kvm_hyp_vector[];
 
 extern void __kvm_flush_vm_context(void);
-extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa);
-extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
-extern void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu);
+extern void __kvm_tlb_flush_vmid_ipa(u64 vttbr, phys_addr_t ipa);
+extern void __kvm_tlb_flush_vmid(u64 vttbr);
+extern void __kvm_tlb_flush_local_vmid(u64 vttbr);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 05d5906..6285f4f 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -305,4 +305,8 @@ static inline unsigned long vcpu_data_host_to_guest(struct 
kvm_vcpu *vcpu,
}
 }
 
+static inline struct kvm_s2_vmid *vcpu_get_active_vmid(struct kvm_vcpu *vcpu)
+{
+   return &vcpu->kvm->arch.mmu.vmid;
+}
 #endif /* __ARM_KVM_EMULATE_H__ */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index f84a59c..da45394 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -53,16 +53,18 @@
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
 void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
 
-struct kvm_s2_mmu {
+struct kvm_s2_vmid {
/* The VMID generation used for the virt. memory system */
u64vmid_gen;
u32vmid;
+};
+
+struct kvm_s2_mmu {
+   struct kvm_s2_vmid vmid;
+   struct kvm_s2_vmid el2_vmid;
 
/* Stage-2 page table */
pgd_t *pgd;
-
-   /* VTTBR value associated with above pgd and vmid */
-   u64vttbr;
 };
 
 struct kvm_arch {
@@ -196,6 +198,9 @@ struct kvm_vcpu_arch {
 
/* Stage 2 paging state used by the hardware on next switch */
struct kvm_s2_mmu *hw_mmu;
+
+   /* VTTBR value used by the hardware on next switch */
+   u64 hw_vttbr;
 };
 
 struct kvm_vm_stat {
@@ -242,6 +247,7 @@ static inline void 
kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 {
 }
 
+unsigned int get_kvm_vmid_bits(void);
 struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
 struct kvm_vcpu __percpu **kvm_get_running_vcpus(void);
 void kvm_arm_halt_guest(struct kvm *kvm);
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 74a44727..1b3309c 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -230,6 +230,17 @@ static inline unsigned int kvm_get_vmid_bits(void)
return 8;
 }
 
+static inline u64 kvm_get_vttbr(struct kvm_s2_vmid *vmid,
+   struct kvm_s2_mmu *mmu)
+{
+   u64 vmid_field, baddr;
+
+   baddr = virt_to_phys(mmu->pgd);
+   vmid_field = ((u64)vmid->vmid << VTTBR_VMID_SHIFT) &
+   VTTBR_VMID_MASK(get_kvm_vmid_bits());
+   return baddr | vmid_field;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ARM_KVM_MMU_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index eb3e709..aa8771d 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -75,6 +75,11 @@ static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
__this_cpu_write(kvm_arm_running_vcpu, vcpu);
 }
 
+unsigned int get_kvm_vmid_bits(void)
+{
+   return kvm_vmid_bits;
+}
+
 /**
  * kvm_arm_get_running_vcpu - get the vcpu running on the current CPU.
  * Must be called from non-

[RFC 34/55] KVM: arm/arm64: Abstract stage-2 MMU state into a separate structure

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Abstract stage-2 MMU state into a separate structure and change all
callers referring to page tables, VMIDs, and the VTTBR to use this new
indirection.

This is about to become very handy when using shadow stage-2 page
tables.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_asm.h|   7 +-
 arch/arm/include/asm/kvm_host.h   |  26 ---
 arch/arm/kvm/arm.c|  34 +
 arch/arm/kvm/hyp/switch.c |   5 +-
 arch/arm/kvm/hyp/tlb.c|  18 ++---
 arch/arm/kvm/mmu.c| 146 +-
 arch/arm64/include/asm/kvm_asm.h  |   7 +-
 arch/arm64/include/asm/kvm_host.h |  10 ++-
 arch/arm64/kvm/hyp/switch.c   |   5 +-
 arch/arm64/kvm/hyp/tlb.c  |  20 +++---
 10 files changed, 159 insertions(+), 119 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 8ef0538..36e3856 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -57,6 +57,7 @@
 #ifndef __ASSEMBLY__
 struct kvm;
 struct kvm_vcpu;
+struct kvm_s2_mmu;
 
 extern char __kvm_hyp_init[];
 extern char __kvm_hyp_init_end[];
@@ -64,9 +65,9 @@
 extern char __kvm_hyp_vector[];
 
 extern void __kvm_flush_vm_context(void);
-extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
-extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
-extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
+extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa);
+extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
+extern void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index d5423ab..f84a59c 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -53,9 +53,21 @@
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
 void kvm_reset_coprocs(struct kvm_vcpu *vcpu);
 
-struct kvm_arch {
-   /* VTTBR value associated with below pgd and vmid */
+struct kvm_s2_mmu {
+   /* The VMID generation used for the virt. memory system */
+   u64vmid_gen;
+   u32vmid;
+
+   /* Stage-2 page table */
+   pgd_t *pgd;
+
+   /* VTTBR value associated with above pgd and vmid */
u64vttbr;
+};
+
+struct kvm_arch {
+   /* Stage 2 paging state for the VM */
+   struct kvm_s2_mmu mmu;
 
/* The last vcpu id that ran on each physical CPU */
int __percpu *last_vcpu_ran;
@@ -68,13 +80,6 @@ struct kvm_arch {
 * here.
 */
 
-   /* The VMID generation used for the virt. memory system */
-   u64vmid_gen;
-   u32vmid;
-
-   /* Stage-2 page table */
-   pgd_t *pgd;
-
/* Interrupt controller */
struct vgic_distvgic;
int max_vcpus;
@@ -188,6 +193,9 @@ struct kvm_vcpu_arch {
 
/* Detect first run of a vcpu */
bool has_run_once;
+
+   /* Stage 2 paging state used by the hardware on next switch */
+   struct kvm_s2_mmu *hw_mmu;
 };
 
 struct kvm_vm_stat {
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 436bf5a..eb3e709 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -139,7 +139,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm_timer_init(kvm);
 
/* Mark the initial VMID generation invalid */
-   kvm->arch.vmid_gen = 0;
+   kvm->arch.mmu.vmid_gen = 0;
 
/* The maximum number of VCPUs is limited by the host's GIC model */
kvm->arch.max_vcpus = vgic_present ?
@@ -321,6 +321,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 
kvm_arm_reset_debug_ptr(vcpu);
 
+   vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
+
return 0;
 }
 
@@ -335,7 +337,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 * over-invalidation doesn't affect correctness.
 */
if (*last_ran != vcpu->vcpu_id) {
-   kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu);
+   kvm_call_hyp(__kvm_tlb_flush_local_vmid, &vcpu->kvm->arch.mmu);
*last_ran = vcpu->vcpu_id;
}
 
@@ -423,25 +425,26 @@ void force_vm_exit(const cpumask_t *mask)
  * VMID for the new generation, we must flush necessary caches and TLBs on all
  * CPUs.
  */
-static bool need_new_vmid_gen(struct kvm *kvm)
+static bool need_new_vmid_gen(struct kvm_s2_mmu *mmu)
 {
-   return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen));
+   return unlikely(mmu->vmid_gen != atomic64_read(&kvm_vmid_gen));
 }
 
 /**
  * update_vttbr - Update the VTTBR with a valid VMID before the guest runs
- * @kvmThe guest that we are about to run
+ * @kvm:   The guest that we are about to run
+ * @mmu:   The stage-2 translation context to update
  *
  * Called from kvm_arch_vcpu_ioctl_run before entering the guest to ensure the
  * V

[RFC 37/55] KVM: arm64: Setup vttbr_el2 on each VM entry

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Now that the vttbr value will be different depending on the VM's
exception level, we set it on each VM entry.

We only have one mmu instance at this point, but there will be
multiple of them when we run nested VMs.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index a93ffe4..b2c0220 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct el1_el2_map {
enum vcpu_sysregel1;
@@ -88,6 +89,15 @@ static void create_shadow_el1_sysregs(struct kvm_vcpu *vcpu)
s_sys_regs[CPACR_EL1] = cptr_el2_to_cpacr_el1(el2_regs[CPTR_EL2]);
 }
 
+static void setup_s2_mmu(struct kvm_vcpu *vcpu)
+{
+   struct kvm_s2_mmu *mmu = &vcpu->kvm->arch.mmu;
+   struct kvm_s2_vmid *vmid = vcpu_get_active_vmid(vcpu);
+
+   vcpu->arch.hw_vttbr = kvm_get_vttbr(vmid, mmu);
+   vcpu->arch.hw_mmu = mmu;
+}
+
 /*
  * List of EL1 registers which we allow the virtual EL2 mode to access
  * directly without trapping and which haven't been paravirtualized.
@@ -166,6 +176,8 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
}
 
vgic_v2_setup_shadow_state(vcpu);
+
+   setup_s2_mmu(vcpu);
 }
 
 /**
-- 
1.9.1




BUG: 4.10 i915 drm display noise regression - bisected to a6a7cc4b7

2017-01-08 Thread lkml
Hello all,

I'm experiencing display noise in the form of 8x1 pixel bars spuriously
appearing in random locations.  This doesn't happen on 4.9, the machine
is an X61s, a Core2Duo 1.8Ghz w/XGA via LVDS.

I was able to bisect the issue to a6a7cc4b7:

commit a6a7cc4b7db6deaeca11cdd38844ea147a354c7a
Author: Chris Wilson 
Date:   Fri Nov 18 21:17:46 2016 +

drm/i915: Always flush the dirty CPU cache when pinning the scanout

Currently we only clflush the scanout if it is in the CPU domain. Also
flush if we have a pending CPU clflush. We also want to treat the
dirtyfb path similar, and flush any pending writes there as well.

v2: Only send the fb flush message if flushing the dirt on flip
v3: Make flush-for-flip and dirtyfb look more alike since they serve
similar roles as end-of-frame marker.

Reproduction is simple, just run this native drm eye candy program:
https://github.com/vcaputo/rototiller

Thanks,
Vito Caputo


[RFC 32/55] KVM: arm/arm64: register GICH iodev for the guest hypervisor

2017-01-08 Thread Jintack Lim
Register a device for the virtual interface control block(GICH) access
from the guest hypervisor.

TODO: Get GICH address from DT, which is hardcoded now.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/uapi/asm/kvm.h  |  6 ++
 include/kvm/arm_vgic.h |  5 -
 virt/kvm/arm/vgic/vgic-mmio.c  |  6 ++
 virt/kvm/arm/vgic/vgic-v2-nested.c | 24 
 virt/kvm/arm/vgic/vgic-v2.c|  7 +++
 virt/kvm/arm/vgic/vgic.h   |  6 ++
 6 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index 78117bf..3995d3d 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -99,6 +99,12 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PMU_V33 /* Support guest PMUv3 */
 #define KVM_ARM_VCPU_NESTED_VIRT   4 /* Support nested virtual EL2 */
 
+/* FIXME: This should come from DT */
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+#define KVM_VGIC_V2_GICH_BASE  0x0803
+#define KVM_VGIC_V2_GICH_SIZE  0x2000
+#endif
+
 struct kvm_vcpu_init {
__u32 target;
__u32 features[7];
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index fc882d6..5bda20c 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -125,7 +125,8 @@ enum iodev_type {
IODEV_CPUIF,
IODEV_DIST,
IODEV_REDIST,
-   IODEV_ITS
+   IODEV_ITS,
+   IODEV_GICH,
 };
 
 struct vgic_io_device {
@@ -198,6 +199,8 @@ struct vgic_dist {
 
struct vgic_io_device   dist_iodev;
 
+   struct vgic_io_device   hyp_iodev;
+
boolhas_its;
 
/*
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 049c570..2e4097d 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -512,6 +512,9 @@ static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct 
kvm_io_device *dev,
case IODEV_ITS:
data = region->its_read(vcpu->kvm, iodev->its, addr, len);
break;
+   case IODEV_GICH:
+   data = region->read(vcpu, addr, len);
+   break;
}
 
vgic_data_host_to_mmio_bus(val, len, data);
@@ -543,6 +546,9 @@ static int dispatch_mmio_write(struct kvm_vcpu *vcpu, 
struct kvm_io_device *dev,
case IODEV_ITS:
region->its_write(vcpu->kvm, iodev->its, addr, len, data);
break;
+   case IODEV_GICH:
+   region->write(vcpu, addr, len, data);
+   break;
}
 
return 0;
diff --git a/virt/kvm/arm/vgic/vgic-v2-nested.c 
b/virt/kvm/arm/vgic/vgic-v2-nested.c
index 85f646b..cb55324 100644
--- a/virt/kvm/arm/vgic/vgic-v2-nested.c
+++ b/virt/kvm/arm/vgic/vgic-v2-nested.c
@@ -206,6 +206,30 @@ static void vgic_mmio_write_v2_gich(struct kvm_vcpu *vcpu,
4 * VGIC_V2_MAX_LRS, VGIC_ACCESS_32bit),
 };
 
+int vgic_register_gich_iodev(struct kvm *kvm, struct vgic_dist *dist)
+{
+   struct vgic_io_device *io_device = &kvm->arch.vgic.hyp_iodev;
+   int ret = 0;
+   unsigned int len;
+
+   len = KVM_VGIC_V2_GICH_SIZE;
+
+   io_device->regions = vgic_v2_gich_registers;
+   io_device->nr_regions = ARRAY_SIZE(vgic_v2_gich_registers);
+   kvm_iodevice_init(&io_device->dev, &kvm_io_gic_ops);
+
+   io_device->base_addr = KVM_VGIC_V2_GICH_BASE;
+   io_device->iodev_type = IODEV_GICH;
+   io_device->redist_vcpu = NULL;
+
+   mutex_lock(&kvm->slots_lock);
+   ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, KVM_VGIC_V2_GICH_BASE,
+   len, &io_device->dev);
+   mutex_unlock(&kvm->slots_lock);
+
+   return ret;
+}
+
 /*
  * For LRs which have HW bit set such as timer interrupts, we modify them to
  * have the host hardware interrupt number instead of the virtual one 
programmed
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index 9bab867..b8b73fd 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -280,6 +280,13 @@ int vgic_v2_map_resources(struct kvm *kvm)
goto out;
}
 
+   /* Register virtual GICH interface to kvm io bus */
+   ret = vgic_register_gich_iodev(kvm, dist);
+   if (ret) {
+   kvm_err("Unable to register VGIC GICH regions\n");
+   goto out;
+   }
+
if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) {
ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base,
kvm_vgic_global_state.vcpu_base,
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 2aef680..11d61a7 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -121,8 +121,14 @@ static inline int vgic_its_inject_msi(struct kvm *kvm, 
struct kvm_msi *msi)
 int vgic_init(struct kvm *kvm);
 
 #ifdef CONFIG_KVM_ARM_NESTED_HYP
+int vgic_register_gich_iodev(struct kvm *kvm, s

Re: [PATCH] ACPI/IORT: Fix iort_node_get_id() mapping entries indexing

2017-01-08 Thread Hanjun Guo

Hi Sinan,

On 2017/1/8 5:09, Sinan Kaya wrote:

On 1/5/2017 1:29 PM, Lorenzo Pieralisi wrote:

Commit 618f535a6062 ("ACPI/IORT: Add single mapping function")
introduced a function (iort_node_get_id()) to retrieve ids for IORT
named components.

iort_node_get_id() takes an index as input to refer to a specific
mapping entry in the mapping array to retrieve the id at a specific
index provided the index is below the total mapping count; currently the
index is used to retrieve the mapping value from the correct entry but
not to dereference the correct entry while retrieving the mapping
output_reference (ie IORT parent pointer), which consequently always
resolves to the output_reference of the first entry in the mapping
array.

Update the map array entry pointer computation in iort_node_get_id() to
take into account the index value, fixing the issue.

Fixes: 618f535a6062 ("ACPI/IORT: Add single mapping function")
Reported-by: Hanjun Guo 
Signed-off-by: Lorenzo Pieralisi 
Cc: Hanjun Guo 
Cc: Sinan Kaya 
Cc: Tomasz Nowicki 
Cc: Nate Watterson 
Cc: "Rafael J. Wysocki" 
---
 drivers/acpi/arm64/iort.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index e0d2e6e..ba156c5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -333,7 +333,7 @@ struct acpi_iort_node *iort_node_get_id(struct 
acpi_iort_node *node,
return NULL;

map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
-  node->mapping_offset);
+  node->mapping_offset + index * sizeof(*map));


What does this give us that the previous code didn't do?


Fir example, if you have multi mappings ids under platform device:

|-|
|  SMMU  2|<---
|-|   |
  |
  |
|-|   |
|  SMMU 1 |<  |
|-||  |
   |  |
   |  |
|-||  |
|  platform   ||  |
|  device ||  |
|-||  |
| stream id   ||  |
| 1   ||  |
| parent--||  |
|-|   |
|  stream id  |   |
|  2  |   |
|  parent-|---|
|-|

For now, we just use the first entry in the mapping entry to get
the parent, and always point to the same parent, as above, we will
always map to SMMU 1 even if you connect to different SMMUs. (Although
we may don't have such device topology yet)




You are using map as a pointer and returning the offset of the first map entry 
above
and then accessing the map at the indexed offset with map[index]

The new code is using map as a plain pointer, calculating the pointer location 
with ACPI_ADD_PTR
instead and then collecting the output parameter with map->output_base.



/* Firmware bug! */
if (!map->output_reference) {
@@ -348,10 +348,10 @@ struct acpi_iort_node *iort_node_get_id(struct 
acpi_iort_node *node,
if (!(IORT_TYPE_MASK(parent->type) & type_mask))
return NULL;

-   if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+   if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
-   *id_out = map[index].output_base;
+   *id_out = map->output_base;


You are claiming that the existing code is collecting the output parameter from 
the first mapping.
I don't see this happening above.

What am I missing?


It's not about the output id but it's about the parent returned
by this function, it always return the first entry's parent in the
mapping entry.




return parent;
}
}



If we are just doing a housekeeping, this is fine. I couldn't see an actual bug 
getting fixed.


Although we may don't have such use cases for now, but I think we
need to prepare for it, it worth a bugfix I think :)

Thanks
Hanjun


[RFC 27/55] KVM: arm/arm64: Emulate GICH interface on GICv2

2017-01-08 Thread Jintack Lim
Emulate GICH interface accesses from the guest hypervisor.

Signed-off-by: Jintack Lim 
Signed-off-by: Shih-Wei Li 
Signed-off-by: Christoffer Dall 
---
 arch/arm64/kvm/Makefile|   1 +
 virt/kvm/arm/vgic/vgic-v2-nested.c | 207 +
 2 files changed, 208 insertions(+)
 create mode 100644 virt/kvm/arm/vgic/vgic-v2-nested.c

diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 9c35e9a..8573faf 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -37,3 +37,4 @@ kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
 
 kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += handle_exit_nested.o
 kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += emulate-nested.o
+kvm-$(CONFIG_KVM_ARM_NESTED_HYP) += $(KVM)/arm/vgic/vgic-v2-nested.o
diff --git a/virt/kvm/arm/vgic/vgic-v2-nested.c 
b/virt/kvm/arm/vgic/vgic-v2-nested.c
new file mode 100644
index 000..b13128e
--- /dev/null
+++ b/virt/kvm/arm/vgic/vgic-v2-nested.c
@@ -0,0 +1,207 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "vgic.h"
+#include "vgic-mmio.h"
+
+static inline struct vgic_v2_cpu_if *vcpu_nested_if(struct kvm_vcpu *vcpu)
+{
+   return &vcpu->arch.vgic_cpu.nested_vgic_v2;
+}
+
+static inline struct vgic_v2_cpu_if *vcpu_shadow_if(struct kvm_vcpu *vcpu)
+{
+   return &vcpu->arch.vgic_cpu.shadow_vgic_v2;
+}
+
+static unsigned long vgic_mmio_read_v2_vtr(struct kvm_vcpu *vcpu,
+  gpa_t addr, unsigned int len)
+{
+   u32 reg;
+
+   reg = kvm_vgic_global_state.nr_lr - 1;
+   reg |= 0b100 << 26;
+   reg |= 0b100 << 29;
+
+   return reg;
+}
+
+static inline bool lr_triggers_eoi(u32 lr)
+{
+   return !(lr & (GICH_LR_STATE | GICH_LR_HW)) && (lr & GICH_LR_EOI);
+}
+
+static unsigned long get_eisr(struct kvm_vcpu *vcpu, bool upper_reg)
+{
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+   int max_lr = upper_reg ? 64 : 32;
+   int min_lr = upper_reg ? 32 : 0;
+   int nr_lr = min(kvm_vgic_global_state.nr_lr, max_lr);
+   int i;
+   u32 reg = 0;
+
+   for (i = min_lr; i < nr_lr; i++) {
+   if (lr_triggers_eoi(cpu_if->vgic_lr[i]))
+   reg |= BIT(i - min_lr);
+   }
+
+   return reg;
+}
+
+static unsigned long vgic_mmio_read_v2_eisr0(struct kvm_vcpu *vcpu,
+gpa_t addr, unsigned int len)
+{
+   return get_eisr(vcpu, false);
+}
+
+static unsigned long vgic_mmio_read_v2_eisr1(struct kvm_vcpu *vcpu,
+gpa_t addr, unsigned int len)
+{
+   return get_eisr(vcpu, true);
+}
+
+static u32 get_elrsr(struct kvm_vcpu *vcpu, bool upper_reg)
+{
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+   int max_lr = upper_reg ? 64 : 32;
+   int min_lr = upper_reg ? 32 : 0;
+   int nr_lr = min(kvm_vgic_global_state.nr_lr, max_lr);
+   u32 reg = 0;
+   int i;
+
+   for (i = min_lr; i < nr_lr; i++) {
+   if (!(cpu_if->vgic_lr[i] & GICH_LR_STATE))
+   reg |= BIT(i - min_lr);
+   }
+
+   return reg;
+}
+
+static unsigned long vgic_mmio_read_v2_elrsr0(struct kvm_vcpu *vcpu,
+ gpa_t addr, unsigned int len)
+{
+   return get_elrsr(vcpu, false);
+}
+
+static unsigned long vgic_mmio_read_v2_elrsr1(struct kvm_vcpu *vcpu,
+ gpa_t addr, unsigned int len)
+{
+   return get_elrsr(vcpu, true);
+}
+
+static unsigned long vgic_mmio_read_v2_misr(struct kvm_vcpu *vcpu,
+   gpa_t addr, unsigned int len)
+{
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+   int nr_lr = kvm_vgic_global_state.nr_lr;
+   u32 reg = 0;
+
+   if (vgic_mmio_read_v2_eisr0(vcpu, addr, len) ||
+   vgic_mmio_read_v2_eisr1(vcpu, addr, len))
+   reg |= GICH_MISR_EOI;
+
+   if (cpu_if->vgic_hcr & GICH_HCR_UIE) {
+   u32 elrsr0 = vgic_mmio_read_v2_elrsr0(vcpu, addr, len);
+   u32 elrsr1 = vgic_mmio_read_v2_elrsr1(vcpu, addr, len);
+   int used_lrs;
+
+   used_lrs = nr_lr - (hweight32(elrsr0) + hweight32(elrsr1));
+   if (used_lrs <= 1)
+   reg |= GICH_MISR_U;
+   }
+
+   /* TODO: Support remaining bits in this register */
+   return reg;
+}
+
+static unsigned long vgic_mmio_read_v2_gich(struct kvm_vcpu *vcpu,
+   gpa_t addr, unsigned int len)
+{
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+   u32 value;
+
+   switch (addr & 0xfff) {
+   case GICH_HCR:
+   value = cpu_if->vgic_hcr;
+   break;
+   case GICH_VMCR:
+   value = cpu_if->vgic_vmcr;
+   break;
+   case GICH_APR:
+   value =

[RFC 45/55] KVM: arm64: KVM: Inject stage-2 page faults

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Inject stage-2 page faults to the guest hypervisor.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/esr.h |  1 +
 arch/arm64/kvm/mmu-nested.c  | 30 --
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index f32e3a7..6104e31 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -107,6 +107,7 @@
 #define ESR_ELx_CM (UL(1) << 8)
 
 /* ISS field definitions for exceptions taken in to Hyp */
+#define ESR_ELx_FSC_ADDRSZ (0x00)
 #define ESR_ELx_CV (UL(1) << 24)
 #define ESR_ELx_COND_SHIFT (20)
 #define ESR_ELx_COND_MASK  (UL(0xF) << ESR_ELx_COND_SHIFT)
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index a2fab41..b161b55 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -55,22 +55,40 @@ static unsigned int pa_max(void)
 static int vcpu_inject_s2_trans_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
  int level)
 {
-   /* TODO: Implement */
-   return -EFAULT;
+   u32 esr;
+
+   vcpu->arch.ctxt.el2_regs[FAR_EL2] = vcpu->arch.fault.far_el2;
+   vcpu->arch.ctxt.el2_regs[HPFAR_EL2] = vcpu->arch.fault.hpfar_el2;
+   esr = kvm_vcpu_get_hsr(vcpu) & ~ESR_ELx_FSC;
+   esr |= ESR_ELx_FSC_FAULT;
+   esr |= level & 0x3;
+   return kvm_inject_nested_sync(vcpu, esr);
 }
 
 static int vcpu_inject_s2_addr_sz_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
int level)
 {
-   /* TODO: Implement */
-   return -EFAULT;
+   u32 esr;
+
+   vcpu->arch.ctxt.el2_regs[FAR_EL2] = vcpu->arch.fault.far_el2;
+   vcpu->arch.ctxt.el2_regs[HPFAR_EL2] = vcpu->arch.fault.hpfar_el2;
+   esr = kvm_vcpu_get_hsr(vcpu) & ~ESR_ELx_FSC;
+   esr |= ESR_ELx_FSC_ADDRSZ;
+   esr |= level & 0x3;
+   return kvm_inject_nested_sync(vcpu, esr);
 }
 
 static int vcpu_inject_s2_access_flag_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
int level)
 {
-   /* TODO: Implement */
-   return -EFAULT;
+   u32 esr;
+
+   vcpu->arch.ctxt.el2_regs[FAR_EL2] = vcpu->arch.fault.far_el2;
+   vcpu->arch.ctxt.el2_regs[HPFAR_EL2] = vcpu->arch.fault.hpfar_el2;
+   esr = kvm_vcpu_get_hsr(vcpu) & ~ESR_ELx_FSC;
+   esr |= ESR_ELx_FSC_ACCESS;
+   esr |= level & 0x3;
+   return kvm_inject_nested_sync(vcpu, esr);
 }
 
 static int check_base_s2_limits(struct kvm_vcpu *vcpu, struct s2_walk_info *wi,
-- 
1.9.1




[RFC 36/55] KVM: arm64: Invalidate virtual EL2 TLB entries when needed

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Sometimes when we are invalidating the TLB for a certain S2 MMU
context, this context can also have EL2 context associated with it and
we have to invalidate this too.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/kvm/arm.c |  6 ++
 arch/arm/kvm/mmu.c | 16 
 2 files changed, 22 insertions(+)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index aa8771d..371b38e7 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -350,6 +350,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
u64 vttbr = kvm_get_vttbr(&mmu->vmid, mmu);
 
kvm_call_hyp(__kvm_tlb_flush_local_vmid, vttbr);
+#ifndef CONFIG_KVM_ARM_NESTED_HYP
+   if (mmu->el2_vmid.vmid) {
+   vttbr = kvm_get_vttbr(&mmu->el2_vmid, mmu);
+   kvm_call_hyp(__kvm_tlb_flush_local_vmid, vttbr);
+   }
+#endif
*last_ran = vcpu->vcpu_id;
}
 
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 5ca3a04..56358fa 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -60,10 +60,20 @@ static bool memslot_is_logging(struct kvm_memory_slot 
*memslot)
  */
 void kvm_flush_remote_tlbs(struct kvm *kvm)
 {
+#ifndef CONFIG_KVM_ARM_NESTED_HYP
struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
u64 vttbr = kvm_get_vttbr(&mmu->vmid, mmu);
 
kvm_call_hyp(__kvm_tlb_flush_vmid, vttbr);
+#else
+   /*
+* When supporting nested virtualization, we can have multiple VMIDs
+* in play for each VCPU in the VM, so it's really not worth it to try
+* to quiesce the system and flush all the VMIDs that may be in use,
+* instead just nuke the whole thing.
+*/
+   kvm_call_hyp(__kvm_flush_vm_context);
+#endif
 }
 
 static void kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa)
@@ -71,6 +81,12 @@ static void kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, 
phys_addr_t ipa)
u64 vttbr = kvm_get_vttbr(&mmu->vmid, mmu);
 
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, vttbr, ipa);
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+   if (!mmu->el2_vmid.vmid)
+   return; /* only if this mmu has el2 context */
+   vttbr = kvm_get_vttbr(&mmu->el2_vmid, mmu);
+   kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, vttbr, ipa);
+#endif
 }
 
 /*
-- 
1.9.1




[RFC 30/55] KVM: arm/arm64: Inject irqs to the guest hypervisor

2017-01-08 Thread Jintack Lim
If we have a pending IRQ for the guest and the guest expects IRQs
to be handled in its virtual EL2 mode (the virtual IMO bit is set)
and it is not already running in virtual EL2 mode, then we have to
emulate an IRQ exception.

Signed-off-by: Jintack Lim 
Signed-off-by: Christoffer Dall 
---
 virt/kvm/arm/vgic/vgic.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 6440b56..4a98654 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vgic.h"
 
@@ -652,6 +653,28 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
/* Nuke remaining LRs */
for ( ; count < kvm_vgic_global_state.nr_lr; count++)
vgic_clear_lr(vcpu, count);
+
+   /*
+* If we have any pending IRQ for the guest and the guest expects IRQs
+* to be handled in its virtual EL2 mode (the virtual IMO bit is set)
+* and it is not already running in virtual EL2 mode, then we have to
+* emulate an IRQ exception to virtual IRQ. Note that a pending IRQ
+* means an irq of which state is pending but not active.
+*/
+   if (vcpu_el2_imo_is_set(vcpu) && !vcpu_mode_el2(vcpu)) {
+   bool pending = false;
+
+   list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
+   spin_lock(&irq->irq_lock);
+   pending = irq->pending && irq->enabled && !irq->active;
+   spin_unlock(&irq->irq_lock);
+
+   if (pending) {
+   kvm_inject_nested_irq(vcpu);
+   break;
+   }
+   }
+   }
 }
 
 /* Sync back the hardware VGIC state into our emulation after a guest's run. */
-- 
1.9.1




[RFC 28/55] KVM: arm/arm64: Prepare vgic state for the nested VM

2017-01-08 Thread Jintack Lim
When entering a nested VM, we set up the hypervisor control interface
based on what the guest hypervisor has set. Especially, we investigate
each list register written by the guest hypervisor whether HW bit is
set.  If so, we translate hw irq number from the guest's point of view
to the real hardware irq number if there is a mapping.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   |  5 ++
 arch/arm64/include/asm/kvm_emulate.h |  5 ++
 arch/arm64/kvm/context.c |  4 ++
 include/kvm/arm_vgic.h   |  8 +++
 virt/kvm/arm/vgic/vgic-init.c|  3 ++
 virt/kvm/arm/vgic/vgic-v2-nested.c   | 99 
 virt/kvm/arm/vgic/vgic.h | 11 
 7 files changed, 135 insertions(+)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 0fa2f5a..05d5906 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -101,6 +101,11 @@ static inline bool vcpu_mode_el2(const struct kvm_vcpu 
*vcpu)
return false;
 }
 
+static inline bool vcpu_el2_imo_is_set(const struct kvm_vcpu *vcpu)
+{
+   return false;
+}
+
 static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
 {
return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_pc;
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 0987ee4..a9c993f 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -178,6 +178,11 @@ static inline bool vcpu_mode_el2(const struct kvm_vcpu 
*vcpu)
return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;
 }
 
+static inline bool vcpu_el2_imo_is_set(const struct kvm_vcpu *vcpu)
+{
+   return (vcpu_el2_reg(vcpu, HCR_EL2) & HCR_IMO);
+}
+
 static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
 {
return vcpu->arch.fault.esr_el2;
diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 0025dd9..7a94c9d 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -161,6 +161,8 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
ctxt->hw_sys_regs = ctxt->sys_regs;
ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
}
+
+   vgic_v2_setup_shadow_state(vcpu);
 }
 
 /**
@@ -179,6 +181,8 @@ void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
*vcpu_cpsr(vcpu) = ctxt->hw_pstate;
ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
}
+
+   vgic_v2_restore_shadow_state(vcpu);
 }
 
 void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 9a9cb27..484f6b1 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -312,6 +312,14 @@ int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid, 
unsigned int intid,
 
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+void vgic_v2_setup_shadow_state(struct kvm_vcpu *vcpu);
+void vgic_v2_restore_shadow_state(struct kvm_vcpu *vcpu);
+#else
+static inline void vgic_v2_setup_shadow_state(struct kvm_vcpu *vcpu) { }
+static inline void vgic_v2_restore_shadow_state(struct kvm_vcpu *vcpu) { }
+#endif
+
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)((k)->arch.vgic.initialized)
 #define vgic_ready(k)  ((k)->arch.vgic.ready)
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 8cebfbc..06ab8a5 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -216,6 +216,9 @@ static void kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
irq->config = VGIC_CONFIG_LEVEL;
}
}
+
+   vgic_init_nested(vcpu);
+
if (kvm_vgic_global_state.type == VGIC_V2)
vgic_v2_enable(vcpu);
else
diff --git a/virt/kvm/arm/vgic/vgic-v2-nested.c 
b/virt/kvm/arm/vgic/vgic-v2-nested.c
index b13128e..a992da5 100644
--- a/virt/kvm/arm/vgic/vgic-v2-nested.c
+++ b/virt/kvm/arm/vgic/vgic-v2-nested.c
@@ -205,3 +205,102 @@ static void vgic_mmio_write_v2_gich(struct kvm_vcpu *vcpu,
vgic_mmio_read_v2_gich, vgic_mmio_write_v2_gich,
4 * VGIC_V2_MAX_LRS, VGIC_ACCESS_32bit),
 };
+
+/*
+ * For LRs which have HW bit set such as timer interrupts, we modify them to
+ * have the host hardware interrupt number instead of the virtual one 
programmed
+ * by the guest hypervisor.
+ */
+static void vgic_v2_create_shadow_lr(struct kvm_vcpu *vcpu)
+{
+   int i;
+   struct vgic_v2_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+   struct vgic_v2_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
+   struct vgic_irq *irq;
+
+   int nr_lr = kvm_vgic_global_state.nr_lr;
+
+   for (i = 0; i < nr_lr; i++) {
+   u32 lr = cpu_if->vgic_lr[i];
+   int l1_irq;
+
+   if (!(lr & GICH_LR_HW))
+   goto next;
+

[RFC 29/55] KVM: arm/arm64: Set up the prepared vgic state

2017-01-08 Thread Jintack Lim
Since vgic state is properly prepared and is pointed by hw_v2_cpu_if,
let's use it to manipulate vgic.

Signed-off-by: Jintack Lim 
---
 virt/kvm/arm/hyp/vgic-v2-sr.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index c8aeb7b..5d4898f 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -22,10 +22,15 @@
 #include 
 #include 
 
+static __hyp_text struct vgic_v2_cpu_if *__hyp_get_cpu_if(struct kvm_vcpu 
*vcpu)
+{
+   return kern_hyp_va(vcpu->arch.vgic_cpu.hw_v2_cpu_if);
+}
+
 static void __hyp_text save_maint_int_state(struct kvm_vcpu *vcpu,
void __iomem *base)
 {
-   struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+   struct vgic_v2_cpu_if *cpu_if = __hyp_get_cpu_if(vcpu);
int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr;
u32 eisr0, eisr1;
int i;
@@ -67,7 +72,7 @@ static void __hyp_text save_maint_int_state(struct kvm_vcpu 
*vcpu,
 
 static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base)
 {
-   struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+   struct vgic_v2_cpu_if *cpu_if = __hyp_get_cpu_if(vcpu);
int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr;
u32 elrsr0, elrsr1;
 
@@ -86,7 +91,7 @@ static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void 
__iomem *base)
 
 static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
 {
-   struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+   struct vgic_v2_cpu_if *cpu_if = __hyp_get_cpu_if(vcpu);
int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr;
int i;
 
@@ -107,7 +112,7 @@ static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void 
__iomem *base)
 void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
 {
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-   struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+   struct vgic_v2_cpu_if *cpu_if = __hyp_get_cpu_if(vcpu);
struct vgic_dist *vgic = &kvm->arch.vgic;
void __iomem *base = kern_hyp_va(vgic->vctrl_base);
 
@@ -138,7 +143,7 @@ void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
 void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu)
 {
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
-   struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
+   struct vgic_v2_cpu_if *cpu_if = __hyp_get_cpu_if(vcpu);
struct vgic_dist *vgic = &kvm->arch.vgic;
void __iomem *base = kern_hyp_va(vgic->vctrl_base);
int nr_lr = (kern_hyp_va(&kvm_vgic_global_state))->nr_lr;
-- 
1.9.1




[RFC 55/55] KVM: arm64: Enable nested virtualization

2017-01-08 Thread Jintack Lim
Now that everything is ready, we enable nested virtualization by setting
the HCR NV and NV1 bit.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_arm.h | 1 +
 arch/arm64/kvm/hyp/switch.c  | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index f9addf3..ab8b93b 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -24,6 +24,7 @@
 
 /* Hyp Configuration Register (HCR) bits */
 #define HCR_NV1(UL(1) << 43)
+#define HCR_NV (UL(1) << 42)
 #define HCR_E2H(UL(1) << 34)
 #define HCR_ID (UL(1) << 33)
 #define HCR_CD (UL(1) << 32)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index c80b2ae..df7b88d 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -87,7 +87,7 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
isb();
}
if (vcpu_mode_el2(vcpu))
-   val |= HCR_TVM | HCR_TRVM;
+   val |= HCR_TVM | HCR_TRVM | HCR_NV | HCR_NV1;
write_sysreg(val, hcr_el2);
/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
write_sysreg(1 << 15, hstr_el2);
-- 
1.9.1




[RFC 33/55] KVM: arm/arm64: Remove unused params in mmu functions

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

stage2_flush_xxx functions take a pointer to the kvm struct as the first
parameter but they are never used. Clean this up before modifying mmu
code for nested virtualization support.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/kvm/mmu.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index a5265ed..57cb671 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -300,7 +300,7 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t 
start, u64 size)
} while (pgd++, addr = next, addr != end);
 }
 
-static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
+static void stage2_flush_ptes(pmd_t *pmd,
  phys_addr_t addr, phys_addr_t end)
 {
pte_t *pte;
@@ -312,7 +312,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
} while (pte++, addr += PAGE_SIZE, addr != end);
 }
 
-static void stage2_flush_pmds(struct kvm *kvm, pud_t *pud,
+static void stage2_flush_pmds(pud_t *pud,
  phys_addr_t addr, phys_addr_t end)
 {
pmd_t *pmd;
@@ -325,12 +325,12 @@ static void stage2_flush_pmds(struct kvm *kvm, pud_t *pud,
if (pmd_thp_or_huge(*pmd))
kvm_flush_dcache_pmd(*pmd);
else
-   stage2_flush_ptes(kvm, pmd, addr, next);
+   stage2_flush_ptes(pmd, addr, next);
}
} while (pmd++, addr = next, addr != end);
 }
 
-static void stage2_flush_puds(struct kvm *kvm, pgd_t *pgd,
+static void stage2_flush_puds(pgd_t *pgd,
  phys_addr_t addr, phys_addr_t end)
 {
pud_t *pud;
@@ -343,7 +343,7 @@ static void stage2_flush_puds(struct kvm *kvm, pgd_t *pgd,
if (stage2_pud_huge(*pud))
kvm_flush_dcache_pud(*pud);
else
-   stage2_flush_pmds(kvm, pud, addr, next);
+   stage2_flush_pmds(pud, addr, next);
}
} while (pud++, addr = next, addr != end);
 }
@@ -359,7 +359,7 @@ static void stage2_flush_memslot(struct kvm *kvm,
pgd = kvm->arch.pgd + stage2_pgd_index(addr);
do {
next = stage2_pgd_addr_end(addr, end);
-   stage2_flush_puds(kvm, pgd, addr, next);
+   stage2_flush_puds(pgd, addr, next);
} while (pgd++, addr = next, addr != end);
 }
 
-- 
1.9.1




[RFC 53/55] KVM: arm64: Reflect shadow VMPIDR_EL2 value to MPIDR_EL1

2017-01-08 Thread Jintack Lim
A non-secure EL0 or EL1 read of MPIDR_EL1 should return the value of
VMPIDR_EL2. We emulate this by copying the virtual VMPIDR_EL2 value to
MPIDR_EL1 when entering VM's EL0 or EL1.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 9ebc38f..dd79b0e 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -173,6 +173,12 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
ctxt->hw_pstate = *vcpu_cpsr(vcpu);
ctxt->hw_sys_regs = ctxt->sys_regs;
ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+
+   /*
+* A non-secure EL0 or EL1 read of MPIDR_EL1 returns
+* the value of VMPIDR_EL2.
+*/
+   ctxt->hw_sys_regs[MPIDR_EL1] = ctxt->el2_regs[VMPIDR_EL2];
}
 
vgic_v2_setup_shadow_state(vcpu);
-- 
1.9.1




[RFC 41/55] KVM: arm/arm64: Unmap/flush shadow stage 2 page tables

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Unmap/flush shadow stage 2 page tables for the nested VMs as well as the
stage 2 page table for the guest hypervisor.

Note: A bunch of the code in mmu.c relating to MMU notifiers is
currently dealt with in an extremely abrupt way, for example by clearing
out an entire shadow stage-2 table.  Probably we can do smarter with
some sort of rmap structure.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_mmu.h   |  7 
 arch/arm/kvm/arm.c   |  6 ++-
 arch/arm/kvm/mmu.c   | 11 +
 arch/arm64/include/asm/kvm_mmu.h | 13 ++
 arch/arm64/kvm/mmu-nested.c  | 90 
 5 files changed, 117 insertions(+), 10 deletions(-)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 1b3309c..ae3aa39 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -230,6 +230,13 @@ static inline unsigned int kvm_get_vmid_bits(void)
return 8;
 }
 
+static inline void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu) { }
+static inline int kvm_nested_s2_init(struct kvm_vcpu *vcpu) { return 0; }
+static inline void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu) { }
+static inline void kvm_nested_s2_all_vcpus_wp(struct kvm *kvm) { }
+static inline void kvm_nested_s2_all_vcpus_unmap(struct kvm *kvm) { }
+static inline void kvm_nested_s2_all_vcpus_flush(struct kvm *kvm) { }
+
 static inline u64 kvm_get_vttbr(struct kvm_s2_vmid *vmid,
struct kvm_s2_mmu *mmu)
 {
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 6fa5754..dc2795f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -191,6 +191,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
if (kvm->vcpus[i]) {
+   kvm_nested_s2_teardown(kvm->vcpus[i]);
kvm_arch_vcpu_free(kvm->vcpus[i]);
kvm->vcpus[i] = NULL;
}
@@ -333,6 +334,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 
vcpu->arch.hw_mmu = mmu;
vcpu->arch.hw_vttbr = kvm_get_vttbr(&mmu->vmid, mmu);
+   kvm_nested_s2_init(vcpu);
 
return 0;
 }
@@ -871,8 +873,10 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu 
*vcpu,
 * Ensure a rebooted VM will fault in RAM pages and detect if the
 * guest MMU is turned off and flush the caches as needed.
 */
-   if (vcpu->arch.has_run_once)
+   if (vcpu->arch.has_run_once) {
stage2_unmap_vm(vcpu->kvm);
+   kvm_nested_s2_unmap(vcpu);
+   }
 
vcpu_reset_hcr(vcpu);
 
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 98b42e8..1677a87 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -416,6 +416,8 @@ static void stage2_flush_vm(struct kvm *kvm)
kvm_for_each_memslot(memslot, slots)
stage2_flush_memslot(&kvm->arch.mmu, memslot);
 
+   kvm_nested_s2_all_vcpus_flush(kvm);
+
spin_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, idx);
 }
@@ -1240,6 +1242,7 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
 
spin_lock(&kvm->mmu_lock);
kvm_stage2_wp_range(kvm, &kvm->arch.mmu, start, end);
+   kvm_nested_s2_all_vcpus_wp(kvm);
spin_unlock(&kvm->mmu_lock);
kvm_flush_remote_tlbs(kvm);
 }
@@ -1278,6 +1281,7 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm 
*kvm,
gfn_t gfn_offset, unsigned long mask)
 {
kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
+   kvm_nested_s2_all_vcpus_wp(kvm);
 }
 
 static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, kvm_pfn_t pfn,
@@ -1604,6 +1608,7 @@ static int handle_hva_to_gpa(struct kvm *kvm,
 static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
 {
kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, PAGE_SIZE);
+   kvm_nested_s2_all_vcpus_unmap(kvm);
return 0;
 }
 
@@ -1642,6 +1647,7 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t 
gpa, void *data)
 * through this calling path.
 */
stage2_set_pte(&kvm->arch.mmu, NULL, gpa, pte, 0);
+   kvm_nested_s2_all_vcpus_unmap(kvm);
return 0;
 }
 
@@ -1675,6 +1681,8 @@ static int kvm_age_hva_handler(struct kvm *kvm, gpa_t 
gpa, void *data)
if (pte_none(*pte))
return 0;
 
+   /* TODO: Handle nested_mmu structures here as well */
+
return stage2_ptep_test_and_clear_young(pte);
 }
 
@@ -1694,6 +1702,8 @@ static int kvm_test_age_hva_handler(struct kvm *kvm, 
gpa_t gpa, void *data)
if (!pte_none(*pte))/* Just a page... */
return pte_young(*pte);
 
+   /* TODO: Handle nested_mmu structures here as well */
+
return 0;
 }
 
@@ -1959,6 +1969,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 
spin_lock(&kvm->mmu_lock);
 

[RFC 43/55] KVM: arm/arm64: Handle shadow stage 2 page faults

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

If we are faulting on a shadow stage 2 translation, we have to take
extra care in faulting in a page, because we have to collapse the two
levels of stage 2 paging by walking the L2-to-L1 stage 2 page tables in
software.

This approach tries to integrate as much as possible with the existing
code.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   |  7 
 arch/arm/kvm/mmio.c  | 12 +++---
 arch/arm/kvm/mmu.c   | 75 
 arch/arm64/include/asm/kvm_emulate.h |  9 +
 4 files changed, 82 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 6285f4f..dfc53ce 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -309,4 +309,11 @@ static inline struct kvm_s2_vmid 
*vcpu_get_active_vmid(struct kvm_vcpu *vcpu)
 {
return &vcpu->kvm->arch.mmu.vmid;
 }
+
+/* arm architecture doesn't support the nesting */
+static inline bool kvm_is_shadow_s2_fault(struct kvm_vcpu *vcpu)
+{
+   return false;
+}
+
 #endif /* __ARM_KVM_EMULATE_H__ */
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index b6e715f..a1009c2 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -153,7 +153,7 @@ static int decode_hsr(struct kvm_vcpu *vcpu, bool 
*is_write, int *len)
 }
 
 int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
-phys_addr_t fault_ipa)
+phys_addr_t ipa)
 {
unsigned long data;
unsigned long rt;
@@ -182,22 +182,22 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run 
*run,
data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt),
   len);
 
-   trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data);
+   trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, ipa, data);
kvm_mmio_write_buf(data_buf, len, data);
 
-   ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, fault_ipa, len,
+   ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, ipa, len,
   data_buf);
} else {
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, len,
-  fault_ipa, 0);
+  ipa, 0);
 
-   ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_ipa, len,
+   ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, ipa, len,
  data_buf);
}
 
/* Now prepare kvm_run for the potential return to userland. */
run->mmio.is_write  = is_write;
-   run->mmio.phys_addr = fault_ipa;
+   run->mmio.phys_addr = ipa;
run->mmio.len   = len;
 
if (!ret) {
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 1677a87..710ae60 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1072,10 +1072,10 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t 
guest_ipa,
return ret;
 }
 
-static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
+static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, gfn_t gfn,
+   phys_addr_t *ipap)
 {
kvm_pfn_t pfn = *pfnp;
-   gfn_t gfn = *ipap >> PAGE_SHIFT;
 
if (PageTransCompoundMap(pfn_to_page(pfn))) {
unsigned long mask;
@@ -1291,13 +1291,15 @@ static void coherent_cache_guest_page(struct kvm_vcpu 
*vcpu, kvm_pfn_t pfn,
 }
 
 static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
- struct kvm_memory_slot *memslot, unsigned long hva,
- unsigned long fault_status)
+ struct kvm_s2_trans *nested,
+ struct kvm_memory_slot *memslot,
+ unsigned long hva, unsigned long fault_status)
 {
int ret;
bool write_fault, writable, hugetlb = false, force_pte = false;
unsigned long mmu_seq;
-   gfn_t gfn = fault_ipa >> PAGE_SHIFT;
+   phys_addr_t ipa = fault_ipa;
+   gfn_t gfn;
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
struct vm_area_struct *vma;
@@ -1323,9 +1325,23 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, 
phys_addr_t fault_ipa,
return -EFAULT;
}
 
-   if (is_vm_hugetlb_page(vma) && !logging_active) {
+   if (kvm_is_shadow_s2_fault(vcpu)) {
+   ipa = nested->output;
+
+   /*
+* If we're about to create a shadow stage 2 entry, then we
+* can only create huge mapings if the guest hypervior also
+* uses a huge mapping.
+*/
+   if (nested->block_size != PMD_SIZE)
+   force_pte = true;
+   }
+   g

[RFC 39/55] KVM: arm/arm64: Add mmu context for the nesting

2017-01-08 Thread Jintack Lim
Add the shadow stage-2 MMU context to be used for the nesting, but don't
do anything with it yet.

The host hypervisor maintains mmu structures for each nested VM. When
entering a nested VM, the host hypervisor searches for the nested VM's
mmu using vmid as a key. Note that this vmid is from the guest
hypervisor's point of view.

Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_host.h  |  3 ++
 arch/arm/kvm/arm.c   |  1 +
 arch/arm64/include/asm/kvm_emulate.h | 13 -
 arch/arm64/include/asm/kvm_host.h| 19 +
 arch/arm64/include/asm/kvm_mmu.h | 31 
 arch/arm64/kvm/Makefile  |  1 +
 arch/arm64/kvm/context.c |  2 +-
 arch/arm64/kvm/mmu-nested.c  | 55 
 8 files changed, 116 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm64/kvm/mmu-nested.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index da45394..fbde48d 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -82,6 +82,9 @@ struct kvm_arch {
 * here.
 */
 
+   /* Never used on arm but added to be compatible with arm64 */
+   struct list_head nested_mmu_list;
+
/* Interrupt controller */
struct vgic_distvgic;
int max_vcpus;
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 371b38e7..147df97 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -146,6 +146,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
/* Mark the initial VMID generation invalid */
kvm->arch.mmu.vmid.vmid_gen = 0;
kvm->arch.mmu.el2_vmid.vmid_gen = 0;
+   INIT_LIST_HEAD(&kvm->arch.nested_mmu_list);
 
/* The maximum number of VCPUs is limited by the host's GIC model */
kvm->arch.max_vcpus = vgic_present ?
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 94068e7..abad676 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -183,6 +183,11 @@ static inline bool vcpu_el2_imo_is_set(const struct 
kvm_vcpu *vcpu)
return (vcpu_el2_reg(vcpu, HCR_EL2) & HCR_IMO);
 }
 
+static inline bool vcpu_nested_stage2_enabled(const struct kvm_vcpu *vcpu)
+{
+   return (vcpu_el2_reg(vcpu, HCR_EL2) & HCR_VM);
+}
+
 static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
 {
return vcpu->arch.fault.esr_el2;
@@ -363,12 +368,4 @@ static inline unsigned long vcpu_data_host_to_guest(struct 
kvm_vcpu *vcpu,
return data;/* Leave LE untouched */
 }
 
-static inline struct kvm_s2_vmid *vcpu_get_active_vmid(struct kvm_vcpu *vcpu)
-{
-   if (unlikely(vcpu_mode_el2(vcpu)))
-   return &vcpu->kvm->arch.mmu.el2_vmid;
-
-   return &vcpu->kvm->arch.mmu.vmid;
-}
-
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index b33d35d..23e2267 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -65,6 +65,22 @@ struct kvm_s2_mmu {
pgd_t *pgd;
 };
 
+/* Per nested VM mmu structure */
+struct kvm_nested_s2_mmu {
+   struct kvm_s2_mmu mmu;
+
+   /*
+* The vttbr value set by the guest hypervisor for this nested VM.
+* vmid field is used as a key to search for this mmu structure among
+* all nested VM mmu structures by the host hypervisor.
+* baddr field is used to determine if we need to unmap stage 2
+* shadow page tables.
+*/
+   u64 virtual_vttbr;
+
+   struct list_head list;
+};
+
 struct kvm_arch {
/* Stage 2 paging state for the VM */
struct kvm_s2_mmu mmu;
@@ -80,6 +96,9 @@ struct kvm_arch {
 
/* Timer */
struct arch_timer_kvm   timer;
+
+   /* Stage 2 shadow paging contexts for nested L2 VM */
+   struct list_head nested_mmu_list;
 };
 
 #define KVM_NR_MEM_OBJS 40
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index a504162..d1ef650 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -112,6 +112,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline unsigned long __kern_hyp_va(unsigned long v)
 {
@@ -323,6 +324,21 @@ static inline unsigned int kvm_get_vmid_bits(void)
return (cpuid_feature_extract_unsigned_field(reg, 
ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
 }
 
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu, u64 vttbr);
+struct kvm_s2_mmu *vcpu_get_active_s2_mmu(struct kvm_vcpu *vcpu);
+#else
+static inline struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu,
+  u64 vttbr)
+{
+   return NULL;
+}
+static inline struct kvm_s2_mmu *vcpu_get_active_s2_mmu(struct kvm_vcpu *vcpu)
+{
+   return &vcpu->kvm->arch.mmu;

[RFC 38/55] KVM: arm/arm64: Make mmu functions non-static

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Make mmu functions non-static so that we can reuse those functions
to support mmu for the nested VMs.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/kvm/mmu.c   | 90 +++-
 arch/arm64/include/asm/kvm_mmu.h |  9 
 2 files changed, 61 insertions(+), 38 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 56358fa..98b42e8 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -301,7 +301,7 @@ static void unmap_stage2_puds(struct kvm_s2_mmu *mmu, pgd_t 
*pgd,
 }
 
 /**
- * unmap_stage2_range -- Clear stage2 page table entries to unmap a range
+ * kvm_unmap_stage2_range -- Clear stage2 page table entries to unmap a range
  * @kvm:   The VM pointer
  * @start: The intermediate physical base address of the range to unmap
  * @size:  The size of the area to unmap
@@ -311,8 +311,7 @@ static void unmap_stage2_puds(struct kvm_s2_mmu *mmu, pgd_t 
*pgd,
  * destroying the VM), otherwise another faulting VCPU may come in and mess
  * with things behind our backs.
  */
-static void unmap_stage2_range(struct kvm_s2_mmu *mmu,
-  phys_addr_t start, u64 size)
+void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 
size)
 {
pgd_t *pgd;
phys_addr_t addr = start, end = start + size;
@@ -374,11 +373,10 @@ static void stage2_flush_puds(pgd_t *pgd,
} while (pud++, addr = next, addr != end);
 }
 
-static void stage2_flush_memslot(struct kvm_s2_mmu *mmu,
-struct kvm_memory_slot *memslot)
+void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu,
+   phys_addr_t start, phys_addr_t end)
 {
-   phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
-   phys_addr_t end = addr + PAGE_SIZE * memslot->npages;
+   phys_addr_t addr = start;
phys_addr_t next;
pgd_t *pgd;
 
@@ -389,6 +387,15 @@ static void stage2_flush_memslot(struct kvm_s2_mmu *mmu,
} while (pgd++, addr = next, addr != end);
 }
 
+static void stage2_flush_memslot(struct kvm_s2_mmu *mmu,
+struct kvm_memory_slot *memslot)
+{
+   phys_addr_t start = memslot->base_gfn << PAGE_SHIFT;
+   phys_addr_t end = start + PAGE_SIZE * memslot->npages;
+
+   kvm_stage2_flush_range(mmu, start, end);
+}
+
 /**
  * stage2_flush_vm - Invalidate cache for pages mapped in stage 2
  * @kvm: The struct kvm pointer
@@ -745,21 +752,9 @@ int create_hyp_io_mappings(void *from, void *to, 
phys_addr_t phys_addr)
 __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE);
 }
 
-/**
- * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
- * @kvm:   The KVM struct pointer for the VM.
- *
- * Allocates only the stage-2 HW PGD level table(s) (can support either full
- * 40-bit input addresses or limited to 32-bit input addresses). Clears the
- * allocated pages.
- *
- * Note we don't need locking here as this is only called when the VM is
- * created, which can only be done once.
- */
-int kvm_alloc_stage2_pgd(struct kvm *kvm)
+int __kvm_alloc_stage2_pgd(struct kvm_s2_mmu *mmu)
 {
pgd_t *pgd;
-   struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
 
if (mmu->pgd != NULL) {
kvm_err("kvm_arch already initialized?\n");
@@ -776,6 +771,22 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
return 0;
 }
 
+/**
+ * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
+ * @kvm:   The KVM struct pointer for the VM.
+ *
+ * Allocates only the stage-2 HW PGD level table(s) (can support either full
+ * 40-bit input addresses or limited to 32-bit input addresses). Clears the
+ * allocated pages.
+ *
+ * Note we don't need locking here as this is only called when the VM is
+ * created, which can only be done once.
+ */
+int kvm_alloc_stage2_pgd(struct kvm *kvm)
+{
+   return __kvm_alloc_stage2_pgd(&kvm->arch.mmu);
+}
+
 static void stage2_unmap_memslot(struct kvm_s2_mmu *mmu,
 struct kvm_memory_slot *memslot)
 {
@@ -811,7 +822,7 @@ static void stage2_unmap_memslot(struct kvm_s2_mmu *mmu,
 
if (!(vma->vm_flags & VM_PFNMAP)) {
gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
-   unmap_stage2_range(mmu, gpa, vm_end - vm_start);
+   kvm_unmap_stage2_range(mmu, gpa, vm_end - vm_start);
}
hva = vm_end;
} while (hva < reg_end);
@@ -841,6 +852,17 @@ void stage2_unmap_vm(struct kvm *kvm)
srcu_read_unlock(&kvm->srcu, idx);
 }
 
+void __kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
+{
+   if (mmu->pgd == NULL)
+   return;
+
+   kvm_unmap_stage2_range(mmu, 0, KVM_PHYS_SIZE);
+   /* Free the HW pgd, one page at a time */
+   free_pages_exact(mmu->pgd, S2_PGD_SIZE);
+   mmu->pgd = NULL;
+}
+
 /**
  * kvm_free_stage2_pgd - fr

[RFC 44/55] KVM: arm/arm64: Move kvm_is_write_fault to header file

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Move this little function to the header files for arm/arm64 so other
code can make use of it directly.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   | 8 
 arch/arm/kvm/mmu.c   | 8 
 arch/arm64/include/asm/kvm_emulate.h | 8 
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index dfc53ce..dde5335 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -235,6 +235,14 @@ static inline u8 kvm_vcpu_trap_get_fault_type(struct 
kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE;
 }
 
+static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
+{
+   if (kvm_vcpu_trap_is_iabt(vcpu))
+   return false;
+
+   return kvm_vcpu_dabt_iswrite(vcpu);
+}
+
 static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
 {
return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 710ae60..abdf345 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1113,14 +1113,6 @@ static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, 
gfn_t gfn,
return false;
 }
 
-static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
-{
-   if (kvm_vcpu_trap_is_iabt(vcpu))
-   return false;
-
-   return kvm_vcpu_dabt_iswrite(vcpu);
-}
-
 /**
  * stage2_wp_ptes - write protect PMD range
  * @pmd:   pointer to pmd entry
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 2994410..17f4855 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -285,6 +285,14 @@ static inline u8 kvm_vcpu_trap_get_fault_type(const struct 
kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE;
 }
 
+static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
+{
+   if (kvm_vcpu_trap_is_iabt(vcpu))
+   return false;
+
+   return kvm_vcpu_dabt_iswrite(vcpu);
+}
+
 static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 {
return vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
-- 
1.9.1




[RFC 42/55] KVM: arm64: Implement nested Stage-2 page table walk logic

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Based on the pseudo-code in the ARM ARM, implement a stage 2 software
page table walker.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_mmu.h   |  11 ++
 arch/arm64/include/asm/kvm_arm.h |   1 +
 arch/arm64/include/asm/kvm_mmu.h |  13 +++
 arch/arm64/kvm/mmu-nested.c  | 223 +++
 4 files changed, 248 insertions(+)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index ae3aa39..ab41a10 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -230,6 +230,17 @@ static inline unsigned int kvm_get_vmid_bits(void)
return 8;
 }
 
+struct kvm_s2_trans {
+   phys_addr_t output;
+   phys_addr_t block_size;
+};
+
+static inline int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+struct kvm_s2_trans *result)
+{
+   return 0;
+}
+
 static inline void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu) { }
 static inline int kvm_nested_s2_init(struct kvm_vcpu *vcpu) { return 0; }
 static inline void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu) { }
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index feded61..f9addf3 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -103,6 +103,7 @@
 #define VTCR_EL2_RES1  (1 << 31)
 #define VTCR_EL2_HD(1 << 22)
 #define VTCR_EL2_HA(1 << 21)
+#define VTCR_EL2_PS_SHIFT  TCR_EL2_PS_SHIFT
 #define VTCR_EL2_PS_MASK   TCR_EL2_PS_MASK
 #define VTCR_EL2_TG0_MASK  TCR_TG0_MASK
 #define VTCR_EL2_TG0_4KTCR_TG0_4K
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index e4d5d54..bf94f0c 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -324,10 +324,17 @@ static inline unsigned int kvm_get_vmid_bits(void)
return (cpuid_feature_extract_unsigned_field(reg, 
ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
 }
 
+struct kvm_s2_trans {
+   phys_addr_t output;
+   phys_addr_t block_size;
+};
+
 #ifdef CONFIG_KVM_ARM_NESTED_HYP
 struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu, u64 vttbr);
 struct kvm_s2_mmu *vcpu_get_active_s2_mmu(struct kvm_vcpu *vcpu);
 bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr);
+int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+  struct kvm_s2_trans *result);
 void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu);
 int kvm_nested_s2_init(struct kvm_vcpu *vcpu);
 void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu);
@@ -350,6 +357,12 @@ static inline bool handle_vttbr_update(struct kvm_vcpu 
*vcpu, u64 vttbr)
return false;
 }
 
+static inline int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+struct kvm_s2_trans *result)
+{
+   return 0;
+}
+
 static inline void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu) { }
 static inline int kvm_nested_s2_init(struct kvm_vcpu *vcpu) { return 0; }
 static inline void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu) { }
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index b22b78c..a2fab41 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -23,6 +23,229 @@
 #include 
 #include 
 
+struct s2_walk_info {
+   unsigned int pgshift;
+   unsigned int pgsize;
+   unsigned int ps;
+   unsigned int sl;
+   unsigned int t0sz;
+};
+
+static unsigned int ps_to_output_size(unsigned int ps)
+{
+   switch (ps) {
+   case 0: return 32;
+   case 1: return 36;
+   case 2: return 40;
+   case 3: return 42;
+   case 4: return 44;
+   case 5:
+   default:
+   return 48;
+   }
+}
+
+static unsigned int pa_max(void)
+{
+   u64 parange = read_sysreg(id_aa64mmfr0_el1) & 7;
+
+   return ps_to_output_size(parange);
+}
+
+static int vcpu_inject_s2_trans_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
+ int level)
+{
+   /* TODO: Implement */
+   return -EFAULT;
+}
+
+static int vcpu_inject_s2_addr_sz_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
+   int level)
+{
+   /* TODO: Implement */
+   return -EFAULT;
+}
+
+static int vcpu_inject_s2_access_flag_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
+   int level)
+{
+   /* TODO: Implement */
+   return -EFAULT;
+}
+
+static int check_base_s2_limits(struct kvm_vcpu *vcpu, struct s2_walk_info *wi,
+   int level, int input_size, int stride)
+{
+   int start_size;
+
+   /* Check translation limits */
+   switch (wi->pgsize) {
+   case SZ_64K:
+   if (level == 0 || (level == 1 && pa_max() <= 42))
+   return -EFAULT;
+   break;
+   case SZ_16K:
+   if (le

[RFC 54/55] KVM: arm/arm64: Adjust virtual offset considering nesting

2017-01-08 Thread Jintack Lim
The guest hypervisor sets cntvoff_el2 for its VM (i.e. nested VM).  Note
that physical/virtual counter value in the guest hypervisor's point of
view is already offsetted by the virtual offset set by the host
hypervisor.  Therefore, the correct offset we need to write to the
cntvoff_el2 is the sum of offset the host hypervisor initially has for
the VM and virtual offset the guest hypervisor sets for the nested VM.

Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   | 6 ++
 arch/arm64/include/asm/kvm_emulate.h | 6 ++
 virt/kvm/arm/arch_timer.c| 3 ++-
 virt/kvm/arm/hyp/timer-sr.c  | 5 -
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index dde5335..c7a690f 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -324,4 +324,10 @@ static inline bool kvm_is_shadow_s2_fault(struct kvm_vcpu 
*vcpu)
return false;
 }
 
+/* Return the guest hypervisor's cntvoff value */
+static inline u64 kvm_get_vcntvoff(struct kvm_vcpu *vcpu)
+{
+   return 0;
+}
+
 #endif /* __ARM_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 17f4855..0aaa4ca 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -385,4 +385,10 @@ static inline bool kvm_is_shadow_s2_fault(struct kvm_vcpu 
*vcpu)
 #endif
 }
 
+/* Return the guest hypervisor's cntvoff value */
+static inline u64 kvm_get_vcntvoff(struct kvm_vcpu *vcpu)
+{
+   return vcpu_el2_reg(vcpu, CNTVOFF_EL2);
+}
+
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 7a161f8..e393939 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -24,6 +24,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -102,7 +103,7 @@ static u64 kvm_timer_cntvoff(struct kvm_vcpu *vcpu,
 struct arch_timer_context *timer_ctx)
 {
if (timer_ctx == vcpu_vtimer(vcpu))
-   return vcpu->kvm->arch.timer.cntvoff;
+   return vcpu->kvm->arch.timer.cntvoff + kvm_get_vcntvoff(vcpu);
 
return 0;
 }
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c
index 4bbd36c..66dab01 100644
--- a/virt/kvm/arm/hyp/timer-sr.c
+++ b/virt/kvm/arm/hyp/timer-sr.c
@@ -20,6 +20,7 @@
 #include 
 
 #include 
+#include 
 
 /* vcpu is already in the HYP VA space */
 void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu)
@@ -49,6 +50,7 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
u64 val;
+   u64 cntvoff;
 
/*
 * Disallow physical timer access for the guest
@@ -60,7 +62,8 @@ void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu)
write_sysreg(val, cnthctl_el2);
 
if (vtimer->enabled) {
-   write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2);
+   cntvoff = kvm->arch.timer.cntvoff + kvm_get_vcntvoff(vcpu);
+   write_sysreg(cntvoff, cntvoff_el2);
write_sysreg_el0(vtimer->cnt_cval, cntv_cval);
isb();
write_sysreg_el0(vtimer->cnt_ctl, cntv_ctl);
-- 
1.9.1




[RFC 46/55] KVM: arm64: Add more info to the S2 translation result

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When translating an L2 IPA to an L1 IPA, we some times need to know at
which level this translation occurred and what the resulting permissions
was, so populate the translation result structure with these additional
fields.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_mmu.h | 3 +++
 arch/arm64/kvm/mmu-nested.c  | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index bf94f0c..2ac603d 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -327,6 +327,9 @@ static inline unsigned int kvm_get_vmid_bits(void)
 struct kvm_s2_trans {
phys_addr_t output;
phys_addr_t block_size;
+   bool writable;
+   bool readable;
+   int level;
 };
 
 #ifdef CONFIG_KVM_ARM_NESTED_HYP
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index b161b55..b579d23 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -236,6 +236,9 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, 
phys_addr_t ipa,
(ipa & GENMASK_ULL(addr_bottom - 1, 0));
out->output = paddr;
out->block_size = 1UL << ((3 - level) * stride + wi->pgshift);
+   out->readable = desc & (0b01 << 6);
+   out->writable = desc & (0b10 << 6);
+   out->level = level;
return 0;
 }
 
-- 
1.9.1




[RFC 51/55] KVM: arm64: Expose physical address of vcpu interface

2017-01-08 Thread Jintack Lim
Expose physical address of vgic virtual cpu interface.

Signed-off-by: Jintack Lim 
---
 include/kvm/arm_vgic.h  | 1 +
 virt/kvm/arm/vgic/vgic-v2.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 5bda20c..05c7811 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -331,6 +331,7 @@ static inline void vgic_handle_nested_maint_irq(struct 
kvm_vcpu *vcpu) { }
 #define vgic_valid_spi(k, i)   (((i) >= VGIC_NR_PRIVATE_IRQS) && \
((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS))
 
+phys_addr_t vgic_vcpu_base(void);
 bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index b8b73fd..5d85041 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -386,3 +386,9 @@ int vgic_v2_probe(const struct gic_kvm_info *info)
 
return ret;
 }
+
+/* Return physical address of vgic virtual cpu interface */
+phys_addr_t vgic_vcpu_base(void)
+{
+   return kvm_vgic_global_state.vcpu_base;
+}
-- 
1.9.1




[RFC 50/55] KVM: arm/arm64: Abstract kvm_phys_addr_ioremap() function

2017-01-08 Thread Jintack Lim
The original kvm_phys_addr_ioremap function only uses mmu pointing to
the VM's mmu context. However, it would be very useful to reuse this
function for the nested mmu context. Therefore, create a function named
__kvm_phys_addr_ioremapp which takes mmu as an argument, and let
kvm_phys_addr_ioremap calls this function with the VM's mmu context.

Signed-off-by: Jintack Lim 
---
 arch/arm/kvm/mmu.c   | 18 +-
 arch/arm64/include/asm/kvm_mmu.h |  3 +++
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 344bc01..2cd6a19 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1058,15 +1058,16 @@ static int stage2_pmdp_test_and_clear_young(pmd_t *pmd)
 }
 
 /**
- * kvm_phys_addr_ioremap - map a device range to guest IPA
+ * __kvm_phys_addr_ioremap - map a device range to guest IPA
  *
  * @kvm:   The KVM pointer
  * @guest_ipa: The IPA at which to insert the mapping
  * @pa:The physical address of the device
  * @size:  The size of the mapping
  */
-int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
- phys_addr_t pa, unsigned long size, bool writable)
+int __kvm_phys_addr_ioremap(struct kvm *kvm, struct kvm_s2_mmu *mmu,
+   phys_addr_t guest_ipa, phys_addr_t pa,
+   unsigned long size, bool writable)
 {
phys_addr_t addr, end;
int ret = 0;
@@ -1087,8 +1088,8 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t 
guest_ipa,
if (ret)
goto out;
spin_lock(&kvm->mmu_lock);
-   ret = stage2_set_pte(&kvm->arch.mmu, &cache, addr, &pte,
-   KVM_S2PTE_FLAG_IS_IOMAP);
+   ret = stage2_set_pte(mmu, &cache, addr, &pte,
+KVM_S2PTE_FLAG_IS_IOMAP);
spin_unlock(&kvm->mmu_lock);
if (ret)
goto out;
@@ -1101,6 +1102,13 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t 
guest_ipa,
return ret;
 }
 
+int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
+ phys_addr_t pa, unsigned long size, bool writable)
+{
+   return __kvm_phys_addr_ioremap(kvm, &kvm->arch.mmu, guest_ipa, pa,
+  size, writable);
+}
+
 static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, gfn_t gfn,
phys_addr_t *ipap)
 {
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 7754f3e..ec9e5e9 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -149,6 +149,9 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
 int __kvm_alloc_stage2_pgd(struct kvm_s2_mmu *mmu);
 void kvm_free_stage2_pgd(struct kvm *kvm);
 void __kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
+int __kvm_phys_addr_ioremap(struct kvm *kvm, struct kvm_s2_mmu *mmu,
+   phys_addr_t guest_ipa, phys_addr_t pa,
+   unsigned long size, bool writable);
 int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
  phys_addr_t pa, unsigned long size, bool writable);
 void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
-- 
1.9.1




[RFC 49/55] KVM: arm64: Fixes to toggle_cache for nesting

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

So far we were flushing almost the entire universe whenever a VM would
load/unload the SCTLR_EL1 and the two versions of that register had
different MMU enabled settings.  This turned out to be so slow that it
prevented forward progress for a nested VM, because a scheduler timer
tick interrupt would always be pending when we reached the nested VM.

To avoid this problem, we consider the SCTLR_EL2 when evaluating if
caches are on or off when entering virtual EL2 (because this is the
value that we end up shadowing onto the hardware EL1 register).

We also reduce the scope of the flush operation to only flush shadow
stage 2 page table state of the particular VCPU toggling the caches
instead of the shadow stage 2 state of all possible VCPUs.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/kvm/mmu.c   | 31 ++-
 arch/arm64/include/asm/kvm_mmu.h |  7 ++-
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 68fc8e8..344bc01 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -422,6 +422,35 @@ static void stage2_flush_vm(struct kvm *kvm)
srcu_read_unlock(&kvm->srcu, idx);
 }
 
+/**
+ * Same as above but only flushed shadow state for specific vcpu
+ */
+static void stage2_flush_vcpu(struct kvm_vcpu *vcpu)
+{
+   struct kvm *kvm = vcpu->kvm;
+   struct kvm_memslots *slots;
+   struct kvm_memory_slot *memslot;
+   int idx;
+   struct kvm_nested_s2_mmu __maybe_unused *nested_mmu;
+
+   idx = srcu_read_lock(&kvm->srcu);
+   spin_lock(&kvm->mmu_lock);
+
+   slots = kvm_memslots(kvm);
+   kvm_for_each_memslot(memslot, slots)
+   stage2_flush_memslot(&kvm->arch.mmu, memslot);
+
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+   list_for_each_entry_rcu(nested_mmu, &vcpu->kvm->arch.nested_mmu_list,
+   list) {
+   kvm_stage2_flush_range(&nested_mmu->mmu, 0, KVM_PHYS_SIZE);
+   }
+#endif
+
+   spin_unlock(&kvm->mmu_lock);
+   srcu_read_unlock(&kvm->srcu, idx);
+}
+
 static void clear_hyp_pgd_entry(pgd_t *pgd)
 {
pud_t *pud_table __maybe_unused = pud_offset(pgd, 0UL);
@@ -2074,7 +2103,7 @@ void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool 
was_enabled)
 * Clean + invalidate does the trick always.
 */
if (now_enabled != was_enabled)
-   stage2_flush_vm(vcpu->kvm);
+   stage2_flush_vcpu(vcpu);
 
/* Caches are now on, stop trapping VM ops (until a S/W op) */
if (now_enabled)
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 2086296..7754f3e 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -241,7 +241,12 @@ static inline bool kvm_page_empty(void *ptr)
 
 static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
 {
-   return (vcpu_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
+   u32 mode = vcpu->arch.ctxt.gp_regs.regs.pstate & PSR_MODE_MASK;
+
+   if (mode != PSR_MODE_EL2h && mode != PSR_MODE_EL2t)
+   return (vcpu_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
+   else
+   return (vcpu_el2_reg(vcpu, SCTLR_EL2) & 0b101) == 0b101;
 }
 
 static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
-- 
1.9.1




[RFC 52/55] KVM: arm/arm64: Create a vcpu mapping for the nested VM

2017-01-08 Thread Jintack Lim
Create a mapping from the nested VM's cpu interface to the hardware
virtual cpu interface. This is to allow the nested VM to access virtual
cpu interface directly.

Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_mmu.h   |  3 +++
 arch/arm/kvm/mmu.c   |  5 +
 arch/arm64/include/asm/kvm_mmu.h |  5 +
 arch/arm64/kvm/mmu-nested.c  | 26 ++
 4 files changed, 39 insertions(+)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 0d106ae..048a021 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -254,6 +254,9 @@ static inline void kvm_nested_s2_teardown(struct kvm_vcpu 
*vcpu) { }
 static inline void kvm_nested_s2_all_vcpus_wp(struct kvm *kvm) { }
 static inline void kvm_nested_s2_all_vcpus_unmap(struct kvm *kvm) { }
 static inline void kvm_nested_s2_all_vcpus_flush(struct kvm *kvm) { }
+static inline int kvm_nested_mmio_ondemand(struct kvm_vcpu *vcpu,
+  phys_addr_t fault_ipa,
+  phys_addr_t ipa) { return 0; }
 
 static inline u64 kvm_get_vttbr(struct kvm_s2_vmid *vmid,
struct kvm_s2_mmu *mmu)
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 2cd6a19..f7c2911 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1615,6 +1615,11 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
goto out_unlock;
}
 
+   if (kvm_nested_mmio_ondemand(vcpu, fault_ipa, ipa)) {
+   ret = 1;
+   goto out_unlock;
+   }
+
/*
 * The IPA is reported as [MAX:12], so we need to
 * complement it with the bottom 12 bits from the
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index ec9e5e9..ee80a58 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -354,6 +354,8 @@ int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, 
phys_addr_t fault_ipa,
 void kvm_nested_s2_all_vcpus_wp(struct kvm *kvm);
 void kvm_nested_s2_all_vcpus_unmap(struct kvm *kvm);
 void kvm_nested_s2_all_vcpus_flush(struct kvm *kvm);
+int kvm_nested_mmio_ondemand(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+phys_addr_t ipa);
 #else
 static inline struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu,
   u64 vttbr)
@@ -389,6 +391,9 @@ static inline void kvm_nested_s2_teardown(struct kvm_vcpu 
*vcpu) { }
 static inline void kvm_nested_s2_all_vcpus_wp(struct kvm *kvm) { }
 static inline void kvm_nested_s2_all_vcpus_unmap(struct kvm *kvm) { }
 static inline void kvm_nested_s2_all_vcpus_flush(struct kvm *kvm) { }
+static inline int kvm_nested_mmio_ondemand(struct kvm_vcpu *vcpu,
+  phys_addr_t fault_ipa,
+  phys_addr_t ipa) { return 0; }
 #endif
 
 static inline u64 kvm_get_vttbr(struct kvm_s2_vmid *vmid,
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index 65ad0da..bce0042 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -473,3 +473,29 @@ bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr)
 
return true;
 }
+
+/*
+ * vcpu interface address. This address is supposed to come from the guest's
+ * device tree via QEMU. Here we just hardcoded it, but should be fixed.
+ */
+#define NESTED_VCPU_IF_ADDR0x0801
+int kvm_nested_mmio_ondemand(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+phys_addr_t ipa)
+{
+   int ret = 0;
+   phys_addr_t vcpu_base = vgic_vcpu_base();
+
+   /* Return if this fault is not from a nested VM */
+   if (vcpu->arch.hw_mmu == &vcpu->kvm->arch.mmu)
+   return ret;
+
+   if (ipa == NESTED_VCPU_IF_ADDR)  {
+   ret = __kvm_phys_addr_ioremap(vcpu->kvm, vcpu->arch.hw_mmu,
+ fault_ipa, vcpu_base,
+ KVM_VGIC_V2_CPU_SIZE, true);
+   if (!ret)
+   ret = 1;
+   }
+
+   return ret;
+}
-- 
1.9.1




[RFC 40/55] KVM: arm/arm64: Handle vttbr_el2 write operation from the guest hypervisor

2017-01-08 Thread Jintack Lim
Each nested VM is supposed to have a mmu (i.e. shadow stage-2 page
table), and we create it when the guest hypervisor writes to vttbr_el2
with a new vmid.

In case the guest hypervisor writes to vttbr_el2 with existing vmid, we
check if the base address is changed. If so, then what we have in the
shadow page table is not valid any more. So ummap it.

Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_host.h   |  1 +
 arch/arm/kvm/arm.c|  1 +
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/include/asm/kvm_mmu.h  |  6 
 arch/arm64/kvm/mmu-nested.c   | 71 +++
 arch/arm64/kvm/sys_regs.c | 15 -
 6 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index fbde48d..ebf2810 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -84,6 +84,7 @@ struct kvm_arch {
 
/* Never used on arm but added to be compatible with arm64 */
struct list_head nested_mmu_list;
+   spinlock_t mmu_list_lock;
 
/* Interrupt controller */
struct vgic_distvgic;
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 147df97..6fa5754 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -147,6 +147,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.mmu.vmid.vmid_gen = 0;
kvm->arch.mmu.el2_vmid.vmid_gen = 0;
INIT_LIST_HEAD(&kvm->arch.nested_mmu_list);
+   spin_lock_init(&kvm->arch.mmu_list_lock);
 
/* The maximum number of VCPUs is limited by the host's GIC model */
kvm->arch.max_vcpus = vgic_present ?
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 23e2267..52eea76 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -99,6 +99,7 @@ struct kvm_arch {
 
/* Stage 2 shadow paging contexts for nested L2 VM */
struct list_head nested_mmu_list;
+   spinlock_t mmu_list_lock;
 };
 
 #define KVM_NR_MEM_OBJS 40
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index d1ef650..fdc9327 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -327,6 +327,7 @@ static inline unsigned int kvm_get_vmid_bits(void)
 #ifdef CONFIG_KVM_ARM_NESTED_HYP
 struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu, u64 vttbr);
 struct kvm_s2_mmu *vcpu_get_active_s2_mmu(struct kvm_vcpu *vcpu);
+bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr);
 #else
 static inline struct kvm_nested_s2_mmu *get_nested_mmu(struct kvm_vcpu *vcpu,
   u64 vttbr)
@@ -337,6 +338,11 @@ static inline struct kvm_s2_mmu 
*vcpu_get_active_s2_mmu(struct kvm_vcpu *vcpu)
 {
return &vcpu->kvm->arch.mmu;
 }
+
+static inline bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr)
+{
+   return false;
+}
 #endif
 
 static inline u64 kvm_get_vttbr(struct kvm_s2_vmid *vmid,
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index d52078f..0811d94 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -53,3 +53,74 @@ struct kvm_s2_mmu *vcpu_get_active_s2_mmu(struct kvm_vcpu 
*vcpu)
 
return &nested_mmu->mmu;
 }
+
+static struct kvm_nested_s2_mmu *create_nested_mmu(struct kvm_vcpu *vcpu,
+  u64 vttbr)
+{
+   struct kvm_nested_s2_mmu *nested_mmu, *tmp_mmu;
+   struct list_head *nested_mmu_list = &vcpu->kvm->arch.nested_mmu_list;
+   bool need_free = false;
+   int ret;
+
+   nested_mmu = kzalloc(sizeof(struct kvm_nested_s2_mmu), GFP_KERNEL);
+   if (!nested_mmu)
+   return NULL;
+
+   ret = __kvm_alloc_stage2_pgd(&nested_mmu->mmu);
+   if (ret) {
+   kfree(nested_mmu);
+   return NULL;
+   }
+
+   spin_lock(&vcpu->kvm->arch.mmu_list_lock);
+   tmp_mmu = get_nested_mmu(vcpu, vttbr);
+   if (!tmp_mmu)
+   list_add_rcu(&nested_mmu->list, nested_mmu_list);
+   else /* Somebody already created and put a new nested_mmu to the list */
+   need_free = true;
+   spin_unlock(&vcpu->kvm->arch.mmu_list_lock);
+
+   if (need_free) {
+   __kvm_free_stage2_pgd(&nested_mmu->mmu);
+   kfree(nested_mmu);
+   nested_mmu = tmp_mmu;
+   }
+
+   return nested_mmu;
+}
+
+static void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu)
+{
+   struct kvm_nested_s2_mmu *nested_mmu;
+   struct list_head *nested_mmu_list = &vcpu->kvm->arch.nested_mmu_list;
+
+   list_for_each_entry_rcu(nested_mmu, nested_mmu_list, list)
+   kvm_unmap_stage2_range(&nested_mmu->mmu, 0, KVM_PHYS_SIZE);
+}
+
+bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr)
+{
+   struct kvm_nested_s2_mmu *nested_mmu;
+
+   /* See if 

[RFC 47/55] KVM: arm/arm64: Forward the guest hypervisor's stage 2 permission faults

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

When faulting on a shadow stage 2 page table we have to check if the
fault was a permission fault and if so, if that fault needs to be
handled by the guest hypervisor before us, in case the guest hypervisor
has created a less permissive S2 entry than the operation required.

Check if this is the case, and inject a fault if it is.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_mmu.h   |  7 +++
 arch/arm/kvm/mmu.c   |  5 +
 arch/arm64/include/asm/kvm_mmu.h |  9 +
 arch/arm64/kvm/mmu-nested.c  | 33 +
 4 files changed, 54 insertions(+)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index ab41a10..0d106ae 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -241,6 +241,13 @@ static inline int kvm_walk_nested_s2(struct kvm_vcpu 
*vcpu, phys_addr_t gipa,
return 0;
 }
 
+static inline int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
+  phys_addr_t fault_ipa,
+  struct kvm_s2_trans *trans)
+{
+   return 0;
+}
+
 static inline void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu) { }
 static inline int kvm_nested_s2_init(struct kvm_vcpu *vcpu) { return 0; }
 static inline void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu) { }
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index abdf345..68fc8e8 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1542,6 +1542,11 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans);
if (ret)
goto out_unlock;
+
+   ret = kvm_s2_handle_perm_fault(vcpu, fault_ipa, &nested_trans);
+   if (ret)
+   goto out_unlock;
+
ipa = nested_trans.output;
}
 
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 2ac603d..2086296 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -338,6 +338,8 @@ struct kvm_s2_trans {
 bool handle_vttbr_update(struct kvm_vcpu *vcpu, u64 vttbr);
 int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
   struct kvm_s2_trans *result);
+int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+struct kvm_s2_trans *trans);
 void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu);
 int kvm_nested_s2_init(struct kvm_vcpu *vcpu);
 void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu);
@@ -366,6 +368,13 @@ static inline int kvm_walk_nested_s2(struct kvm_vcpu 
*vcpu, phys_addr_t gipa,
return 0;
 }
 
+static inline int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
+  phys_addr_t fault_ipa,
+  struct kvm_s2_trans *trans)
+{
+   return 0;
+}
+
 static inline void kvm_nested_s2_unmap(struct kvm_vcpu *vcpu) { }
 static inline int kvm_nested_s2_init(struct kvm_vcpu *vcpu) { return 0; }
 static inline void kvm_nested_s2_teardown(struct kvm_vcpu *vcpu) { }
diff --git a/arch/arm64/kvm/mmu-nested.c b/arch/arm64/kvm/mmu-nested.c
index b579d23..65ad0da 100644
--- a/arch/arm64/kvm/mmu-nested.c
+++ b/arch/arm64/kvm/mmu-nested.c
@@ -52,6 +52,19 @@ static unsigned int pa_max(void)
return ps_to_output_size(parange);
 }
 
+static int vcpu_inject_s2_perm_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
+int level)
+{
+   u32 esr;
+
+   vcpu->arch.ctxt.el2_regs[FAR_EL2] = vcpu->arch.fault.far_el2;
+   vcpu->arch.ctxt.el2_regs[HPFAR_EL2] = vcpu->arch.fault.hpfar_el2;
+   esr = kvm_vcpu_get_hsr(vcpu) & ~ESR_ELx_FSC;
+   esr |= ESR_ELx_FSC_PERM;
+   esr |= level & 0x3;
+   return kvm_inject_nested_sync(vcpu, esr);
+}
+
 static int vcpu_inject_s2_trans_fault(struct kvm_vcpu *vcpu, gpa_t ipa,
  int level)
 {
@@ -268,6 +281,26 @@ int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t 
gipa,
return walk_nested_s2_pgd(vcpu, gipa, &wi, result);
 }
 
+/*
+ * Returns non-zero if permission fault is handled by injecting it to the next
+ * level hypervisor.
+ */
+int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
+struct kvm_s2_trans *trans)
+{
+   unsigned long fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
+   bool write_fault = kvm_is_write_fault(vcpu);
+
+   if (fault_status != FSC_PERM)
+   return 0;
+
+   if ((write_fault && !trans->writable) ||
+   (!write_fault && !trans->readable))
+   return vcpu_inject_s2_perm_fault(vcpu, fault_ipa, trans->level);
+
+   return 0;
+}
+
 /* expects kvm->mmu_lock to be held */
 void kvm_nested_s2_all_vcpus_wp(struct kvm *kvm)
 {
-- 
1.9.1

[RFC 48/55] KVM: arm64: Emulate TLBI instruction

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Currently, we flush ALL shadow stage-2 page tables on the tlbi
instruction execution. We may be able to do this more efficiently by
considering the vttbr_el2 value of the guest hypervisor, but leave it
for now.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/sys_regs.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ddb641c..b0a057d 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2013,8 +2013,14 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
 static int emulate_tlbi(struct kvm_vcpu *vcpu,
 struct sys_reg_params *params)
 {
-   /* TODO: support tlbi instruction emulation*/
-   kvm_inject_undefined(vcpu);
+   /*
+* We unmap ALL stage-2 page tables on tlbi instruction.
+* We may make it more efficient by looking at the exact tlbi
+* instruction.
+*/
+   stage2_unmap_vm(vcpu->kvm);
+   kvm_nested_s2_unmap(vcpu);
+
return 1;
 }
 
-- 
1.9.1




[RFC 25/55] KVM: arm/arm64: Let vcpu thread modify its own active state

2017-01-08 Thread Jintack Lim
Currently, if a vcpu thread tries to change its own active state when
the irq is already in AP list, it'll loop forever. Since the VCPU thread
has already synced back LR state to the struct vgic_irq, let it modify
its own state safely.

Signed-off-by: Jintack Lim 
---
 virt/kvm/arm/vgic/vgic-mmio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index ebe1b9f..049c570 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -192,9 +192,9 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, 
struct vgic_irq *irq,
 * If this virtual IRQ was written into a list register, we
 * have to make sure the CPU that runs the VCPU thread has
 * synced back LR state to the struct vgic_irq.  We can only
-* know this for sure, when either this irq is not assigned to
+* know this for sure, when this irq is not assigned to
 * anyone's AP list anymore, or the VCPU thread is not
-* running on any CPUs.
+* running on any CPUs, or current thread is the VCPU thread.
 *
 * In the opposite case, we know the VCPU thread may be on its
 * way back from the guest and still has to sync back this
@@ -202,6 +202,7 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, 
struct vgic_irq *irq,
 * other thread sync back the IRQ.
 */
while (irq->vcpu && /* IRQ may have state in an LR somewhere */
+  irq->vcpu != vcpu && /* Current thread is not the VCPU thread */
   irq->vcpu->cpu != -1) /* VCPU thread is running */
cond_resched_lock(&irq->irq_lock);
 
-- 
1.9.1




[RFC 26/55] KVM: arm/arm64: Add VGIC data structures for the nesting

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

This adds a couple of extra data structures:

The nested_vgic_vX structures contain the data manipulated by the guest
hypervisor when it faults/traps on accesses to the GICH_ interface.

The shadow_vgic_vX arrays contain the shadow copies of the LRs.  That
is, it is a modified version of the nested_vgic_vX->vgic_lr.  The reason
why we need a modified version is that for interrupts with the HW bit
set (those for the timer) the interrupt number must be that of the host
hardware number, and not the virtual one programmed by the guest
hypervisor.

The hw_vX_cpu_if pointers point to the registers that the lowvisor (EL2)
code actually copied into hardware when switching to the guest, so at
init time we set:

vgic_cpu->hw_v2_cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;

And we should change the vgic-sr function to read the LRs from the
hw_v2_lr pointer.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 include/kvm/arm_vgic.h | 20 
 1 file changed, 20 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 002f092..9a9cb27 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -246,6 +246,26 @@ struct vgic_cpu {
unsigned int used_lrs;
struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
 
+   /* CPU vif control registers for the virtual GICH interface */
+   union {
+   struct vgic_v2_cpu_if   nested_vgic_v2;
+   struct vgic_v3_cpu_if   nested_vgic_v3;
+   };
+
+   /*
+* The shadow vif control register loaded to the hardware when
+* running a sted L2 guest with the virtual IMO bit set.
+*/
+   union {
+   struct vgic_v2_cpu_if   shadow_vgic_v2;
+   struct vgic_v3_cpu_if   shadow_vgic_v3;
+   };
+
+   union {
+   struct vgic_v2_cpu_if   *hw_v2_cpu_if;
+   struct vgic_v3_cpu_if   *hw_v3_cpu_if;
+   };
+
spinlock_t ap_list_lock;/* Protects the ap_list */
 
/*
-- 
1.9.1




[RFC 12/55] KVM: arm64: Handle EL2 register access traps

2017-01-08 Thread Jintack Lim
ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
this bit is set, accessing EL2 registers in EL1 traps to EL2. In
addition, executing following instructions in EL1 will trap to EL2 -
tlbi and at instructions which are undefined when exectued in EL1, eret
instruction, msr/mrs instructions to access SP_EL1.

This patch handles traps due to accessing EL2 registers in EL1.  The
host hypervisor keeps EL2 register values in memory, and will use them
to emulate the behavior that the guest hypervisor expects from the
hardware.

Subsequent patches will handle other kinds of traps.

Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/sys_regs.c | 119 ++
 arch/arm64/kvm/sys_regs.h |   7 +++
 2 files changed, 126 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7cef94f..4158f2f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -873,6 +873,18 @@ static bool access_cntp_cval(struct kvm_vcpu *vcpu,
return true;
 }
 
+static bool trap_el2_reg(struct kvm_vcpu *vcpu,
+struct sys_reg_params *p,
+const struct sys_reg_desc *r)
+{
+   if (!p->is_write)
+   p->regval = vcpu_el2_reg(vcpu, r->reg);
+   else
+   vcpu_el2_reg(vcpu, r->reg) = p->regval;
+
+   return true;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -1163,15 +1175,122 @@ static bool access_cntp_cval(struct kvm_vcpu *vcpu,
{ Op0(0b11), Op1(0b011), CRn(0b1110), CRm(0b), Op2(0b111),
  access_pmu_evtyper, reset_val, PMCCFILTR_EL0, 0 },
 
+   /* VPIDR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b), CRm(0b), Op2(0b000),
+ trap_el2_reg, reset_el2_val, VPIDR_EL2, 0 },
+   /* VMPIDR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b), CRm(0b), Op2(0b101),
+ trap_el2_reg, reset_el2_val, VMPIDR_EL2, 0 },
+
+   /* SCTLR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b), Op2(0b000),
+ trap_el2_reg, reset_el2_val, SCTLR_EL2, 0 },
+   /* ACTLR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b), Op2(0b001),
+ trap_el2_reg, reset_el2_val, ACTLR_EL2, 0 },
+   /* HCR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b0001), Op2(0b000),
+ trap_el2_reg, reset_el2_val, HCR_EL2, 0 },
+   /* MDCR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b0001), Op2(0b001),
+ trap_el2_reg, reset_el2_val, MDCR_EL2, 0 },
+   /* CPTR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b0001), Op2(0b010),
+ trap_el2_reg, reset_el2_val, CPTR_EL2, 0 },
+   /* HSTR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b0001), Op2(0b011),
+ trap_el2_reg, reset_el2_val, HSTR_EL2, 0 },
+   /* HACR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0001), CRm(0b0001), Op2(0b111),
+ trap_el2_reg, reset_el2_val, HACR_EL2, 0 },
+
+   /* TTBR0_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0010), CRm(0b), Op2(0b000),
+ trap_el2_reg, reset_el2_val, TTBR0_EL2, 0 },
+   /* TCR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0010), CRm(0b), Op2(0b010),
+ trap_el2_reg, reset_el2_val, TCR_EL2, 0 },
+   /* VTTBR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0010), CRm(0b0001), Op2(0b000),
+ trap_el2_reg, reset_el2_val, VTTBR_EL2, 0 },
+   /* VTCR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0010), CRm(0b0001), Op2(0b010),
+ trap_el2_reg, reset_el2_val, VTCR_EL2, 0 },
+
/* DACR32_EL2 */
{ Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b), Op2(0b000),
  NULL, reset_unknown, DACR32_EL2 },
+
+   /* SPSR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0100), CRm(0b), Op2(0b000),
+ trap_el2_reg, reset_el2_val, SPSR_EL2, 0 },
+   /* ELR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0100), CRm(0b), Op2(0b001),
+ trap_el2_reg, reset_el2_val, ELR_EL2, 0 },
+   /* SP_EL1 */
+   { Op0(0b11), Op1(0b100), CRn(0b0100), CRm(0b0001), Op2(0b000),
+ trap_el2_reg },
+
/* IFSR32_EL2 */
{ Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b), Op2(0b001),
  NULL, reset_unknown, IFSR32_EL2 },
+   /* AFSR0_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0001), Op2(0b000),
+ trap_el2_reg, reset_el2_val, AFSR0_EL2, 0 },
+   /* AFSR1_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0001), Op2(0b001),
+ trap_el2_reg, reset_el2_val, AFSR1_EL2, 0 },
+   /* ESR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0010), Op2(0b000),
+ trap_el2_reg, reset_el2_val, ESR_EL2, 0 },
/* FPEXC32_EL2 */
{ Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),
  NULL, reset_val, FPEXC32_EL2, 0x70 },
+
+   /* FAR_EL2 */
+   { Op0(0b11), Op1(0b100), CRn(0b0110)

[RFC 14/55] KVM: arm64: Take account of system instruction traps

2017-01-08 Thread Jintack Lim
When HCR.NV bit is set, execution of the EL2 translation regime Address
Translation instructions and TLB maintenance instructions are trapped to
EL2. In addition, execution of the EL1 translation regime Address
Translation instructions and TLB maintenance instructions that are only
accessible from EL2 and above are trapped to EL2. In these cases,
ESR_EL2.EC will be set to 0x18.

Take account of this and handle system instructions as well as MRS/MSR
instructions in the handler. Change the handler name to reflect this.

Emulation of those system instructions is to be done.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_coproc.h |  2 +-
 arch/arm64/kvm/handle_exit.c|  2 +-
 arch/arm64/kvm/sys_regs.c   | 49 -
 arch/arm64/kvm/trace.h  |  2 +-
 4 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_coproc.h 
b/arch/arm64/include/asm/kvm_coproc.h
index 0b52377..1b3d21b 100644
--- a/arch/arm64/include/asm/kvm_coproc.h
+++ b/arch/arm64/include/asm/kvm_coproc.h
@@ -43,7 +43,7 @@ void kvm_register_target_sys_reg_table(unsigned int target,
 int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
-int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_sys(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
 #define kvm_coproc_table_init kvm_sys_reg_table_init
 void kvm_sys_reg_table_init(void);
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 4e4a915..a891684 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -147,7 +147,7 @@ static int kvm_handle_eret(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
[ESR_ELx_EC_SMC32]  = handle_smc,
[ESR_ELx_EC_HVC64]  = handle_hvc,
[ESR_ELx_EC_SMC64]  = handle_smc,
-   [ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
+   [ESR_ELx_EC_SYS64]  = kvm_handle_sys,
[ESR_ELx_EC_ERET]   = kvm_handle_eret,
[ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4158f2f..202f64d 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1903,6 +1903,36 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
return 1;
 }
 
+static int emulate_tlbi(struct kvm_vcpu *vcpu,
+struct sys_reg_params *params)
+{
+   /* TODO: support tlbi instruction emulation*/
+   kvm_inject_undefined(vcpu);
+   return 1;
+}
+
+static int emulate_at(struct kvm_vcpu *vcpu,
+struct sys_reg_params *params)
+{
+   /* TODO: support address translation instruction emulation */
+   kvm_inject_undefined(vcpu);
+   return 1;
+}
+
+static int emulate_sys_instr(struct kvm_vcpu *vcpu,
+struct sys_reg_params *params)
+{
+   int ret;
+
+   /* TLB maintenance instructions*/
+   if (params->CRn == 0b1000)
+   ret = emulate_tlbi(vcpu, params);
+   /* Address Translation instructions */
+   else if (params->CRn == 0b0111 && params->CRm == 0b1000)
+   ret = emulate_at(vcpu, params);
+   return ret;
+}
+
 static void reset_sys_reg_descs(struct kvm_vcpu *vcpu,
  const struct sys_reg_desc *table, size_t num)
 {
@@ -1914,18 +1944,19 @@ static void reset_sys_reg_descs(struct kvm_vcpu *vcpu,
 }
 
 /**
- * kvm_handle_sys_reg -- handles a mrs/msr trap on a guest sys_reg access
+ * kvm_handle_sys-- handles a system instruction or mrs/msr instruction trap
+   on a guest execution
  * @vcpu: The VCPU pointer
  * @run:  The kvm_run struct
  */
-int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
+int kvm_handle_sys(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
struct sys_reg_params params;
unsigned long esr = kvm_vcpu_get_hsr(vcpu);
int Rt = (esr >> 5) & 0x1f;
int ret;
 
-   trace_kvm_handle_sys_reg(esr);
+   trace_kvm_handle_sys(esr);
 
params.is_aarch32 = false;
params.is_32bit = false;
@@ -1937,10 +1968,16 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
params.regval = vcpu_get_reg(vcpu, Rt);
params.is_write = !(esr & 1);
 
-   ret = emulate_sys_reg(vcpu, ¶ms);
+   if (params.Op0 == 1) {
+   /* System instructions */
+   ret = emulate_sys_instr(vcpu, ¶ms);
+   } else {
+   /* MRS/MSR instructions */
+   ret = emulate_sys_reg(vcpu, ¶ms);
+   if (!params.is_write)
+   vcpu_set_reg(vcpu, Rt, params.regval);
+   }
 
-   if (!params.is_write)
-   vcpu_set_reg(vcpu, Rt, params.regval);

[RFC 24/55] KVM: arm64: Forward FP exceptions to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward exceptions due to floating-point register accesses to the guest
hypervisor if it has set CPTR_EL2.TFP bit.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_nested.h |  1 +
 arch/arm64/kernel/asm-offsets.c |  1 +
 arch/arm64/kvm/handle_exit.c|  3 +++
 arch/arm64/kvm/handle_exit_nested.c |  6 ++
 arch/arm64/kvm/hyp/entry.S  | 14 ++
 arch/arm64/kvm/hyp/hyp-entry.S  |  2 +-
 6 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h 
b/arch/arm64/include/asm/kvm_nested.h
index 8d36935..54c5ce5 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -3,4 +3,5 @@
 
 int handle_hvc_nested(struct kvm_vcpu *vcpu);
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
+int kvm_handle_fp_asimd(struct kvm_vcpu *vcpu, struct kvm_run *run);
 #endif
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 4a2f0f0..b635f1a 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -131,6 +131,7 @@ int main(void)
   DEFINE(CPU_FP_REGS,  offsetof(struct kvm_regs, fp_regs));
   DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, 
arch.ctxt.sys_regs[FPEXC32_EL2]));
   DEFINE(VCPU_HOST_CONTEXT,offsetof(struct kvm_vcpu, 
arch.host_cpu_context));
+  DEFINE(VIRTUAL_CPTR_EL2, offsetof(struct kvm_vcpu, 
arch.ctxt.el2_regs[CPTR_EL2]));
 #endif
 #ifdef CONFIG_CPU_PM
   DEFINE(CPU_SUSPEND_SZ,   sizeof(struct cpu_suspend_ctx));
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 046fdf8..308f5c5 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -195,6 +195,9 @@ static int kvm_handle_eret(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
[ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
[ESR_ELx_EC_BRK64]  = kvm_handle_guest_debug,
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+   [ESR_ELx_EC_FP_ASIMD]   = kvm_handle_fp_asimd,
+#endif
 };
 
 static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/handle_exit_nested.c 
b/arch/arm64/kvm/handle_exit_nested.c
index 871ecfc..7544c6d 100644
--- a/arch/arm64/kvm/handle_exit_nested.c
+++ b/arch/arm64/kvm/handle_exit_nested.c
@@ -43,3 +43,9 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
 
return -EINVAL;
 }
+
+/* This is only called when virtual CPTR_EL2.TFP bit is set. */
+int kvm_handle_fp_asimd(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+}
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d..a76f102 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -158,6 +158,20 @@ abort_guest_exit_end:
 1: ret
 ENDPROC(__guest_exit)
 
+ENTRY(__fpsimd_guest_trap)
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+// If virtual CPTR_EL2.TFP is set, then foward it to the nested hyp.
+   mrs x1, tpidr_el2
+   ldr x0, [x1, #VIRTUAL_CPTR_EL2]
+   and x0, x0, #CPTR_EL2_TFP
+   cbnzx0, 1f
+#endif
+   b   __fpsimd_guest_restore
+1:
+   mov x0, #ARM_EXCEPTION_TRAP
+   b   __guest_exit
+ENDPROC(__fpsimd_guest_trap)
+
 ENTRY(__fpsimd_guest_restore)
stp x2, x3, [sp, #-16]!
stp x4, lr, [sp, #-16]!
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 4e92399..d83494b 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -108,7 +108,7 @@ el1_trap:
 
/* Guest accessed VFP/SIMD registers, save host, restore Guest */
cmp x0, #ESR_ELx_EC_FP_ASIMD
-   b.eq__fpsimd_guest_restore
+   b.eq__fpsimd_guest_trap
 
mrs x1, tpidr_el2
mov x0, #ARM_EXCEPTION_TRAP
-- 
1.9.1




[RFC 23/55] KVM: arm64: Forward WFX to the guest hypervisor

2017-01-08 Thread Jintack Lim
Forward exceptions due to WFI or WFE to the guest hypervisor if the
guest hypervisor has set corresponding virtual HCR_EL2.TWX bits.

Signed-off-by: Jintack Lim 
---
 arch/arm64/include/asm/kvm_nested.h |  1 +
 arch/arm64/kvm/handle_exit.c| 11 ++-
 arch/arm64/kvm/handle_exit_nested.c | 18 ++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h 
b/arch/arm64/include/asm/kvm_nested.h
index 620b4d3..8d36935 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -2,4 +2,5 @@
 #define __ARM64_KVM_NESTED_H__
 
 int handle_hvc_nested(struct kvm_vcpu *vcpu);
+int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 #endif
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index ce6d2ef..046fdf8 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -101,7 +101,16 @@ static int handle_smc(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
  */
 static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-   if (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WFx_ISS_WFE) {
+   bool is_wfe = !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WFx_ISS_WFE);
+#ifdef CONFIG_KVM_ARM_NESTED_HYP
+   int ret = handle_wfx_nested(vcpu, is_wfe);
+
+   if (ret < 0 && ret != -EINVAL)
+   return ret;
+   else if (ret >= 0)
+   return ret;
+#endif
+   if (is_wfe) {
trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true);
vcpu->stat.wfe_exit_stat++;
kvm_vcpu_on_spin(vcpu);
diff --git a/arch/arm64/kvm/handle_exit_nested.c 
b/arch/arm64/kvm/handle_exit_nested.c
index a6ce23b..871ecfc 100644
--- a/arch/arm64/kvm/handle_exit_nested.c
+++ b/arch/arm64/kvm/handle_exit_nested.c
@@ -25,3 +25,21 @@ int handle_hvc_nested(struct kvm_vcpu *vcpu)
 {
return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
 }
+
+/*
+ * Inject wfx to the nested hypervisor if this is from the nested VM and
+ * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
+ * handle this.
+ */
+int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
+{
+   u64 hcr_el2 = vcpu_el2_reg(vcpu, HCR_EL2);
+
+   if (vcpu_mode_el2(vcpu))
+   return -EINVAL;
+
+   if ((is_wfe && (hcr_el2 & HCR_TWE)) || (!is_wfe && (hcr_el2 & HCR_TWI)))
+   return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_hsr(vcpu));
+
+   return -EINVAL;
+}
-- 
1.9.1




[RFC 06/55] KVM: arm64: Add EL2 execution context for nesting

2017-01-08 Thread Jintack Lim
With the nested virtualization support, the context of the guest
includes EL2 register states. The host manages a set of virtual EL2
registers.  In addition to that, the guest hypervisor supposed to run in
EL2 is now deprivilaged and runs in EL1. So, the host also manages a set
of shadow system registers to be able to run the guest hypervisor in
EL1.

Signed-off-by: Jintack Lim 
Signed-off-by: Christoffer Dall 
---
 arch/arm64/include/asm/kvm_host.h | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index c0c8b02..ed78d73 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -146,6 +146,42 @@ enum vcpu_sysreg {
NR_SYS_REGS /* Nothing after this line! */
 };
 
+enum el2_regs {
+   ELR_EL2,
+   SPSR_EL2,
+   SP_EL2,
+   AMAIR_EL2,
+   MAIR_EL2,
+   TCR_EL2,
+   TTBR0_EL2,
+   VTCR_EL2,
+   VTTBR_EL2,
+   VMPIDR_EL2,
+   VPIDR_EL2,  /* 10 */
+   MDCR_EL2,
+   CNTHCTL_EL2,
+   CNTHP_CTL_EL2,
+   CNTHP_CVAL_EL2,
+   CNTHP_TVAL_EL2,
+   CNTVOFF_EL2,
+   ACTLR_EL2,
+   AFSR0_EL2,
+   AFSR1_EL2,
+   CPTR_EL2,   /* 20 */
+   ESR_EL2,
+   FAR_EL2,
+   HACR_EL2,
+   HCR_EL2,
+   HPFAR_EL2,
+   HSTR_EL2,
+   RMR_EL2,
+   RVBAR_EL2,
+   SCTLR_EL2,
+   TPIDR_EL2,  /* 30 */
+   VBAR_EL2,
+   NR_EL2_REGS /* Nothing after this line! */
+};
+
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
 #define c0_CSSELR  (CSSELR_EL1 * 2)/* Cache Size Selection Register */
@@ -193,6 +229,23 @@ struct kvm_cpu_context {
u64 sys_regs[NR_SYS_REGS];
u32 copro[NR_COPRO_REGS];
};
+
+   u64 el2_regs[NR_EL2_REGS]; /* only used for nesting */
+   u64 shadow_sys_regs[NR_SYS_REGS];  /* only used for virtual EL2 */
+
+   /*
+* hw_* will be used when switching to a VM. They point to either
+* the virtual EL2 or EL1/EL0 context depending on vcpu mode.
+*/
+
+   /* pointing shadow_sys_regs or sys_regs */
+   u64 *hw_sys_regs;
+
+   /* copy of either gp_regs.sp_el1 or el2_regs[SP_EL2] */
+   u64 hw_sp_el1;
+
+   /* pstate written to SPSR_EL2 */
+   u64 hw_pstate;
 };
 
 typedef struct kvm_cpu_context kvm_cpu_context_t;
@@ -277,6 +330,7 @@ struct kvm_vcpu_arch {
 
 #define vcpu_gp_regs(v)(&(v)->arch.ctxt.gp_regs)
 #define vcpu_sys_reg(v,r)  ((v)->arch.ctxt.sys_regs[(r)])
+#define vcpu_el2_reg(v, r) ((v)->arch.ctxt.el2_regs[(r)])
 /*
  * CP14 and CP15 live in the same array, as they are backed by the
  * same system registers.
-- 
1.9.1




[RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Set up virutal EL2 context to hardware if the guest exception level is
EL2.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 320afc6..acb4b1e 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -25,10 +25,25 @@
 void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
 
-   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
-   ctxt->hw_sys_regs = ctxt->sys_regs;
-   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   /*
+* We emulate virtual EL2 mode in hardware EL1 mode using the
+* same stack pointer mode as the guest expects.
+*/
+   if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
+   ctxt->hw_pstate |= PSR_MODE_EL1h;
+   else
+   ctxt->hw_pstate |= PSR_MODE_EL1t;
+
+   ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
+   ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
+   } else {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
+   ctxt->hw_sys_regs = ctxt->sys_regs;
+   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   }
 }
 
 /**
@@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
-
-   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
-   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
+   *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
+   ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
+   } else {
+   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
+   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   }
 }
 
 void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
-- 
1.9.1




[RFC 07/55] KVM: arm/arm64: Add virtual EL2 state emulation framework

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Add a framework to set up the guest's context depending on the guest's
exception level. A chosen context is written to hardware in the lowvisor.
We don't set the virtual EL2 context yet.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm/include/asm/kvm_emulate.h   |   4 ++
 arch/arm/kvm/arm.c   |   5 ++
 arch/arm64/include/asm/kvm_emulate.h |   4 ++
 arch/arm64/kvm/Makefile  |   2 +-
 arch/arm64/kvm/context.c |  49 
 arch/arm64/kvm/hyp/sysreg-sr.c   | 109 +++
 6 files changed, 122 insertions(+), 51 deletions(-)
 create mode 100644 arch/arm64/kvm/context.c

diff --git a/arch/arm/include/asm/kvm_emulate.h 
b/arch/arm/include/asm/kvm_emulate.h
index 399cd75e..0a03b7d 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -47,6 +47,10 @@ static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 
reg_num,
 void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
 void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
+static inline void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu) { };
+static inline void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu) { };
+static inline void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt) { };
+
 static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
 {
return kvm_condition_valid32(vcpu);
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d2dfa32..436bf5a 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -646,6 +647,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
}
 
kvm_arm_setup_debug(vcpu);
+   kvm_arm_setup_shadow_state(vcpu);
 
/**
 * Enter the guest
@@ -662,6 +664,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
 * Back from guest
 */
 
+   kvm_arm_restore_shadow_state(vcpu);
kvm_arm_clear_debug(vcpu);
 
/*
@@ -1369,6 +1372,8 @@ static int init_hyp_mode(void)
kvm_err("Cannot map host CPU state: %d\n", err);
goto out_err;
}
+
+   kvm_arm_init_cpu_context(cpu_ctxt);
}
 
kvm_info("Hyp mode initialized successfully\n");
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 830be2e..8892c82 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -42,6 +42,10 @@
 void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
 void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
+void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu);
+void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu);
+void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt);
+
 static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 {
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index d50a82a..7811d27 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -16,7 +16,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o 
$(KVM)/coalesced_mmio.o $(KVM)/e
 kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
 
-kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o
+kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o context.o
 kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
 kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o 
sys_regs_generic_v8.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/aarch32.o
diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
new file mode 100644
index 000..320afc6
--- /dev/null
+++ b/arch/arm64/kvm/context.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 - Linaro Ltd.
+ * Author: Christoffer Dall 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include 
+#include 
+
+/**
+ * kvm_arm_setup_shadow_state -- prepare shadow state based on emulated mode
+ * @vcpu: The VCPU pointer
+ */
+voi

Re: [PATCH v3] arm64: mm: Fix NOMAP page initialization

2017-01-08 Thread Prakash B
Thanks Hanjun ,


On Mon, Jan 9, 2017 at 10:39 AM, Hanjun Guo  wrote:
> Hi Prakash,
> I didn't test "cpuset01" on D05 but according to the test in
> Linaro, LTP full test is passed on D05 with Ard's 2 patches.
>
>>
>> Any idea what might be causing this issue.
>
>
> Since it's not happening on D05, maybe it's related to
> the firmware? (just a wild guess...)
>

 Used same firmware b/w 4.4 kernel and 4.9 (and   above kernels) .
Test passed wtih 4.4 kernel and didn't generated  any crashes or
dumps.

If there is more observation I will  send a  mail  or I will start a
separate mail thread.

Thanks,
Prakash B


[PATCH v2] staging: wilc1000: Connect to highest RSSI value for required SSID

2017-01-08 Thread Aditya Shankar
Connect to the highest rssi with the required SSID in the shadow
table if the connection criteria is based only on the SSID.
For the first matching SSID, an index to the table is saved.
Later the index is updated if matching SSID has a higher
RSSI value than the last saved index.

However if decision is made based on BSSID, there is only one match
in the table and corresponding index is used.

changes in v2:
initialize sel_bssi_idx to UINT_MAX.
Combine two checks for identifying
sel_bssi_idx value for a SSID.

Signed-off-by: Aditya Shankar 
---
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index c1a24f7..507bdf7 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
 {
s32 s32Error = 0;
u32 i;
+   u32 sel_bssi_idx = UINT_MAX;
u8 u8security = NO_ENCRYPT;
enum AUTHTYPE tenuAuth_type = ANY;
 
@@ -688,18 +689,24 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
memcmp(last_scanned_shadow[i].ssid,
   sme->ssid,
   sme->ssid_len) == 0) {
-   if (!sme->bssid)
-   break;
-   else
+   if (!sme->bssid) {
+   if (sel_bssi_idx == UINT_MAX ||
+   last_scanned_shadow[i].rssi >
+   last_scanned_shadow[sel_bssi_idx].rssi)
+   sel_bssi_idx = i;
+   } else {
if (memcmp(last_scanned_shadow[i].bssid,
   sme->bssid,
-  ETH_ALEN) == 0)
+  ETH_ALEN) == 0) {
+   sel_bssi_idx = i;
break;
+   }
+   }
}
}
 
-   if (i < last_scanned_cnt) {
-   pstrNetworkInfo = &last_scanned_shadow[i];
+   if (sel_bssi_idx < last_scanned_cnt) {
+   pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx];
} else {
s32Error = -ENOENT;
wilc_connecting = 0;
-- 
2.7.4



Re: [PATCH] staging: wilc1000: Connect to highest RSSI value for required SSID

2017-01-08 Thread Aditya Shankar
On Thu, 5 Jan 2017 15:14:50 +0300
Dan Carpenter  wrote:

> On Thu, Jan 05, 2017 at 01:03:41PM +0530, Aditya Shankar wrote:
> > Connect to the highest rssi with the required SSID in the shadow
> > table if the connection criteria is based only on the SSID.
> > For the first matching SSID, an index to the table is saved.
> > Later the index is updated if matching SSID has a higher
> > RSSI value than the last saved index.
> > 
> > However if decision is made based on BSSID, there is only one match
> > in the table and corresponding index is used.
> > 
> > Signed-off-by: Aditya Shankar 
> > ---
> >  drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 20 ++--
> >  1 file changed, 14 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
> > b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > index c1a24f7..32206b8 100644
> > --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > @@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct 
> > net_device *dev,
> >  {
> > s32 s32Error = 0;
> > u32 i;
> > +   u32 sel_bssi_idx = last_scanned_cnt + 1;  
> 
> 
> My understanding from reading the code is that "last_scanned_cnt + 1"
> is a randomly chosen invalid value.  Just saying:
> 
>   sel_bssi_idx = last_scanned_cnt;
> 
> would  also work because it's also invalid and slightly shorter to type.
> But I suggest that you go with something like UINT_MAX because that's
> more clearly invalid.

Thanks. Will change this.
> 
> > u8 u8security = NO_ENCRYPT;
> > enum AUTHTYPE tenuAuth_type = ANY;
> >  
> > @@ -688,18 +689,25 @@ static int connect(struct wiphy *wiphy, struct 
> > net_device *dev,
> > memcmp(last_scanned_shadow[i].ssid,
> >sme->ssid,
> >sme->ssid_len) == 0) {
> > -   if (!sme->bssid)
> > -   break;
> > -   else
> > +   if (!sme->bssid) {
> > +   if (sel_bssi_idx == (last_scanned_cnt + 1))
> > +   sel_bssi_idx = i;
> > +   else if (last_scanned_shadow[i].rssi >
> > +last_scanned_shadow[sel_bssi_idx].rssi)
> > +   sel_bssi_idx = i;  
> 
> Combine these with an ||.
> 
>   if (!sme->bssid) {
>   if (sel_bssi_idx == UINT_MAX ||
>   last_scanned_shadow[i].rssi >
>   last_scanned_shadow[sel_bssi_idx].rssi)
>   sel_bssi_idx = i;
>
>
> 
> In a separate patch, you can reverse the if statement at the start of
> the loop:
> 
>   if (sme->ssid_len != last_scanned_shadow[i].ssid_len ||
>   memcmp(last_scanned_shadow[i].ssid, sme->ssid,
>  sme->ssid_len) != 0)
>   continue;
> 
> That way you can pull these lines in a tab.
> 
> 
> > +   } else {
> > if (memcmp(last_scanned_shadow[i].bssid,
> >sme->bssid,
> > -  ETH_ALEN) == 0)
> > +  ETH_ALEN) == 0){  
> 
> Add a space before the curly brace.
> 
> regards,
> dan carpenter
> 
> 

I shall send an updated patch with the suggested changes and a separate
patch for the change at the beginning of the loop. 

Thanks for your review!

-- 
adiTya


Re: [PATCH] samples/seccomp: fix 64-bit comparison macros

2017-01-08 Thread James Morris
On Fri, 6 Jan 2017, Kees Cook wrote:

> On Fri, Jan 6, 2017 at 1:32 PM, Kees Cook  wrote:
> > There were some bugs in the JNE64 and JLT64 comparision macros. This fixes
> > them, improves comments, and cleans up the file while we are at it.
> >
> > Reported-by: Stephen Röttger 
> > Signed-off-by: Mathias Svensson 
> > Signed-off-by: Kees Cook 
> > Cc: sta...@vger.kernel.org
> 
> Oops, the in-body "From:" got stripped. This patch is authored by Mathias:
> 
> From: Mathias Svensson 
> 

Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next


-- 
James Morris



Re: [PATCH] Staging: lustre: lustre: lmv: Compress return logic into one line.

2017-01-08 Thread Dilger, Andreas
On Jan 4, 2017, at 22:14, Gustavo A. R. Silva  
wrote:
> 
> Simplify return logic to avoid unnecessary variable assignments.
> These issues were detected using Coccinelle and the following semantic patch:
> 
> @@
> local idexpression ret;
> expression e;
> @@
> 
> -ret =
> +return
> e;
> -return ret;
> 
> Signed-off-by: Gustavo A. R. Silva 

Reviewed-by: Andreas Dilger 

> ---
> drivers/staging/lustre/lustre/lmv/lmv_obd.c | 58 -
> 1 file changed, 16 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c 
> b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
> index f124f6c..76a0306 100644
> --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
> +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
> @@ -771,7 +771,6 @@ static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, 
> unsigned int cmd, int len,
>struct lustre_kernelcomm *lk,
>void __user *uarg)
> {
> - int rc = 0;
>   __u32 i;
> 
>   /* unregister request (call from llapi_hsm_copytool_fini) */
> @@ -791,9 +790,7 @@ static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, 
> unsigned int cmd, int len,
>* Unreached coordinators will get EPIPE on next requests
>* and will unregister automatically.
>*/
> - rc = libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group);
> -
> - return rc;
> + return libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group);
> }
> 
> static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len,
> @@ -1425,8 +1422,7 @@ static int lmv_getstatus(struct obd_export *exp,
>   if (rc)
>   return rc;
> 
> - rc = md_getstatus(lmv->tgts[0]->ltd_exp, fid);
> - return rc;
> + return md_getstatus(lmv->tgts[0]->ltd_exp, fid);
> }
> 
> static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid,
> @@ -1447,10 +1443,8 @@ static int lmv_getxattr(struct obd_export *exp, const 
> struct lu_fid *fid,
>   if (IS_ERR(tgt))
>   return PTR_ERR(tgt);
> 
> - rc = md_getxattr(tgt->ltd_exp, fid, valid, name, input,
> + return md_getxattr(tgt->ltd_exp, fid, valid, name, input,
>input_size, output_size, flags, request);
> -
> - return rc;
> }
> 
> static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
> @@ -1472,11 +1466,9 @@ static int lmv_setxattr(struct obd_export *exp, const 
> struct lu_fid *fid,
>   if (IS_ERR(tgt))
>   return PTR_ERR(tgt);
> 
> - rc = md_setxattr(tgt->ltd_exp, fid, valid, name, input,
> + return md_setxattr(tgt->ltd_exp, fid, valid, name, input,
>input_size, output_size, flags, suppgid,
>request);
> -
> - return rc;
> }
> 
> static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data,
> @@ -1500,9 +1492,7 @@ static int lmv_getattr(struct obd_export *exp, struct 
> md_op_data *op_data,
>   return 0;
>   }
> 
> - rc = md_getattr(tgt->ltd_exp, op_data, request);
> -
> - return rc;
> + return md_getattr(tgt->ltd_exp, op_data, request);
> }
> 
> static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid)
> @@ -1549,8 +1539,7 @@ static int lmv_close(struct obd_export *exp, struct 
> md_op_data *op_data,
>   return PTR_ERR(tgt);
> 
>   CDEBUG(D_INODE, "CLOSE "DFID"\n", PFID(&op_data->op_fid1));
> - rc = md_close(tgt->ltd_exp, op_data, mod, request);
> - return rc;
> + return md_close(tgt->ltd_exp, op_data, mod, request);
> }
> 
> /**
> @@ -1743,10 +1732,8 @@ lmv_enqueue(struct obd_export *exp, struct 
> ldlm_enqueue_info *einfo,
>   CDEBUG(D_INODE, "ENQUEUE '%s' on " DFID " -> mds #%u\n",
>  LL_IT2STR(it), PFID(&op_data->op_fid1), tgt->ltd_idx);
> 
> - rc = md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh,
> + return md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh,
>   extra_lock_flags);
> -
> - return rc;
> }
> 
> static int
> @@ -1894,9 +1881,7 @@ static int lmv_link(struct obd_export *exp, struct 
> md_op_data *op_data,
>   if (rc != 0)
>   return rc;
> 
> - rc = md_link(tgt->ltd_exp, op_data, request);
> -
> - return rc;
> + return md_link(tgt->ltd_exp, op_data, request);
> }
> 
> static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
> @@ -2109,8 +2094,7 @@ static int lmv_sync(struct obd_export *exp, const 
> struct lu_fid *fid,
>   if (IS_ERR(tgt))
>   return PTR_ERR(tgt);
> 
> - rc = md_sync(tgt->ltd_exp, fid, request);
> - return rc;
> + return md_sync(tgt->ltd_exp, fid, request);
> }
> 
> /**
> @@ -2428,17 +2412,14 @@ static int lmv_read_page(struct obd_export *exp, 
> struct md_op_data *op_data,
>   return rc;
> 
>   if (unlikely(lsm)) {
> - rc = lmv_read_striped_page(exp, op_data, cb_op, offset, ppage);
> - return 

Re: [PATCH v4] mmc: dw_mmc: force setup bus if active slots exist

2017-01-08 Thread Jaehoon Chung
On 01/09/2017 12:39 PM, Ziyuan wrote:
> 
> 
> On 01/05/2017 03:34 PM, Shawn Lin wrote:
>> On 2017/1/5 15:23, Ziyuan Xu wrote:
>>> It's necessary to setup bus if any slots are present.
>>> - update clock after ctrl reset
>>> - if the host has genpd node, we can guarantee the clock is available
>>> before starting request. Otherwies, the clock register is reset once
>>> power off the pd, and host can't output the active clock during
>>> communication.
>>>
>>> fixes: e9ed8835e990 ("mmc: dw_mmc: add runtime PM callback")
>>> Reported-by: Randy Li 
>>> Signed-off-by: Ziyuan Xu 
>>>
>>> ---
>>> Hi guys,
>>>
>>> I found a similar issue on rk3399 platform, which has a genpd node for
>>> SD card host. Power off-on pd will reset the registers to a default
>>> value (ie. CLKENA), so that the host can't output the active clock
>>> during communication.
>>>
>>
>> Indeed, Caesar recently introduced all the genpd for rk3399 platform,
>> so we need to restore them.
>>
>>> So we need to setup bus in rpm resume. It also wraps the update clock
>>> behaviour which I did in V3.
>>>
>>> Thanks,
>>> Ziyuan Xu
>>>
>>>
>>> Changes in v4:
>>> - update commit message
>>> - fix SD host rpm resume can't work
>>>
>>> Changes in v3:
>>> - only reset host with active slot.
>>>
>>> Changes in v2:
>>> - update the commit message
>>> - use dw_mci_reset instead of dw_mci_ctrl_reset
>>>
>>>  drivers/mmc/host/dw_mmc.c | 6 +++---
>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index b44306b..b6053b3 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -3354,10 +3354,10 @@ int dw_mci_runtime_resume(struct device *dev)
>>>
>>>  if (!slot)
>>>  continue;
>>> -if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
>>> +if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
>>>  dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
>>> -dw_mci_setup_bus(slot, true);
>>> -}
>>> +/* Force setup bus to guarantee available clock output */
>>> +dw_mci_setup_bus(slot, true);
>>
>> So the spamming message about
>>
>> "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n"
>>
>> will always be there, right? So you could append a new patch to shut
>> up it as I think it's useless no matter for system pm or rpm to print
>> it.  How about?
> 
> Fine, it's favourable with dev_vdbg if the dw_mmc rpm is enabled.
> Hi Jaehoon,
> What's your opinion? If you think this patch and shawn's advice are 
> acceptable, I will send the v5 patch.

I don't agreed to use dev_vdbg()..but it needs not to display at everytime.
Hmm..It needs to consider more..because we needs to see the clock value when 
it's initialized.

Best Regards,
Jaehoon Chung

> 
> BR
> Ziyuan Xu
> 
>>
>>>  }
>>>
>>>  /* Now that slots are all setup, we can enable card detect */
>>>
>>
>>
> 
> 
> 
> 
> 



RE: [PATCH] ACPI / EC: Use busy polling mode when GPE is not enabled

2017-01-08 Thread Zheng, Lv
Hi, Yu

> From: Chen, Yu C
> Subject: [PATCH] ACPI / EC: Use busy polling mode when GPE is not enabled
> 
> From: Lv Zheng 
> 
> Previously we have report that during system bootup, the EC command
> was running too slow because the EC GPE has not been enabled yet
> (For example, _REG tries to access the EC operation region, while the
> EC GPE has not been enabled at that stage). Actually we can optimize this
> scenario by using busy polling mode if GPE is disabled, which is much
> faster than the default behavior.

I suddenly realized that why I didn't put this check during my previous EC work.
Though this patch can solve the issue in question, it doesn't handle runtime EC 
polling in a proper way.
Sorry for my damaged memory.

Let me provide a different fix.
So please drop it.

Thanks and best regards
Lv

> 
> Reported-and-tested-by: Chen Yu 
> Signed-off-by: Lv Zheng 
> ---
>  drivers/acpi/ec.c | 10 +-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 48e19d0..457949d 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -342,6 +342,14 @@ static const char *acpi_ec_cmd_string(u8 cmd)
>   *   GPE Registers
>   * 
> -- */
> 
> +static inline bool acpi_ec_is_gpe_enabled(struct acpi_ec *ec)
> +{
> + acpi_event_status gpe_status = 0;
> +
> + (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status);
> + return (gpe_status & ACPI_EVENT_FLAG_ENABLE_SET) ? true : false;
> +}
> +
>  static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec)
>  {
>   acpi_event_status gpe_status = 0;
> @@ -734,7 +742,7 @@ static int ec_guard(struct acpi_ec *ec)
> 
>   /* Ensure guarding period before polling EC status */
>   do {
> - if (ec_busy_polling) {
> + if (!acpi_ec_is_gpe_enabled(ec) || ec_busy_polling) {
>   /* Perform busy polling */
>   if (ec_transaction_completed(ec))
>   return 0;
> --
> 2.7.4



[PATCH v11 3/3] fpga: Add support for Lattice iCE40 FPGAs

2017-01-08 Thread Joel Holdsworth
This patch adds support to the FPGA manager for configuring the SRAM of
iCE40LM, iCE40LP, iCE40HX, iCE40 Ultra, iCE40 UltraLite and iCE40
UltraPlus devices, through slave SPI.

Signed-off-by: Joel Holdsworth 
Reviewed-by: Marek Vasut 
Reviewed-by: Moritz Fischer 
Acked-by: Alan Tull 
---
 drivers/fpga/Kconfig |   6 ++
 drivers/fpga/Makefile|   1 +
 drivers/fpga/ice40-spi.c | 207 +++
 3 files changed, 214 insertions(+)
 create mode 100644 drivers/fpga/ice40-spi.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ce861a2..967cda4 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -20,6 +20,12 @@ config FPGA_REGION
  FPGA Regions allow loading FPGA images under control of
  the Device Tree.
 
+config FPGA_MGR_ICE40_SPI
+   tristate "Lattice iCE40 SPI"
+   depends on OF && SPI
+   help
+ FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
+
 config FPGA_MGR_SOCFPGA
tristate "Altera SOCFPGA FPGA Manager"
depends on ARCH_SOCFPGA || COMPILE_TEST
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8df07bc..cc0d364 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_FPGA) += fpga-mgr.o
 
 # FPGA Manager Drivers
+obj-$(CONFIG_FPGA_MGR_ICE40_SPI)   += ice40-spi.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)   += zynq-fpga.o
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
new file mode 100644
index 000..6a4194b
--- /dev/null
+++ b/drivers/fpga/ice40-spi.c
@@ -0,0 +1,207 @@
+/*
+ * FPGA Manager Driver for Lattice iCE40.
+ *
+ *  Copyright (c) 2016 Joel Holdsworth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This driver adds support to the FPGA manager for configuring the SRAM of
+ * Lattice iCE40 FPGAs through slave SPI.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ICE40_SPI_MAX_SPEED 2500 /* Hz */
+#define ICE40_SPI_MIN_SPEED 100 /* Hz */
+
+#define ICE40_SPI_RESET_DELAY 1 /* us (>200ns) */
+#define ICE40_SPI_HOUSEKEEPING_DELAY 1200 /* us */
+
+#define ICE40_SPI_NUM_ACTIVATION_BYTES DIV_ROUND_UP(49, 8)
+
+struct ice40_fpga_priv {
+   struct spi_device *dev;
+   struct gpio_desc *reset;
+   struct gpio_desc *cdone;
+};
+
+static enum fpga_mgr_states ice40_fpga_ops_state(struct fpga_manager *mgr)
+{
+   struct ice40_fpga_priv *priv = mgr->priv;
+
+   return gpiod_get_value(priv->cdone) ? FPGA_MGR_STATE_OPERATING :
+   FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int ice40_fpga_ops_write_init(struct fpga_manager *mgr,
+struct fpga_image_info *info,
+const char *buf, size_t count)
+{
+   struct ice40_fpga_priv *priv = mgr->priv;
+   struct spi_device *dev = priv->dev;
+   struct spi_message message;
+   struct spi_transfer assert_cs_then_reset_delay = {
+   .cs_change   = 1,
+   .delay_usecs = ICE40_SPI_RESET_DELAY
+   };
+   struct spi_transfer housekeeping_delay_then_release_cs = {
+   .delay_usecs = ICE40_SPI_HOUSEKEEPING_DELAY
+   };
+   int ret;
+
+   if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+   dev_err(&dev->dev,
+   "Partial reconfiguration is not supported\n");
+   return -ENOTSUPP;
+   }
+
+   /* Lock the bus, assert CRESET_B and SS_B and delay >200ns */
+   spi_bus_lock(dev->master);
+
+   gpiod_set_value(priv->reset, 1);
+
+   spi_message_init(&message);
+   spi_message_add_tail(&assert_cs_then_reset_delay, &message);
+   ret = spi_sync_locked(dev, &message);
+
+   /* Come out of reset */
+   gpiod_set_value(priv->reset, 0);
+
+   /* Abort if the chip-select failed */
+   if (ret)
+   goto fail;
+
+   /* Check CDONE is de-asserted i.e. the FPGA is reset */
+   if (gpiod_get_value(priv->cdone)) {
+   dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
+   ret = -EIO;
+   goto fail;
+   }
+
+   /* Wait for the housekeeping to complete, and release SS_B */
+   spi_message_init(&message);
+   spi_message_add_tail(&housekeeping_delay_then_release_cs, &message);
+   ret = spi_sync_locked(dev, &message);
+
+fail:
+   spi_bus_unlock(dev->master);
+
+   return ret;
+}
+
+static int ice40_fpga_ops_write(struct fpga_manager *mgr,
+   const char *buf, size_t count)
+{
+   struct ice40_fpga_priv *priv = mgr->priv;
+
+   return spi_write(priv->dev, buf, count);
+}
+
+static int ice40_

Re: [PATCH 2/2] ocfs2: fix deadlocks when taking inode lock at vfs entry points

2017-01-08 Thread Eric Ren

Hi Fengguang,

On 01/06/2017 10:52 PM, kbuild test robot wrote:

Hi Eric,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc2 next-20170106]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Eric-Ren/fix-deadlock-caused-by-recursive-cluster-locking/20170106-200837
config: ia64-allyesconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
 wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=ia64


I failed to reproduce this issue locally by following the above instructions, after rebasing 
my patch set onto the lastest

mainline(Linux 4.10-rc3), only seeing this compiler error message:
"
test:/mnt/build/linux # make.cross ARCH=ia64
make CROSS_COMPILE=/opt/gcc-4.9.0-nolibc/ia64-linux/bin/ia64-linux- --jobs=4 
ARCH=ia64
...
  CALLscripts/checksyscalls.sh
:1184:2: warning: #warning syscall perf_event_open not implemented 
[-Wcpp]
:1238:2: warning: #warning syscall seccomp not implemented [-Wcpp]
:1316:2: warning: #warning syscall pkey_mprotect not implemented [-Wcpp]
:1319:2: warning: #warning syscall pkey_alloc not implemented [-Wcpp]
:1322:2: warning: #warning syscall pkey_free not implemented [-Wcpp]
...
 AS  arch/ia64/kernel/gate.o
arch/ia64/kernel/entry.S: Assembler messages:
arch/ia64/kernel/entry.S:622: Error: Operand 2 of `adds' should be a 14-bit 
integer (-8192-8191)
arch/ia64/kernel/entry.S:729: Error: Operand 2 of `adds' should be a 14-bit 
integer (-8192-8191)
arch/ia64/kernel/entry.S:860: Error: Operand 2 of `adds' should be a 14-bit 
integer (-8192-8191)
make[1]: *** [scripts/Makefile.build:393: arch/ia64/kernel/entry.o] Error 1
make[1]: *** Waiting for unfinished jobs
make: *** [Makefile:988: arch/ia64/kernel] Error 2
make: *** Waiting for unfinished jobs
"

The obvious difference I noticed is my gcc version is little newer than kbuild, not sure if 
it's related:

"
test:/mnt/build/linux # gcc -v
gcc version 6.2.1 20160830 [gcc-6-branch revision 239856] (SUSE Linux)
"



All errors (new ones prefixed by >>):

In file included from fs/ocfs2/acl.c:31:0:
fs/ocfs2/acl.c: In function 'ocfs2_iop_set_acl':

fs/ocfs2/dlmglue.h:189:29: error: inlining failed in call to always_inline 
'ocfs2_is_locked_by_me': function body not available

 inline struct ocfs2_holder *ocfs2_is_locked_by_me(struct ocfs2_lock_res 
*lockres);


This error is probably because I should not add "inline" at the declaration while putting 
the function body into source file.

But, no error or warning occurred when I built and tested locally this way:
"
test:/mnt/build/linux/fs/ocfs2 # make -C /lib/modules/4.9.0-2-vanilla/build 
M=`pwd` modules
"

Anyway, I wanna make kbuild silent before resending again;-) Please correct me if I'm 
missing something?


Thanks!
Eric

 ^
fs/ocfs2/acl.c:292:16: note: called from here
  has_locked = (ocfs2_is_locked_by_me(lockres) != NULL);
^~
In file included from fs/ocfs2/acl.c:31:0:

fs/ocfs2/dlmglue.h:189:29: error: inlining failed in call to always_inline 
'ocfs2_is_locked_by_me': function body not available

 inline struct ocfs2_holder *ocfs2_is_locked_by_me(struct ocfs2_lock_res 
*lockres);
 ^
fs/ocfs2/acl.c:292:16: note: called from here
  has_locked = (ocfs2_is_locked_by_me(lockres) != NULL);
^~
In file included from fs/ocfs2/acl.c:31:0:

fs/ocfs2/dlmglue.h:185:13: error: inlining failed in call to always_inline 
'ocfs2_add_holder': function body not available

 inline void ocfs2_add_holder(struct ocfs2_lock_res *lockres,
 ^~~~
fs/ocfs2/acl.c:302:3: note: called from here
   ocfs2_add_holder(lockres, &oh);
   ^~
In file included from fs/ocfs2/acl.c:31:0:

fs/ocfs2/dlmglue.h:187:13: error: inlining failed in call to always_inline 
'ocfs2_remove_holder': function body not available

 inline void ocfs2_remove_holder(struct ocfs2_lock_res *lockres,
 ^~~
fs/ocfs2/acl.c:307:3: note: called from here
   ocfs2_remove_holder(lockres, &oh);
   ^
--
In file included from arch/ia64/include/uapi/asm/intrinsics.h:21:0,
 from arch/ia64/include/asm/intrinsics.h:10,
 from arch/ia64/include/asm/bitops.h:18,
 from include/linux/bitops.h:36,
 from include/linux/kernel.h:10,
 from include/linux/list.h:8,
 from include/linux/wait.h:6,
 from in

[PATCH v11 2/3] Documentation: Add binding document for Lattice iCE40 FPGA manager

2017-01-08 Thread Joel Holdsworth
This adds documentation of the device tree bindings of the Lattice iCE40
FPGA driver for the FPGA manager framework.

Signed-off-by: Joel Holdsworth 
Acked-by: Rob Herring 
Acked-by: Alan Tull 
Acked-by: Moritz Fischer 
Acked-by: Marek Vasut 
---
 .../bindings/fpga/lattice-ice40-fpga-mgr.txt| 21 +
 1 file changed, 21 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt

diff --git a/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt 
b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
new file mode 100644
index 000..4dc4124
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
@@ -0,0 +1,21 @@
+Lattice iCE40 FPGA Manager
+
+Required properties:
+- compatible:  Should contain "lattice,ice40-fpga-mgr"
+- reg: SPI chip select
+- spi-max-frequency:   Maximum SPI frequency (>=100, <=2500)
+- cdone-gpios: GPIO input connected to CDONE pin
+- reset-gpios: Active-low GPIO output connected to CRESET_B pin. Note
+   that unless the GPIO is held low during startup, the
+   FPGA will enter Master SPI mode and drive SCK with a
+   clock signal potentially jamming other devices on the
+   bus until the firmware is loaded.
+
+Example:
+   fpga: fpga@0 {
+   compatible = "lattice,ice40-fpga-mgr";
+   reg = <0>;
+   spi-max-frequency = <100>;
+   cdone-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+   reset-gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+   };
-- 
2.7.4



[PATCH v11 1/3] of: Add vendor prefix for Lattice Semiconductor

2017-01-08 Thread Joel Holdsworth
Lattice Semiconductor Corporation is a manufacturer of integrated
circuits and IP products, including low-power FPGAs, video connectivity
devices and millimeter wave wireless products.

Website: http://latticesemi.com

Signed-off-by: Joel Holdsworth 
Acked-by: Rob Herring 
Acked-by: Alan Tull 
Acked-by: Moritz Fischer 
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 4ec84b7..5f8e533 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -159,6 +159,7 @@ kosagi  Sutajio Ko-Usagi PTE Ltd.
 kyoKyocera Corporation
 lacie  LaCie
 lantiq Lantiq Semiconductor
+latticeLattice Semiconductor
 lenovo Lenovo Group Ltd.
 lg LG Corporation
 licheepi   Lichee Pi
-- 
2.7.4



Re: [RFC] drm: Parse HDMI 2.0 YCbCr 4:2:0 VDB and VCB

2017-01-08 Thread Sharma, Shashank

Regards

Shashank


On 12/30/2016 10:23 PM, Jose Abreu wrote:

HDMI 2.0 introduces a new sampling mode called YCbCr 4:2:0.
According to the spec the EDID may contain two blocks that
signal this sampling mode:
- YCbCr 4:2:0 Video Data Block
- YCbCr 4:2:0 Video Capability Map Data Block

The video data block contains the list of vic's were
only YCbCr 4:2:0 sampling mode shall be used while the
video capability map data block contains a mask were
YCbCr 4:2:0 sampling mode may be used.

This RFC patch adds support for parsing these two new blocks
and introduces new flags to signal the drivers if the
mode is 4:2:0'only or 4:2:0'able.

The reason this is still a RFC is because there is no
reference in kernel for this new sampling mode (specially in
AVI infoframe part), so, I was hoping to hear some feedback
first.

Tested in a HDMI 2.0 compliance scenario.

Signed-off-by: Jose Abreu 
Cc: Carlos Palminha 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: Sean Paul 
Cc: David Airlie 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
---
  drivers/gpu/drm/drm_edid.c  | 139 +++-
  drivers/gpu/drm/drm_modes.c |  10 +++-
  include/uapi/drm/drm_mode.h |   6 ++
  3 files changed, 151 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 67d6a73..6ce1a38 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2549,6 +2549,8 @@ static int drm_cvt_modes(struct drm_connector *connector,
  #define VENDOR_BLOCK0x03
  #define SPEAKER_BLOCK 0x04
  #define VIDEO_CAPABILITY_BLOCK0x07
+#define VIDEO_DATA_BLOCK_420   0x0E
+#define VIDEO_CAP_BLOCK_4200x0F
  #define EDID_BASIC_AUDIO  (1 << 6)
  #define EDID_CEA_YCRCB444 (1 << 5)
  #define EDID_CEA_YCRCB422 (1 << 4)
@@ -3050,6 +3052,98 @@ static int add_3d_struct_modes(struct drm_connector 
*connector, u16 structure,
return modes;
  }
  
+static int add_420_mode(struct drm_connector *connector, u8 vic)

+{
+   struct drm_device *dev = connector->dev;
+   struct drm_display_mode *newmode;
+
+   if (!drm_valid_cea_vic(vic))
+   return 0;
+
+   newmode = drm_mode_duplicate(dev, &edid_cea_modes[vic]);
Sorry to start the review late, I missed this mail chain. It would be 
great if you can please keep me in CC for this chain.


Practically, YUV420 modes are being used for 4k and UHD video modes. Now 
here, when we want to
add these modes from edid_cea_db, using the VIC index, we should have 
full list of cea_modes from 1 - 107
Particularly 93-107 ( which is for new 38x21 and 40x21 modes, added in 
CEA-861-F). right now, edid_cea_modes
cant index 4k modes, so practically this this patch series will do 
nothing (even though its doing everything right)


To handle this scenario, I had added a patch series 
https://patchwork.freedesktop.org/patch/119627/
(complete the cea modedb (VIC=65 onwards)) Now, this patch series had 
dependency on new aspect ratios
being added in CEA-861-F which I tried to add in series 
(https://patchwork.freedesktop.org/patch/116095/)
Which was added and later reverted by Ville 
(https://patchwork.freedesktop.org/patch/119808/).


In short, the method/sequence for effective development would be:
- Add aspect ratio support in DRM
- Add HDMI 2.0 (CEA-861-F) aspect ratios 
(https://patchwork.freedesktop.org/patch/116095/)
- Complete edid_cea_modes, adding new modes as per 4k VICs 
(https://patchwork.freedesktop.org/patch/119627/ )
- Parse these modes from 420_vdb and 420_vcb using edid_cea_modes db[]  
(This patch series)


And that we should re-prioritize the aspect ratio handling to target YUV 
420 handling from CEA blocks.

Shashank

+   if (!newmode)
+   return 0;
+
+   newmode->flags |= DRM_MODE_FLAG_420_ONLY;
+   drm_mode_probed_add(connector, newmode);
+
+   return 1;
+}
+
+static int add_420_vdb_modes(struct drm_connector *connector, const u8 *svds,
+   u8 svds_len)
+{
+   int modes = 0, i;
+
+   for (i = 0; i < svds_len; i++)
+   modes += add_420_mode(connector, svds[i]);
+
+   return modes;
+}
+
+static int add_420_vcb_modes(struct drm_connector *connector, const u8 *svds,
+   u8 svds_len, const u8 *video_db, u8 video_len)
+{
+   struct drm_display_mode *newmode = NULL;
+   int modes = 0, i, j;
+
+   for (i = 0; i < svds_len; i++) {
+   u8 mask = svds[i];
+   for (j = 0; j < 8; j++) {
+   if (mask & (1 << j)) {
+   newmode = drm_display_mode_from_vic_index(
+   connector, video_db, video_len,
+   i * 8 + j);
+   if (newmode) {
+   newmode->flags |= DRM_MODE_FLAG_420;
+   drm_mode_probed_add(connector, newmode);
+ 

RE: 174cc7187e6f ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

2017-01-08 Thread Zheng, Lv
Hi, Borislav

> From: Zheng, Lv
> Subject: RE: 174cc7187e6f ACPICA: Tables: Back port 
> acpi_get_table_with_size() and
> early_acpi_os_unmap_memory() from Linux kernel
> 
> Hi,
> 
> > From: linux-acpi-ow...@vger.kernel.org 
> > [mailto:linux-acpi-ow...@vger.kernel.org] On Behalf Of Zheng,
> > Lv
> > Subject: RE: 174cc7187e6f ACPICA: Tables: Back port 
> > acpi_get_table_with_size() and
> > early_acpi_os_unmap_memory() from Linux kernel
> >
> > Hi,
> >
> > > From: linux-acpi-ow...@vger.kernel.org 
> > > [mailto:linux-acpi-ow...@vger.kernel.org] On Behalf Of
> > Borislav
> > > Petkov
> > > Subject: Re: 174cc7187e6f ACPICA: Tables: Back port 
> > > acpi_get_table_with_size() and
> > > early_acpi_os_unmap_memory() from Linux kernel
> > >
> > > On Sun, Jan 08, 2017 at 03:20:20AM +0100, Rafael J. Wysocki wrote:
> > > >  drivers/iommu/amd_iommu_init.c |2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > Index: linux-pm/drivers/iommu/amd_iommu_init.c
> > > > ===
> > > > --- linux-pm.orig/drivers/iommu/amd_iommu_init.c
> > > > +++ linux-pm/drivers/iommu/amd_iommu_init.c
> > > > @@ -2230,7 +2230,7 @@ static int __init early_amd_iommu_init(v
> > > >  */
> > > > ret = check_ivrs_checksum(ivrs_base);
> > > > if (ret)
> > > > -   return ret;
> > > > +   goto out;
> > > >
> > > > amd_iommu_target_ivhd_type = 
> > > > get_highest_supported_ivhd_type(ivrs_base);
> > > > DUMP_printk("Using IVHD type %#x\n", 
> > > > amd_iommu_target_ivhd_type);
> > >
> > > Good catch, this one needs to be applied regardless.
> > >
> > > However, it doesn't fix my issue though.
> > >
> > > But I think I have it - I went and applied the well-proven debugging
> > > technique of sprinkling printks around. Here's what I'm seeing:
> > >
> > > early_amd_iommu_init()
> > > |-> acpi_put_table(ivrs_base);
> > > |-> acpi_tb_put_table(table_desc);
> > > |-> acpi_tb_invalidate_table(table_desc);
> > > |-> acpi_tb_release_table(...)
> > > |-> acpi_os_unmap_memory
> > > |-> acpi_os_unmap_iomem
> > > |-> acpi_os_map_cleanup
> > > |-> synchronize_rcu_expedited <-- the kernel/rcu/tree_exp.h version 
> > > with CONFIG_PREEMPT_RCU=y
> > >
> > > Now that function goes and sends IPIs, i.e., schedule_work()
> > > but this is too early - we haven't even done workqueue_init().
> > > Actually, from looking at the callstack, we do
> > > kernel_init_freeable->native_smp_prepare_cpus() and workqueue_init()
> > > comes next.
> > >
> > > And this makes sense because the splat rIP points to __queue_work() but
> > > we haven't done that yet.
> > >
> > > So that acpi_put_table() is happening too early. Looks like AMD IOMMU
> > > should not put the table but WTH do I know?!
> > >
> > > In any case, commenting out:
> > >
> > > acpi_put_table(ivrs_base);
> > > ivrs_base = NULL;
> > >
> > > and the end of early_amd_iommu_init() makes the box boot again.
> >
> > So please help to comment out these 2 lines (with descriptions and do not 
> > delete them).
> > Until acpi_os_unmap_memory() is able to handle such an early case.
> 
> IMO, synchronize_rcu_expedited() should be improved:
> If rcu_init() isn't called or there is nothing to synchronize, 
> schedule_work() shouldn't be invoked.


Hmm, I think this problem has its history.
In APEI code, NMI handlers cannot utilize spinlock.
So the developers there used RCU to synchronize NMI handlers before the 
register region is unmapped.
At that time, there might not be pre-map/post-unmap code prepared in the APEI 
drivers.
So the APEI developers relied on map/unmap logics implemented in the ACPICA 
register read/write APIs where the OSL map/unmap is invoked.

That's why the RCU code is in acpi_os_xxx().
If:
1. there is map/unmap/read/write operations available for APEI developers to 
invoke;
2. RCU synchronization is invoked before invoking the last unmap operation;
3. map/unmap/read/write order is strictly ensured inside of the APEI drivers.
Then we can remove RCU stuffs from acpi_os_xxx.
And the root cause of this issue can be fixed.

I'm not sure if this approach is possible, but can give it a try.
Before that I think all such acpi_put_table() should just be commented out.

Thanks and best regards
Lv

> 
> Thanks and best regards
> Lv
> 
> >
> > Thanks and best regards
> > Lv
> >
> > >
> > > --
> > > Regards/Gruss,
> > > Boris.
> > >
> > > Good mailing practices for 400: avoid top-posting and trim the reply.


  1   2   3   4   >