summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason M. Bills <jason.m.bills@linux.intel.com>2020-11-17 00:51:01 +0300
committerJason M. Bills <jason.m.bills@linux.intel.com>2020-11-17 01:37:09 +0300
commit18576aaaa49bf249aef0b72dd12fc452fccb6aed (patch)
treee3f3d79d24a0e6966b33fbdbbbecfe3bb2932efb
parent989cbcf37fea988ef6b76b9bc1cc5774bacda2cf (diff)
downloadopenbmc-18576aaaa49bf249aef0b72dd12fc452fccb6aed.tar.xz
Update to internal 0.74-155
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch185
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0050-Enable-CONFIG_DDR4_SUPPORT_HYNIX.patch28
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0052-Fix-issue-on-host-console-is-broken-due-to-BMC-reset.patch124
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0003-Fix-PSU-PWM-fan-control.patch61
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0004-Check-readingStateGood-before-updating-thresholds-pr.patch99
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0005-ExitAir-Move-to-GetSensorConfiguration.patch75
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0006-Treat-negative-temperatures-as-errors.patch73
-rw-r--r--meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors_%.bbappend6
-rw-r--r--meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.service10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.sh34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check_git.bb22
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem/0006-Update-Product-ID-for-EEPROM-FRU-platforms.patch230
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager/0001-disable-PSU-cold-redundancy.patch73
-rw-r--r--meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2/0001-Replace-throw-with-log-error-message.patch130
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch8
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0120-media-aspeed-adjust-irq-enabling-timing-and-resource.patch512
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0121-Add-a-WA-to-defer-flash-writes-on-PS_ALERT_N-asserti.patch191
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0123-peci-fix-error-handling-in-peci_dev_ioctl.patch43
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/1001-Igore-0x3FF-in-aspeed_adc-driver.patch75
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0001-Eliminate-swampd-core-dump-after-D-Bus-updates-senso.patch172
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0002-Prevent-run-away-memory-consumption-from-swamped.patch270
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0015-Fix-delete-image-by-ID-and-inhibit-removal-of-bmc_ac.patch153
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Fix-memory-leak.patch124
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Workaround-Fix-memory-leak.patch33
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0027-EventService-Improvements-and-limitations.patch265
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0028-EventService-Schedule-MetricReport-data-format.patch58
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0029-Added-Validation-on-MessageId-and-RegistryPrefix.patch166
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0030-Initialize-Event-Service-Config-on-bmcweb-restart.patch36
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0031-get-on-crashdump-can-follow-redfish-privileges.patch140
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0034-Avoid-using-deleted-Connection-in-Response.patch42
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0035-EventService-Fix-hostname-resolve-issue.patch137
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Redfish-TelemetryService-schema-implementation.patch43
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Add-support-for-POST-in-MetricReportDefinitions.patch2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-OnRequest-in-MetricReportDefinition.patch6
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-support-for-MetricDefinition-scheme.patch42
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch21
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0007-Treat-pwd-is-not-set-if-no-entry-in-shadow-for-usr.patch49
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit/0002-Add-support-for-ssl-config.patch66
-rw-r--r--meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit_git.bb1
50 files changed, 3586 insertions, 253 deletions
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch
index d52b1184a..4de12fd82 100644
--- a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch
+++ b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch
@@ -1,4 +1,4 @@
-From cc144438f78be5de8e9a67fd8cc898123e32d266 Mon Sep 17 00:00:00 2001
+From bd79f95696957ee1e63e4506e7f4d0693b7d1c6a Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Mon, 14 Sep 2020 17:38:28 -0700
Subject: [PATCH] Add WDT to u-boot to cover booting failures
@@ -13,150 +13,69 @@ timeout is 100 seconds.
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
- arch/arm/mach-aspeed/platform_g5.S | 78 ++++++++++++++++++++++++++++++
- board/aspeed/ast-g5/ast-g5-intel.c | 3 ++
- board/aspeed/ast-g5/ast-g5.c | 30 +++++++++++-
- common/bootm_os.c | 5 ++
- 4 files changed, 114 insertions(+), 2 deletions(-)
+ arch/arm/mach-aspeed/flash.c | 7 +++++++
+ arch/arm/mach-aspeed/platform_g5.S | 13 +++++++++++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 3 +++
+ board/aspeed/ast-g5/ast-g5.c | 30 ++++++++++++++++++++++++++++--
+ common/bootm_os.c | 5 +++++
+ 5 files changed, 56 insertions(+), 2 deletions(-)
+diff --git a/arch/arm/mach-aspeed/flash.c b/arch/arm/mach-aspeed/flash.c
+index d33fb9e0fe78..31bbf77e9e67 100644
+--- a/arch/arm/mach-aspeed/flash.c
++++ b/arch/arm/mach-aspeed/flash.c
+@@ -30,6 +30,7 @@
+ #include <asm/byteorder.h>
+ #include <asm/io.h>
+ #include <environment.h>
++#include <watchdog.h>
+
+ #include <asm/arch/ast_scu.h>
+ #include <asm/arch/aspeed.h>
+@@ -610,6 +611,9 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
+ }
+
+ putc ('.');
++#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
++ WATCHDOG_RESET();
++#endif
+ }
+ }
+ puts (" done\n");
+@@ -679,6 +683,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+ src += count;
+ cnt -= count;
+ printf("%c\b", pat[(patcnt++) & 0x03]);
++#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
++ WATCHDOG_RESET();
++#endif
+ }
+
+ reset_flash(info);
diff --git a/arch/arm/mach-aspeed/platform_g5.S b/arch/arm/mach-aspeed/platform_g5.S
-index f221c97b19dc..e468ed68d687 100644
+index f221c97b19dc..3a06557fa99d 100644
--- a/arch/arm/mach-aspeed/platform_g5.S
+++ b/arch/arm/mach-aspeed/platform_g5.S
-@@ -582,6 +582,31 @@ espi_early_init_done:
+@@ -582,6 +582,19 @@ espi_early_init_done:
mov r1, #0xAE
str r1, [r0]
+#ifdef CONFIG_HW_WATCHDOG
-+ /* Enable WDT1 to recover u-boot hang */
-+ ldr r0, =0x1e785004
++ /* Enable WDT2 to recover u-boot hang */
++ ldr r0, =0x1e785024
+ ldr r1, =0x00500000 @ ~5 seconds
+ str r1, [r0]
-+ ldr r0, =0x1e785008
++ ldr r0, =0x1e785028
+ ldr r1, =0x00004755
+ str r1, [r0]
-+ ldr r0, =0x1e78500c
++ ldr r0, =0x1e78502c
+ ldr r1, =0x00000033
+ str r1, [r0]
-+
-+ /* Clear Scratch register Bit 6 to do DDR training again on WDT1 reset */
-+ ldr r0, =0x1e6e203c
-+ ldr r1, [r0]
-+ tst r1, #(1<<2)
-+ beq bypass_scratch_reg_clear
-+ ldr r0, =0x1e6e2040
-+ ldr r1, [r0]
-+ and r1, r1, #0xFFFFFFBF
-+ str r1, [r0]
-+
-+bypass_scratch_reg_clear:
+#endif
+
/* Test - DRAM initial time */
ldr r0, =0x1e78203c
ldr r1, =0x0000F000
-@@ -2335,6 +2360,13 @@ spi_checksum_wait_0:
- ldr r1, [r0]
- tst r1, r2
- beq spi_checksum_wait_0
-+
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x31 @ '1'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- ldr r0, =0x1e620090
- ldr r5, [r0] @ record golden checksum
- ldr r0, =0x1e620080
-@@ -2363,6 +2395,13 @@ spi_checksum_wait_1:
- ldr r1, [r0]
- tst r1, r2
- beq spi_checksum_wait_1
-+
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- ldr r0, =0x1e620090
- ldr r2, [r0] @ read checksum
- ldr r0, =0x1e620080
-@@ -2377,6 +2416,13 @@ spi_checksum_wait_2:
- ldr r1, [r0]
- tst r1, r2
- beq spi_checksum_wait_2
-+
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- ldr r0, =0x1e620090
- ldr r2, [r0] @ read checksum
- ldr r0, =0x1e620080
-@@ -2394,6 +2440,12 @@ spi_cbr_next_delay_e:
- blt spi_cbr_next_delay_s
- b spi_cbr_next_clkrate
-
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- spi_cbr_end:
- ldr r0, =0x1e620094
- str r8, [r0]
-@@ -2401,6 +2453,16 @@ spi_cbr_end:
- mov r1, #0x0
- str r1, [r0]
-
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x32 @ '2'
-+ str r1, [r0]
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- /******************************************************************************
- Miscellaneous Setting
- ******************************************************************************/
-@@ -2447,6 +2509,16 @@ spi_cbr_end:
- mov r1, #0
- str r1, [r0]
-
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x33 @ '3'
-+ str r1, [r0]
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+ mov r1, #0x2E @ '.'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- /******************************************************************************
- Configure MAC timing
- ******************************************************************************/
-@@ -2535,6 +2607,12 @@ set_D2PLL:
- ldr r1, =0xEA
- str r1, [r0]
-
-+/* Debug - UART console message */
-+ ldr r0, =0x1e784000
-+ mov r1, #0x34 @ '4'
-+ str r1, [r0]
-+/* Debug - UART console message */
-+
- /* restore lr */
- mov lr, r4
-
diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
index c46bd70b71b2..92518a66fa67 100644
--- a/board/aspeed/ast-g5/ast-g5-intel.c
@@ -192,25 +111,25 @@ index 00bd92ae5f94..3f27503bce62 100644
{
- /* Restart WD2 timer */
- writel(0x4755, AST_WDT2_BASE + 0x08);
-+ /* Restart WDT1 */
++ /* Restart WDT2 */
+ writel(AST_WDT_RESTART_VALUE,
-+ AST_WDT1_BASE + AST_WDT_COUNTER_RESTART_CTRL);
++ AST_WDT2_BASE + AST_WDT_COUNTER_RESTART_CTRL);
+}
+
+void hw_watchdog_init(void)
+{
-+ writel(0, AST_WDT1_BASE + AST_WDT_CTRL);
++ writel(0, AST_WDT2_BASE + AST_WDT_CTRL);
+ writel(AST_WDT_TIMEOUT_DEFAULT,
-+ AST_WDT1_BASE + AST_WDT_COUNTER_RELOAD_VALUE);
++ AST_WDT2_BASE + AST_WDT_COUNTER_RELOAD_VALUE);
+ writel(AST_WDT_RESTART_VALUE,
-+ AST_WDT1_BASE + AST_WDT_COUNTER_RESTART_CTRL);
++ AST_WDT2_BASE + AST_WDT_COUNTER_RESTART_CTRL);
+ writel(AST_WDT_EN_1MHZ_CLK | AST_WDT_SYS_RESET | AST_WDT_ENABLE,
-+ AST_WDT1_BASE + AST_WDT_CTRL);
++ AST_WDT2_BASE + AST_WDT_CTRL);
+}
+
+void hw_watchdog_disable(void)
+{
-+ writel(0, AST_WDT1_BASE + AST_WDT_CTRL);
++ writel(0, AST_WDT2_BASE + AST_WDT_CTRL);
}
#endif /* CONFIG_WATCHDOG */
diff --git a/common/bootm_os.c b/common/bootm_os.c
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0050-Enable-CONFIG_DDR4_SUPPORT_HYNIX.patch b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0050-Enable-CONFIG_DDR4_SUPPORT_HYNIX.patch
deleted file mode 100644
index d8309f32c..000000000
--- a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0050-Enable-CONFIG_DDR4_SUPPORT_HYNIX.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From daa5fdb53f4ed5d40063daf3a3b8ee40115fe5bd Mon Sep 17 00:00:00 2001
-From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
-Date: Fri, 11 Sep 2020 09:19:43 -0700
-Subject: [PATCH] Enable CONFIG_DDR4_SUPPORT_HYNIX
-
-This commit enables CONFIG_DDR4_SUPPORT_HYNIX for test.
-
-Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
----
- arch/arm/mach-aspeed/platform_g5.S | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/arch/arm/mach-aspeed/platform_g5.S b/arch/arm/mach-aspeed/platform_g5.S
-index f221c97b19dc..4276d6db3a9a 100644
---- a/arch/arm/mach-aspeed/platform_g5.S
-+++ b/arch/arm/mach-aspeed/platform_g5.S
-@@ -149,7 +149,7 @@
- on the MB layout. Customer can find the appropriate frequency for their products.
- Below are the new defined parameters for the Hynix DDR4 supporting.
- ******************************************************************************/
--//#define CONFIG_DDR4_SUPPORT_HYNIX @ Enable this when Hynix DDR4 included in the BOM
-+#define CONFIG_DDR4_SUPPORT_HYNIX @ Enable this when Hynix DDR4 included in the BOM
- //#define CONFIG_DDR4_HYNIX_SET_1536
- //#define CONFIG_DDR4_HYNIX_SET_1488
- #define CONFIG_DDR4_HYNIX_SET_1440
---
-2.17.1
-
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0052-Fix-issue-on-host-console-is-broken-due-to-BMC-reset.patch b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0052-Fix-issue-on-host-console-is-broken-due-to-BMC-reset.patch
new file mode 100644
index 000000000..3c1705c05
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/files/0052-Fix-issue-on-host-console-is-broken-due-to-BMC-reset.patch
@@ -0,0 +1,124 @@
+From b6f1f040f515a43d1903f4c4020032dfe436670d Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Sun, 27 Sep 2020 17:45:56 +0800
+Subject: [PATCH] Fix issue on host console is broken due to BMC reset by
+ watchdog.
+
+obmc-console service changed uart routing to support SOL.
+UART routing must be changed to normal, when BMC reset happens,
+as BMC reset must be treated as SOL connection closure.
+User needs to establish a new SOL connection after BMC reset,
+and routing will be initialized for SOL at that time.
+Which need several seconds (depends on BMC cycle time),
+or even never been recoverred if stopped at u-boot shell.
+
+error situaton as below:
+root@intel-obmc:~# devmem 0x1e78909c
+0x03450003
+root@intel-obmc:~# /sbin/watchdog -T 0 -F /dev/watchdog1
+
+U-Boot 2016.07 (Aug 25 2020 - 05:24:44 +0000)
+
+SOC : AST2500-A2
+RST : 0x08 (WDT2)
+PLL : 24 MHz
+CPU : 792 MHz
+MEM : 792 MHz, EEC: Disable, Cache: Disable
+VGA : 16 MiB
+DRAM : init by SOC
+ Watchdog enabled
+DRAM: 496 MiB
+Flash: 64 MiB
+In: serial
+Out: serial
+Err: serial
+Un-Protected 1 sectors
+Un-Protected 1 sectors
+Erasing Flash...
+. done
+Erased 1 sectors
+Writing to Flash... done
+Protected 1 sectors
+Protected 1 sectors
+Net: MAC0 : RMII/NCSI
+MAC1 : RGMII
+FTGMAC100#0, FTGMAC100#1
+ast#
+ast#
+ast# md 0x1e78909c
+1e78909c: 03450003 ffceff00 19000000 00000000
+
+Tested:
+u-boot could reset HICRA 0x1e78909c
+
+correct situation as below:
+root@intel-obmc:~# devmem 0x1e78909c
+0x03450003
+root@intel-obmc:~# /sbin/watchdog -T 0 -F /dev/watchdog1
+
+U-Boot 2016.07 (Sep 27 2020 - 09:34:20 +0000)
+
+SOC : AST2500-A2
+RST : 0x08 (WDT2)
+PLL : 24 MHz
+CPU : 792 MHz
+MEM : 792 MHz, EEC: Disable, Cache: Disable
+VGA : 16 MiB
+DRAM : init by SOC
+ Watchdog enabled
+DRAM: 496 MiB
+Flash: 64 MiB
+In: serial
+Out: serial
+Err: serial
+Un-Protected 1 sectors
+Un-Protected 1 sectors
+Erasing Flash...
+. done
+Erased 1 sectors
+Writing to Flash... done
+Protected 1 sectors
+Protected 1 sectors
+Net: MAC0 : RMII/NCSI
+MAC1 : RGMII
+FTGMAC100#0, FTGMAC100#1
+ast#
+ast#
+ast# md 0x1e78909c
+1e78909c: 00000000 ffceff00 19000000 00000000
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ arch/arm/include/asm/arch-aspeed/regs-lpc.h | 1 +
+ board/aspeed/ast-g5/ast-g5.c | 3 +++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-aspeed/regs-lpc.h b/arch/arm/include/asm/arch-aspeed/regs-lpc.h
+index b0162ae4f3..b4d3da2906 100644
+--- a/arch/arm/include/asm/arch-aspeed/regs-lpc.h
++++ b/arch/arm/include/asm/arch-aspeed/regs-lpc.h
+@@ -18,6 +18,7 @@
+ */
+
+ #define AST_LPC_HICR5 0x80
++#define AST_LPC_HICRA 0x9C
+ #define AST_LPC_HICRB 0x100
+
+ /* AST_LPC_HICR5 : 0x80 Host Interface Control Register 5 */
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index 00bd92ae5f..4c5997ab8a 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -45,6 +45,9 @@ int board_init(void)
+ val |= LPC_HICRB_ILPC2AHB;
+ writel(val, AST_LPC_BASE + AST_LPC_HICRB);
+
++ /* Reset UART routing */
++ writel(0x0, AST_LPC_BASE + AST_LPC_HICRA);
++
+ /* P2A, PCIe BMC */
+ val = readl(AST_SCU_BASE + AST_SCU_PCIE_CONFIG_SET);
+ val &= ~(SCU_PCIE_CONFIG_SET_BMC_DMA
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend
index fe150bf9d..a229bd969 100644
--- a/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend
+++ b/meta-openbmc-mods/meta-ast2500/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend
@@ -47,8 +47,8 @@ SRC_URI_append_intel-ast2500 = " \
file://0046-Enable-FMC-DMA-for-memmove.patch \
file://0047-ast2500-parse-reset-reason.patch \
file://0049-Add-WDT-to-u-boot-to-cover-booting-failures.patch \
- file://0050-Enable-CONFIG_DDR4_SUPPORT_HYNIX.patch \
file://0051-Add-Aspeed-DRAM-stress-test-command.patch \
+ file://0052-Fix-issue-on-host-console-is-broken-due-to-BMC-reset.patch \
"
# CVE-2020-10648 vulnerability fix
SRC_URI_append_intel-ast2500 = " \
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0003-Fix-PSU-PWM-fan-control.patch b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0003-Fix-PSU-PWM-fan-control.patch
new file mode 100644
index 000000000..49aaaf5f9
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0003-Fix-PSU-PWM-fan-control.patch
@@ -0,0 +1,61 @@
+From ed3e946c02c89c389c0e28360692e51971734728 Mon Sep 17 00:00:00 2001
+From: James Feist <james.feist@linux.intel.com>
+Date: Thu, 24 Sep 2020 15:31:03 -0700
+Subject: [PATCH 1/1] Fix PSU PWM fan control
+
+105a19754f003956def5934612b1de86225a4bc1 broke the control
+interface range as the interface is supposed to accept 0-255
+fix it.
+
+Tested:
+PSU PID control worked again
+
+Change-Id: I89c03c3382b221256353cc28b1f182c80a063249
+Signed-off-by: James Feist <james.feist@linux.intel.com>
+---
+ src/PwmSensor.cpp | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/PwmSensor.cpp b/src/PwmSensor.cpp
+index 0c5d439..4824489 100644
+--- a/src/PwmSensor.cpp
++++ b/src/PwmSensor.cpp
+@@ -27,6 +27,7 @@
+ static constexpr size_t sysPwmMax = 255;
+ static constexpr size_t psuPwmMax = 100;
+ static constexpr double defaultPwm = 30.0;
++static constexpr size_t targetIfaceMax = 255;
+
+ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
+ std::shared_ptr<sdbusplus::asio::connection>& conn,
+@@ -99,7 +100,7 @@ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
+ controlInterface->register_property(
+ "Target", static_cast<uint64_t>(pwmValue),
+ [this](const uint64_t& req, uint64_t& resp) {
+- if (req > pwmMax)
++ if (req > targetIfaceMax)
+ {
+ throw std::runtime_error("Value out of range");
+ return -1;
+@@ -108,7 +109,8 @@ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
+ {
+ return 1;
+ }
+- setValue(req);
++ setValue(
++ std::round(pwmMax * static_cast<double>(req) / targetIfaceMax));
+ resp = req;
+
+ sensorInterface->signal_property("Value");
+@@ -117,6 +119,8 @@ PwmSensor::PwmSensor(const std::string& name, const std::string& sysPath,
+ },
+ [this](uint64_t& curVal) {
+ uint64_t value = getValue();
++ value = static_cast<uint64_t>(std::round(
++ (static_cast<double>(value) / pwmMax) * targetIfaceMax));
+ if (curVal != value)
+ {
+ curVal = value;
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0004-Check-readingStateGood-before-updating-thresholds-pr.patch b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0004-Check-readingStateGood-before-updating-thresholds-pr.patch
new file mode 100644
index 000000000..ae626661a
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0004-Check-readingStateGood-before-updating-thresholds-pr.patch
@@ -0,0 +1,99 @@
+From 22a81c2898d6d3da1ba82cd9efead70b860b0acb Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Thu, 1 Oct 2020 08:54:32 -0700
+Subject: [PATCH] Check readingStateGood before updating thresholds property
+
+Sensor read function checks for readingStateGood before
+start. But if host resets while reading is in progress,
+incorrect sensor value maybe returned.
+Check readingStateGood before changing threshold.
+
+Add a timer async call for checkThresholds. This gives
+power match callback a chance to run to update power state.
+This change is only added for cpu sensors to minimize the
+the impact and test needed. Change for other sensors or
+in base class can be done as a follow up task.
+
+Tested:
+Run host reset test for 500 cycles, no erronous sensor
+events were reported. Before the change, same tests
+never run more than 200 cycles.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ include/CPUSensor.hpp | 1 +
+ src/CPUSensor.cpp | 18 +++++++++++++++---
+ src/Thresholds.cpp | 10 ++++++++++
+ 3 files changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/include/CPUSensor.hpp b/include/CPUSensor.hpp
+index 07f7ffd..4a56b21 100644
+--- a/include/CPUSensor.hpp
++++ b/include/CPUSensor.hpp
+@@ -37,6 +37,7 @@ class CPUSensor : public Sensor
+
+ private:
+ sdbusplus::asio::object_server& objServer;
++ std::shared_ptr<sdbusplus::asio::connection>& busConn;
+ boost::asio::posix::stream_descriptor inputDev;
+ boost::asio::deadline_timer waitTimer;
+ boost::asio::streambuf readBuf;
+diff --git a/src/CPUSensor.cpp b/src/CPUSensor.cpp
+index 127d68a..401412f 100644
+--- a/src/CPUSensor.cpp
++++ b/src/CPUSensor.cpp
+@@ -45,8 +45,8 @@ CPUSensor::CPUSensor(const std::string& path, const std::string& objectType,
+ Sensor(boost::replace_all_copy(sensorName, " ", "_"),
+ std::move(_thresholds), sensorConfiguration, objectType, maxReading,
+ minReading, PowerState::on),
+- objServer(objectServer), inputDev(io), waitTimer(io), path(path),
+- privTcontrol(std::numeric_limits<double>::quiet_NaN()),
++ objServer(objectServer), busConn(conn), inputDev(io), waitTimer(io),
++ path(path), privTcontrol(std::numeric_limits<double>::quiet_NaN()),
+ dtsOffset(dtsOffset), show(show), pollTime(CPUSensor::sensorPollMs)
+ {
+ nameTcontrol = labelTcontrol;
+@@ -288,6 +288,18 @@ void CPUSensor::checkThresholds(void)
+ {
+ if (show)
+ {
+- thresholds::checkThresholds(this);
++ // give the power match callback to have a chance to run
++ // checkThresholds checks for host power state
++ auto timer = std::make_shared<boost::asio::steady_timer>(
++ busConn->get_io_context());
++ timer->expires_after(std::chrono::milliseconds(100));
++ timer->async_wait([this, timer](boost::system::error_code ec) {
++ if (ec)
++ {
++ // log the error but still check the thresholds
++ std::cerr << "Cpu sensor threshold timer error!\n";
++ }
++ thresholds::checkThresholds(this);
++ });
+ }
+ }
+diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
+index 025057e..ce1c759 100644
+--- a/src/Thresholds.cpp
++++ b/src/Thresholds.cpp
+@@ -421,6 +421,16 @@ void assertThresholds(Sensor* sensor, double assertValue,
+ return;
+ }
+
++ // readingState is verified before sensor read,
++ // but it can change during sensor read
++ // and return an incorrect value
++ if (assert && !sensor->readingStateGood())
++ {
++ std::cout << "bad readingState, ignore theshold assert " << sensor->name
++ << " assert value " << assertValue << "\n";
++ return;
++ }
++
+ if (interface->set_property<bool, true>(property, assert))
+ {
+ try
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0005-ExitAir-Move-to-GetSensorConfiguration.patch b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0005-ExitAir-Move-to-GetSensorConfiguration.patch
new file mode 100644
index 000000000..a7533b88a
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0005-ExitAir-Move-to-GetSensorConfiguration.patch
@@ -0,0 +1,75 @@
+From 655f376a240ce73f7c3fb6f37cd6da0cbce1693e Mon Sep 17 00:00:00 2001
+From: James Feist <james.feist@linux.intel.com>
+Date: Mon, 5 Oct 2020 15:28:15 -0700
+Subject: [PATCH 1/1] ExitAir: Move to GetSensorConfiguration
+
+GetSensorConfiguration has improved to have retries
+and avoid more expensive GetManagedOjects calls. Use
+it.
+
+Tested: System Airflow still worked
+
+Change-Id: Icbbabb6ebda771b9cde563559a83f633ffc3769f
+Signed-off-by: James Feist <james.feist@linux.intel.com>
+---
+ src/ExitAirTempSensor.cpp | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/src/ExitAirTempSensor.cpp b/src/ExitAirTempSensor.cpp
+index 41d9a19..c667457 100644
+--- a/src/ExitAirTempSensor.cpp
++++ b/src/ExitAirTempSensor.cpp
+@@ -61,6 +61,9 @@ static constexpr double cfmMinReading = 0;
+
+ static constexpr size_t minSystemCfm = 50;
+
++constexpr const std::array<const char*, 2> monitorIfaces = {exitAirIface,
++ cfmIface};
++
+ static std::vector<std::shared_ptr<CFMSensor>> cfmSensors;
+
+ static void setupSensorMatch(
+@@ -827,14 +830,10 @@ void createSensor(sdbusplus::asio::object_server& objectServer,
+ std::cerr << "Connection not created\n";
+ return;
+ }
+- dbusConnection->async_method_call(
+- [&](boost::system::error_code ec, const ManagedObjectType& resp) {
+- if (ec)
+- {
+- std::cerr << "Error contacting entity manager\n";
+- return;
+- }
+-
++ auto getter = std::make_shared<GetSensorConfiguration>(
++ dbusConnection,
++ std::move([&objectServer, &dbusConnection,
++ &exitAirSensor](const ManagedObjectType& resp) {
+ cfmSensors.clear();
+ for (const auto& pathPair : resp)
+ {
+@@ -908,9 +907,9 @@ void createSensor(sdbusplus::asio::object_server& objectServer,
+ exitAirSensor->setupMatches();
+ exitAirSensor->updateReading();
+ }
+- },
+- entityManagerName, "/", "org.freedesktop.DBus.ObjectManager",
+- "GetManagedObjects");
++ }));
++ getter->getConfiguration(
++ std::vector<std::string>(monitorIfaces.begin(), monitorIfaces.end()));
+ }
+
+ int main()
+@@ -944,8 +943,6 @@ int main()
+ }
+ });
+ };
+- constexpr const std::array<const char*, 2> monitorIfaces = {exitAirIface,
+- cfmIface};
+ for (const char* type : monitorIfaces)
+ {
+ auto match = std::make_unique<sdbusplus::bus::match::match>(
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0006-Treat-negative-temperatures-as-errors.patch b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0006-Treat-negative-temperatures-as-errors.patch
new file mode 100644
index 000000000..13dc820d6
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors/0006-Treat-negative-temperatures-as-errors.patch
@@ -0,0 +1,73 @@
+From 6f6b9cb68992e3493489d16b28bd0903e66ce587 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Tue, 6 Oct 2020 15:34:29 -0700
+Subject: [PATCH] Treat negative temperatures as errors
+
+During normal operations, temperature sensors are not expected to
+read as zero or have negative values.
+There might be some other root cause need to be identified
+and addressed. Treat zeros and negative readings as errors
+in temperatures as a workaround.
+
+Tested:
+Valid temperature reading are being reported.
+Negative readings are ignored.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ src/HwmonTempSensor.cpp | 13 +++++++++++--
+ src/IpmbSensor.cpp | 7 ++++---
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/src/HwmonTempSensor.cpp b/src/HwmonTempSensor.cpp
+index 649ca68..5514504 100644
+--- a/src/HwmonTempSensor.cpp
++++ b/src/HwmonTempSensor.cpp
+@@ -116,8 +116,17 @@ void HwmonTempSensor::handleResponse(const boost::system::error_code& err)
+ try
+ {
+ double nvalue = std::stod(response);
+- nvalue /= sensorScaleFactor;
+- updateValue(nvalue);
++ if (nvalue < 0)
++ {
++ std::cerr << "Hwmon temp sensor " << name
++ << ": ignore negative rawValue " << nvalue << "\n";
++ incrementError();
++ }
++ else
++ {
++ nvalue /= sensorScaleFactor;
++ updateValue(nvalue);
++ }
+ }
+ catch (const std::invalid_argument&)
+ {
+diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
+index bc9d842..1855519 100644
+--- a/src/IpmbSensor.cpp
++++ b/src/IpmbSensor.cpp
+@@ -241,7 +241,6 @@ bool IpmbSensor::processReading(const std::vector<uint8_t>& data, double& resp)
+ return false;
+ }
+ resp = data[0];
+-
+ return true;
+ }
+ case (ReadingFormat::byte3):
+@@ -341,8 +340,10 @@ void IpmbSensor::read(void)
+ }
+
+ double value = 0;
+-
+- if (!processReading(data, value))
++ // Temperature sensors are not expected to read 0
++ // treat them as errors
++ if (!processReading(data, value) ||
++ (subType == IpmbSubType::temp && value == 0.0))
+ {
+ incrementError();
+ read();
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors_%.bbappend b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors_%.bbappend
index a8a74f3e0..a265f04df 100644
--- a/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors_%.bbappend
+++ b/meta-openbmc-mods/meta-ast2500/recipes-phosphor/sensors/dbus-sensors_%.bbappend
@@ -1,4 +1,8 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://0001-Only-allow-drive-sensors-on-bus-2-for-ast2500.patch \
- file://0002-Fix-missing-threshold-de-assert-event-when-threshold.patch"
+ file://0002-Fix-missing-threshold-de-assert-event-when-threshold.patch \
+ file://0003-Fix-PSU-PWM-fan-control.patch \
+ file://0004-Check-readingStateGood-before-updating-thresholds-pr.patch \
+ file://0005-ExitAir-Move-to-GetSensorConfiguration.patch \
+ file://0006-Treat-negative-temperatures-as-errors.patch"
diff --git a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
index 034f7ac70..1caf28239 100644
--- a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
+++ b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
@@ -45,6 +45,7 @@ IMAGE_INSTALL_append = " \
virtual-media \
enable-nics \
host-misc-comm-manager \
+ dhcp-check \
"
IMAGE_INSTALL_append = " ${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'pfr-manager', '', d)}"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
index ae6303668..b603cdefe 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
+++ b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb
@@ -13,7 +13,7 @@ LICENSE = "Proprietary"
LIC_FILES_CHKSUM = "file://LICENSE;md5=43c09494f6b77f344027eea0a1c22830"
SRC_URI = "git://github.com/Intel-BMC/crashdump;protocol=git"
-SRCREV = "wht-1.0"
+SRCREV = "wht-1.0.4"
S = "${WORKDIR}/git"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.service b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.service
new file mode 100644
index 000000000..f32935a7f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Check for DHCP address
+After=network.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/dhcp-check.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.sh b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.sh
new file mode 100644
index 000000000..e2ee80d89
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check/dhcp-check.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# if eth0 is configured DHCP and the interface is up (has carrier) and there is
+# no IP address after 2 mins, restart the interface to try again
+
+LOG_TAG=dhcp-check
+CHK_DELAY=120
+CFG_DELAY=60
+IFC=eth0
+NETWORK_CONFIG=/etc/systemd/network/00-bmc-${IFC}.network
+
+carrier=$(cat /sys/class/net/${IFC}/carrier 2>/dev/null)
+if [[ "$carrier" == "1" ]]; then
+ dhcp=$(egrep -c "DHCP=(true|ipv4)" $NETWORK_CONFIG)
+ if [[ "$dhcp" != "0" ]]; then
+ # Give time for DHCP address to be configured
+ sleep $CHK_DELAY
+
+ hasip=$(ip addr show dev ${IFC} | grep -c dynamic)
+ if [[ "$hasip" == "0" ]]; then
+ logger -t $LOG_TAG \
+ "$IFC: No DHCP address after ${CHK_DELAY}s; reconfigure"
+ networkctl reconfigure $IFC
+
+ # give time for network to come up and acquire DHCP address
+ sleep $CFG_DELAY
+ fi
+
+ IP=$(ip addr show dev ${IFC} | sed -n '/dynamic/s/^.*inet \([0-9\.]*\).*$/\1/p')
+ logger -t $LOG_TAG "$IFC: DHCP address $IP"
+ fi
+fi
+
+exit 0
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check_git.bb b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check_git.bb
new file mode 100644
index 000000000..19ee407d7
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dhcp-check/dhcp-check_git.bb
@@ -0,0 +1,22 @@
+SUMMARY = "DHCP Check"
+DESCRIPTION = "Script to check and restart network interface if DHCP fails to get an address"
+
+S = "${WORKDIR}"
+SRC_URI = "file://dhcp-check.sh \
+ file://dhcp-check.service \
+"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658"
+RDEPENDS_${PN} += "bash"
+
+inherit obmc-phosphor-systemd
+
+FILES_${PN} += "${systemd_system_unitdir}/dhcp-check.service"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 ${S}/dhcp-check.sh ${D}/${bindir}/dhcp-check.sh
+}
+
+SYSTEMD_SERVICE_${PN} += " dhcp-check.service"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem/0006-Update-Product-ID-for-EEPROM-FRU-platforms.patch b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem/0006-Update-Product-ID-for-EEPROM-FRU-platforms.patch
new file mode 100644
index 000000000..93dcc1c33
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem/0006-Update-Product-ID-for-EEPROM-FRU-platforms.patch
@@ -0,0 +1,230 @@
+From a9899d878d49c5d37810f2d97a68ae9d1de1a390 Mon Sep 17 00:00:00 2001
+From: Anoop S <anoopx.s@intel.com>
+Date: Fri, 2 Oct 2020 13:32:05 +0000
+Subject: [PATCH] Update Product ID for EEPROM FRU platforms.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Update Product ID based on property found in boards json config file,
+once entity-manager starts exposing it.
+
+This will be one-time update to ‘prodID’ file after dediprog flashing.
+This will be common logic for all baseboard EEPROM FRU platforms.
+This logic won't get effected for non-EEPROM FRU platfroms as its Product ID
+is already non-zero.
+
+Tested-by:
+1. Dediprog and redfish flash a platform (baseboard FRU platform type)
+ - System up and running.
+ - ‘Product ID’ is properly updated in ‘prodID’ file and working fine.
+2. Dediprog and redfish flash a platform.(filesystem FRU platform type)
+ - System up and running.
+ - Non-zero ‘Product ID’ in ‘prodID’ file is not modified by new logic
+ and working fine.
+3. Negative TestCase: The FRU is corrupted and tested.
+ - ‘Product ID’ value of 0x00 is remained in ‘prodID’ file, and same
+ will go in GetDeviceId() response.
+4. Negative TestCase: If ‘Product ID’ update failed or EntityManager
+ service not started before ipmiAppGetDeviceId() is invoked.
+ - ‘Product ID’ value of 0x00 is remained in ‘prodID’ file, and same
+ will go in GetDeviceId() response.
+
+Signed-off-by: Anoop S <anoopx.s@intel.com>
+Signed-off-by: Saravanan Palanisamy <saravanan.palanisamy@linux.intel.com>
+---
+ src/appcommands.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 6 deletions(-)
+
+diff --git a/src/appcommands.cpp b/src/appcommands.cpp
+index 10e3d13..d5b5c50 100644
+--- a/src/appcommands.cpp
++++ b/src/appcommands.cpp
+@@ -16,6 +16,7 @@
+ #include <byteswap.h>
+
+ #include <appcommands.hpp>
++#include <boost/algorithm/string/predicate.hpp>
+ #include <ipmid/api.hpp>
+ #include <ipmid/utils.hpp>
+ #include <nlohmann/json.hpp>
+@@ -45,6 +46,11 @@ static constexpr const char* bmcStateReadyStr =
+
+ static std::unique_ptr<sdbusplus::bus::match::match> bmcStateChangedSignal;
+ static uint8_t bmcDeviceBusy = true;
++std::unique_ptr<sdbusplus::bus::match::match> baseBoardUpdatedSignal;
++static constexpr const char* prodIdFilename = "/var/cache/private/prodID";
++static constexpr const char* baseBoardIntf =
++ "xyz.openbmc_project.Inventory.Item.Board.Motherboard";
++static uint16_t productId;
+
+ int initBMCDeviceState(ipmi::Context::ptr ctx)
+ {
+@@ -286,7 +292,6 @@ RspType<uint8_t, // Device ID
+ static bool devIdInitialized = false;
+ static bool bmcStateInitialized = false;
+ const char* filename = "/usr/share/ipmi-providers/dev_id.json";
+- const char* prodIdFilename = "/var/cache/private/prodID";
+ if (!fwVerInitialized)
+ {
+ std::string versionString;
+@@ -351,13 +356,13 @@ RspType<uint8_t, // Device ID
+ // boot time. Avoid using DBus to get the Product ID. The Product ID is
+ // stored in a non-volatile file now. The /usr/bin/checkFru.sh script,
+ // run during bootup, will populate the productIdFile.
+- std::fstream prodIdFile(prodIdFilename);
++ std::fstream prodIdFile(prodIdFilename, std::ios::in);
+ if (prodIdFile.is_open())
+ {
+- std::string id = "0x00";
+- char* end;
+- prodIdFile.getline(&id[0], id.size() + 1);
+- devId.prodId = std::strtol(&id[0], &end, 0);
++ uint16_t id = 0x00;
++ // id will become 0xFFFF (Reserved) if prodIdFile has invalid data.
++ prodIdFile >> std::hex >> id;
++ devId.prodId = id;
+ devIdInitialized = true;
+ }
+ else
+@@ -377,17 +382,137 @@ RspType<uint8_t, // Device ID
+ }
+ }
+
++ // Update the productId, if required.
++ if (!devId.prodId && productId)
++ {
++ devId.prodId = productId;
++ baseBoardUpdatedSignal.reset();
++ }
+ return ipmi::responseSuccess(devId.id, devId.revision, devId.fwMajor,
+ bmcDeviceBusy, devId.fwMinor, devId.ipmiVer,
+ devId.addnDevSupport, devId.manufId,
+ devId.prodId, devId.aux);
+ }
+
++static void getProductId(const std::string& baseboardObjPath)
++{
++ // Get the Baseboard object to find the Product id
++ constexpr std::chrono::microseconds IPMI_DBUS_TIMEOUT = 30s;
++ uint16_t propertyIdRead;
++
++ try
++ {
++ std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
++ std::string service =
++ getService(*dbus, baseBoardIntf, baseboardObjPath);
++ ipmi::Value property =
++ getDbusProperty(*dbus, service, baseboardObjPath, baseBoardIntf,
++ "ProductId", IPMI_DBUS_TIMEOUT);
++ propertyIdRead = static_cast<uint16_t>(std::get<uint64_t>(property));
++ }
++
++ catch (std::exception& ec)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "dbus call failed in getProductId",
++ phosphor::logging::entry("ERROR=%s", ec.what()));
++ return;
++ }
++ std::fstream prodIdFile(prodIdFilename, std::ios::in | std::ios::out);
++ if (prodIdFile.is_open())
++ {
++ uint16_t id = 0xFF;
++ prodIdFile >> std::hex >> id;
++ if (id == 0)
++ {
++ prodIdFile.seekp(0);
++ prodIdFile << "0x" << std::hex << propertyIdRead << std::endl;
++ productId = propertyIdRead;
++ }
++ }
++}
++
++static void getProductIdFromBoard()
++{
++ // If Product ID is already non-zero, just return.
++ std::fstream prodIdFile(prodIdFilename, std::ios::in);
++ if (prodIdFile.is_open())
++ {
++ uint16_t id = 0xFF;
++ prodIdFile >> std::hex >> id;
++ if (id != 0)
++ {
++ return;
++ }
++ }
++
++ // Register signal handler callback, 'baseBoardUpdatedSignal'.
++ namespace rules = sdbusplus::bus::match::rules;
++ const std::string filterStrPostIntfAdd =
++ rules::interfacesAdded() +
++ rules::argNpath(0, "/xyz/openbmc_project/inventory/system/board/");
++
++ auto callback = [](sdbusplus::message::message& m) {
++ sdbusplus::message::object_path objPath;
++ boost::container::flat_map<
++ std::string, boost::container::flat_map<
++ std::string, std::variant<std::string, uint64_t>>>
++ msgData;
++ m.read(objPath, msgData);
++ const auto intfFound = msgData.find(baseBoardIntf);
++ if (intfFound != msgData.cend())
++ {
++ getProductId(objPath.str);
++ return;
++ }
++ };
++ std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
++ baseBoardUpdatedSignal = std::make_unique<sdbusplus::bus::match::match>(
++ static_cast<sdbusplus::bus::bus&>(*bus), filterStrPostIntfAdd,
++ callback);
++
++ // Try by async_method_call() once by querying ObjectMapper.
++ bus->async_method_call(
++ [](boost::system::error_code ec, std::vector<std::string>& subtree) {
++ if (ec)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "dbus call failed in getSubTree of board interface.",
++ phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
++ return;
++ }
++ baseBoardUpdatedSignal.reset();
++ const std::string match = "board";
++ for (const std::string& objpath : subtree)
++ {
++ // Iterate over all retrieved ObjectPaths.
++ if (!boost::ends_with(objpath, match))
++ {
++ // Just move to next path.
++ continue;
++ }
++
++ // Baseboard object path found
++ getProductId(objpath);
++ return;
++ }
++ },
++ "xyz.openbmc_project.ObjectMapper",
++ "/xyz/openbmc_project/object_mapper",
++ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
++ "/xyz/openbmc_project/inventory", 0,
++ std::array<const char*, 1>{baseBoardIntf});
++
++ return;
++}
++
+ static void registerAPPFunctions(void)
+ {
+ // <Get Device ID>
+ registerHandler(prioOemBase, netFnApp, app::cmdGetDeviceId, Privilege::User,
+ ipmiAppGetDeviceId);
++ // Get Product ID from BaseBoard.json, if required.
++ getProductIdFromBoard();
+ }
+
+ } // namespace ipmi
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
index 75ecb2bd4..5bbf35e70 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend
@@ -12,4 +12,5 @@ SRC_URI += "file://0001-Fix-cold-redundancy-is-not-runing-as-user-configurat.pat
file://0003-storagecommands-Fix-for-GetFruAreaInfo-command.patch \
file://0004-firmware-update-Add-Support-to-get-fwSecurityVer.patch \
file://0005-oemcommands-Fix-for-set-security-mode-to-mfg-mode.patch \
+ file://0006-Update-Product-ID-for-EEPROM-FRU-platforms.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend b/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend
index a47d923f8..ba95727b4 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/os-release/os-release.bbappend
@@ -9,6 +9,8 @@ require version-vars.inc
OS_RELEASE_FIELDS_append = " OPENBMC_VERSION IPMI_MAJOR IPMI_MINOR IPMI_AUX13 IPMI_AUX14 IPMI_AUX15 IPMI_AUX16"
+OS_RELEASE_FIELDS_remove = "BUILD_ID"
+
python do_compile_append () {
import glob
with open(d.expand('${B}/os-release'), 'a') as f:
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager/0001-disable-PSU-cold-redundancy.patch b/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager/0001-disable-PSU-cold-redundancy.patch
new file mode 100644
index 000000000..23b805b87
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-intel/psu-manager/psu-manager/0001-disable-PSU-cold-redundancy.patch
@@ -0,0 +1,73 @@
+From 5829d9e6e1956ebb34ed8a723b0758146529459f Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Wed, 7 Oct 2020 22:42:26 +0530
+Subject: [PATCH] disable PSU cold redundancy
+
+In RP platforms, single PSU also considered as
+valid configuration. We don't have user configuration
+option to enable/disable PSU cold redundancy. So
+it should be disabled by default to avoid issues in
+Rp platforms.
+Also make sure if persistent config already set this
+to true, make it to false.
+
+This avoids unwanted critical event logs and
+unexpected LED status for RP platforms where
+single PSU also considered as valid config.
+
+Tested:
+ - Rebooted BMC and observed no CR event logs and
+ no amber blocking of status LED.
+ - Set the persistent store to true, rebooted
+ BMC and value changed back to disabled.
+
+Change-Id: Ie0f1f3f8daa95593af6db698d65ea804cebfee87
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ src/cold_redundancy.cpp | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/src/cold_redundancy.cpp b/src/cold_redundancy.cpp
+index d64a9e3..3bfd37f 100644
+--- a/src/cold_redundancy.cpp
++++ b/src/cold_redundancy.cpp
+@@ -76,8 +76,9 @@ ColdRedundancy::ColdRedundancy(
+ std::cerr << "error initializing assoc interface\n";
+ }
+
++ // For RP platforms, default cold redundancy should be disabled.
++ powerSupplyRedundancyEnabled(false);
+ // set default configuration
+- powerSupplyRedundancyEnabled(true);
+ rotationEnabled(true);
+ periodOfRotation(7 * oneDay);
+ rotationAlgorithm(Algo::bmcSpecific);
+@@ -109,6 +110,14 @@ ColdRedundancy::ColdRedundancy(
+ return;
+ }
+
++ // For RP platforms, cold redundancy should be disabled.
++ // If its already set to true in persistent area, Lets
++ // override to false during bootup.
++ if (*redundancyEnabled)
++ {
++ *redundancyEnabled = false;
++ }
++
+ if (*period >= minRotationPeriod && *period <= maxRotationPeriod)
+ {
+ periodOfRotation(*period);
+@@ -867,6 +876,10 @@ void ColdRedundancy::readPmbus(uint8_t bus, uint8_t slaveAddr, int& value)
+
+ void ColdRedundancy::checkRedundancyEvent()
+ {
++ if (!crSupported || !powerSupplyRedundancyEnabled())
++ {
++ return;
++ }
+ puRedundantTimer.expires_after(std::chrono::seconds(2));
+ puRedundantTimer.async_wait([this](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
index 631a70cef..b56098722 100644
--- a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
+++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb
@@ -17,6 +17,10 @@ inherit obmc-phosphor-systemd
SYSTEMD_SERVICE_${PN} += "smbios-mdrv2.service"
SYSTEMD_SERVICE_${PN} += "xyz.openbmc_project.cpuinfo.service"
+
+SRC_URI += "file://0001-Replace-throw-with-log-error-message.patch \
+"
+
DEPENDS += " \
autoconf-archive-native \
boost \
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2/0001-Replace-throw-with-log-error-message.patch b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2/0001-Replace-throw-with-log-error-message.patch
new file mode 100644
index 000000000..9cf75563e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2/0001-Replace-throw-with-log-error-message.patch
@@ -0,0 +1,130 @@
+From b84c3bd333a7b67d7b7ff73e12c382aa529f3e5c Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 20 Oct 2020 15:44:41 +0800
+Subject: [PATCH] Replace throw with log error message.
+
+Replace throw with log error message and return.
+When run into error, log error message but not crash
+smbios service as throw did.
+
+Tested:
+smbiosmdrv2app is working well.
+
+Change-Id: Ia2d40997987a0c84a613568d65f93006043459d0
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+---
+ src/mdrv2.cpp | 37 ++++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+diff --git a/src/mdrv2.cpp b/src/mdrv2.cpp
+index 9a73c65..c1bc09d 100644
+--- a/src/mdrv2.cpp
++++ b/src/mdrv2.cpp
+@@ -35,8 +35,9 @@ std::vector<uint8_t> MDR_V2::getDirectoryInformation(uint8_t dirIndex)
+ if (dirIndex > smbiosDir.dirEntries)
+ {
+ responseDir.push_back(0);
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "getDirectoryInformation: Invalid Parameter");
++ return responseDir;
+ }
+ responseDir.push_back(mdr2Version);
+ responseDir.push_back(smbiosDir.dirVersion);
+@@ -117,8 +118,6 @@ std::vector<uint8_t> MDR_V2::getDataOffer()
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "smbios is not ready for update");
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- UpdateInProgress();
+ }
+ return offer;
+ }
+@@ -173,8 +172,9 @@ std::vector<uint8_t> MDR_V2::getDataInformation(uint8_t idIndex)
+
+ if (idIndex >= maxDirEntries)
+ {
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "getDataInformation: Invalid Parameter");
++ return responseInfo;
+ }
+
+ for (uint8_t index = 0; index < sizeof(DataIdStruct); index++)
+@@ -253,15 +253,13 @@ bool MDR_V2::sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex,
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Send Dir info failed - input parameter invalid");
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ return teminate;
+ }
+ if (dirEntry.size() < sizeof(Mdr2DirEntry))
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Directory size invalid");
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ return teminate;
+ }
+ if (dirVersion == smbiosDir.dirVersion)
+ {
+@@ -307,8 +305,9 @@ bool MDR_V2::sendDataInformation(uint8_t idIndex, uint8_t flag,
+ {
+ if (idIndex >= maxDirEntries)
+ {
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "sendDataInformation: Invalid Parameter");
++ return false;
+ }
+ int entryChanged = 0;
+ if (smbiosDir.dir[idIndex].common.dataSetSize != dataLen)
+@@ -341,8 +340,7 @@ int MDR_V2::findIdIndex(std::vector<uint8_t> dataInfo)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Length of dataInfo invalid");
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
+- InvalidParameter();
++ return -1;
+ }
+ std::array<uint8_t, 16> arrayDataInfo;
+
+@@ -364,7 +362,9 @@ int MDR_V2::findIdIndex(std::vector<uint8_t> dataInfo)
+ return index;
+ }
+ }
+- throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::InvalidId();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "findIdIndex: Invalid ID");
++ return -1;
+ }
+
+ uint8_t MDR_V2::directoryEntries(uint8_t value)
+@@ -546,7 +546,9 @@ std::vector<boost::container::flat_map<std::string, RecordVariant>>
+
+ if (dataIn == nullptr)
+ {
+- throw std::runtime_error("Data not populated");
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Data not populated");
++ return ret;
+ }
+
+ do
+@@ -617,7 +619,8 @@ std::vector<boost::container::flat_map<std::string, RecordVariant>>
+ return ret;
+ }
+
+- throw std::invalid_argument("Invalid record type");
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Invalid record type");
+ return ret;
+ }
+
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch
index 088e1a02b..7a9a5626c 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch
@@ -1,4 +1,4 @@
-From 7ad89fd032d56cc20622d34cf9d0d09adacb2796 Mon Sep 17 00:00:00 2001
+From e82178e44348a8594bc4ae2c3c5473336033483f Mon Sep 17 00:00:00 2001
From: Yuan Li <yuan.li@linux.intel.com>
Date: Tue, 19 Sep 2017 15:55:39 +0800
Subject: [PATCH] arm: dts: add DTS for Intel ast2500 platforms
@@ -24,7 +24,7 @@ Signed-off-by: Arun P. Mohanan <arun.p.m@linux.intel.com>
diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts
new file mode 100644
-index 000000000000..7a09ca54f161
+index 000000000000..09198052fdd5
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts
@@ -0,0 +1,477 @@
@@ -56,9 +56,9 @@ index 000000000000..7a09ca54f161
+ #size-cells = <1>;
+ ranges;
+
-+ vga_memory: framebuffer@7f000000 {
++ vga_memory: framebuffer@9f000000 {
+ no-map;
-+ reg = <0x7f000000 0x01000000>;
++ reg = <0x9f000000 0x01000000>;
+ };
+
+ gfx_memory: framebuffer {
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0120-media-aspeed-adjust-irq-enabling-timing-and-resource.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0120-media-aspeed-adjust-irq-enabling-timing-and-resource.patch
new file mode 100644
index 000000000..3474f0c8b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0120-media-aspeed-adjust-irq-enabling-timing-and-resource.patch
@@ -0,0 +1,512 @@
+From 82109f3a6a9d044e7244f186eff53dac0bbe87fe Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Tue, 29 Sep 2020 16:29:28 -0700
+Subject: [PATCH] media: aspeed: adjust irq enabling timing and resource
+ handling
+
+This commit makes irq enabling to be after video engine
+initialization to avoid any garbage interrupt handling in
+uninitialized state. Also, this commit changes behavior of DMA
+memory allocation for frame buffers and JPEG header buffer from
+dynamic to static for better performance and to avoid any potential
+memory corruption issue caused by invalid DMA address or length.
+This commit also changes VR004[5] bit handling logic to set the bit
+only when capture and compression is triggered.
+
+Also, it fixes the clock enabling flow to give a sufficient delay
+to the video engine hardware to make it get stablized itself.
+Currently, only eclk is coupled with SCU04[6] reset flag for
+video engine so 10ms of delay will be made by the clk-aspeed module
+when this driver enables eclk. Thus, clock enabling order should
+be vclk and then eclk to get sufficient delay after enabling
+clocks and resetting the hardware.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ drivers/media/platform/aspeed-video.c | 245 ++++++++++++++++----------
+ 1 file changed, 151 insertions(+), 94 deletions(-)
+
+diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
+index a09cdb148c53..cf49c52fa5f0 100644
+--- a/drivers/media/platform/aspeed-video.c
++++ b/drivers/media/platform/aspeed-video.c
+@@ -52,9 +52,12 @@
+
+ #define VE_MAX_SRC_BUFFER_SIZE 0x8ca000 /* 1920 * 1200, 32bpp */
+ #define VE_JPEG_HEADER_SIZE 0x006000 /* 512 * 12 * 4 */
++#define VE_MAX_COMP_BUFFER_SIZE 0x400000 /* 128KB * 32 */
++#define VE_MAX_BCD_FLAG_BUFFER_SIZE 0x008ca0 /* (1920 / 4) * (1200 / 4) */
+
+ #define VE_PROTECTION_KEY 0x000
+ #define VE_PROTECTION_KEY_UNLOCK 0x1a038aa8
++#define VE_PROTECTION_KEY_LOCK 0x0
+
+ #define VE_SEQ_CTRL 0x004
+ #define VE_SEQ_CTRL_TRIG_MODE_DET BIT(0)
+@@ -105,6 +108,8 @@
+ #define VE_SCALING_FILTER2 0x020
+ #define VE_SCALING_FILTER3 0x024
+
++#define VE_BCD_CTRL 0x02c
++
+ #define VE_CAP_WINDOW 0x030
+ #define VE_COMP_WINDOW 0x034
+ #define VE_COMP_PROC_OFFSET 0x038
+@@ -113,6 +118,7 @@
+ #define VE_SRC0_ADDR 0x044
+ #define VE_SRC_SCANLINE_OFFSET 0x048
+ #define VE_SRC1_ADDR 0x04c
++#define VE_BCD_ADDR 0x050
+ #define VE_COMP_ADDR 0x054
+
+ #define VE_STREAM_BUF_SIZE 0x058
+@@ -168,6 +174,9 @@
+ #define VE_SYNC_STATUS_VSYNC_SHF 16
+ #define VE_SYNC_STATUS_VSYNC GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
+
++#define VE_VM_SRC_ADDR 0x244
++#define VE_VM_COMP_ADDR 0x254
++
+ #define VE_INTERRUPT_CTRL 0x304
+ #define VE_INTERRUPT_STATUS 0x308
+ #define VE_INTERRUPT_MODE_DETECT_WD BIT(0)
+@@ -234,8 +243,11 @@ struct aspeed_video {
+ unsigned int sequence;
+
+ unsigned int max_compressed_size;
++ struct reserved_mem *rsvd_mem;
+ struct aspeed_video_addr srcs[2];
+- struct aspeed_video_addr jpeg;
++ struct aspeed_video_addr jpeg_hdr;
++ struct aspeed_video_addr comp;
++ struct aspeed_video_addr bcd;
+
+ bool yuv420;
+ unsigned int frame_rate;
+@@ -439,6 +451,7 @@ static int aspeed_video_start_frame(struct aspeed_video *video)
+ unsigned long flags;
+ struct aspeed_video_buffer *buf;
+ u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
++ u32 comp_ctrl;
+
+ if (video->v4l2_input_status) {
+ dev_dbg(video->dev, "No signal; don't start frame\n");
+@@ -467,12 +480,23 @@ static int aspeed_video_start_frame(struct aspeed_video *video)
+ aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
+ aspeed_video_write(video, VE_COMP_OFFSET, 0);
+ aspeed_video_write(video, VE_COMP_ADDR, addr);
++ comp_ctrl = VE_COMP_CTRL_RSVD |
++ FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
++ FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
++ aspeed_video_update(video, VE_COMP_CTRL,
++ VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR,
++ comp_ctrl);
+
+ aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
+ VE_INTERRUPT_COMP_COMPLETE);
+
++ /* VE_SEQ_CTRL_AUTO_COMP should be set before VE_SEQ_CTRL_TRIG_COMP */
++ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_AUTO_COMP);
++ if (video->yuv420)
++ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
+ aspeed_video_update(video, VE_SEQ_CTRL, 0,
+- VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
++ VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP |
++ VE_SEQ_CTRL_JPEG_MODE);
+
+ return 0;
+ }
+@@ -497,8 +521,8 @@ static void aspeed_video_off(struct aspeed_video *video)
+ aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
+
+ /* Turn off the relevant clocks */
+- clk_disable(video->vclk);
+ clk_disable(video->eclk);
++ clk_disable(video->vclk);
+
+ clear_bit(VIDEO_CLOCKS_ON, &video->flags);
+ }
+@@ -509,8 +533,8 @@ static void aspeed_video_on(struct aspeed_video *video)
+ return;
+
+ /* Turn on the relevant clocks */
+- clk_enable(video->eclk);
+ clk_enable(video->vclk);
++ clk_enable(video->eclk);
+
+ set_bit(VIDEO_CLOCKS_ON, &video->flags);
+ }
+@@ -602,7 +626,10 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg)
+ aspeed_video_update(video, VE_SEQ_CTRL,
+ VE_SEQ_CTRL_TRIG_CAPTURE |
+ VE_SEQ_CTRL_FORCE_IDLE |
+- VE_SEQ_CTRL_TRIG_COMP, 0);
++ VE_SEQ_CTRL_TRIG_COMP |
++ VE_SEQ_CTRL_AUTO_COMP |
++ VE_SEQ_CTRL_YUV420 |
++ VE_SEQ_CTRL_JPEG_MODE, 0);
+ aspeed_video_update(video, VE_INTERRUPT_CTRL,
+ VE_INTERRUPT_COMP_COMPLETE, 0);
+ aspeed_video_write(video, VE_INTERRUPT_STATUS,
+@@ -686,6 +713,9 @@ static bool aspeed_video_alloc_buf(struct aspeed_video *video,
+ static void aspeed_video_free_buf(struct aspeed_video *video,
+ struct aspeed_video_addr *addr)
+ {
++ if (!addr->virt)
++ return;
++
+ dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
+ addr->size = 0;
+ addr->dma = 0ULL;
+@@ -824,14 +854,10 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
+ det->width = (video->frame_right - video->frame_left) + 1;
+ video->v4l2_input_status = 0;
+
+- /*
+- * Enable mode-detect watchdog, resolution-change watchdog and
+- * automatic compression after frame capture.
+- */
++ /* Enable mode-detect watchdog and resolution-change watchdog */
+ aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
+ VE_INTERRUPT_MODE_DETECT_WD);
+- aspeed_video_update(video, VE_SEQ_CTRL, 0,
+- VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
++ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_EN_WATCHDOG);
+
+ dev_dbg(video->dev, "Got resolution: %dx%d\n", det->width,
+ det->height);
+@@ -880,64 +906,38 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
+ } else {
+ aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH);
+ }
+-
+- size *= 4;
+-
+- if (size != video->srcs[0].size) {
+- if (video->srcs[0].size)
+- aspeed_video_free_buf(video, &video->srcs[0]);
+- if (video->srcs[1].size)
+- aspeed_video_free_buf(video, &video->srcs[1]);
+-
+- if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
+- goto err_mem;
+- if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
+- goto err_mem;
+-
+- aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
+- aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
+- }
+-
+- return;
+-
+-err_mem:
+- dev_err(video->dev, "Failed to allocate source buffers\n");
+-
+- if (video->srcs[0].size)
+- aspeed_video_free_buf(video, &video->srcs[0]);
+ }
+
+ static void aspeed_video_init_regs(struct aspeed_video *video)
+ {
+- u32 comp_ctrl = VE_COMP_CTRL_RSVD |
+- FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
+- FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
+ u32 ctrl = VE_CTRL_AUTO_OR_CURSOR;
+- u32 seq_ctrl = VE_SEQ_CTRL_JPEG_MODE;
+
+ if (video->frame_rate)
+ ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
+
+- if (video->yuv420)
+- seq_ctrl |= VE_SEQ_CTRL_YUV420;
+-
+ /* Unlock VE registers */
+ aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
+
++ /* Set buffer addresses */
++ aspeed_video_write(video, VE_MEM_RESTRICT_START, video->rsvd_mem->base);
++ aspeed_video_write(video, VE_MEM_RESTRICT_END,
++ video->rsvd_mem->base + video->rsvd_mem->size);
++ aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg_hdr.dma);
++ aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
++ aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
++ aspeed_video_write(video, VE_BCD_ADDR, video->bcd.dma);
++ aspeed_video_write(video, VE_VM_SRC_ADDR, video->srcs[0].dma);
++ aspeed_video_write(video, VE_VM_COMP_ADDR, video->comp.dma);
++
+ /* Disable interrupts */
+ aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
+ aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
+
+- /* Clear the offset */
+- aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
+- aspeed_video_write(video, VE_COMP_OFFSET, 0);
+-
+- aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
+-
+ /* Set control registers */
+- aspeed_video_write(video, VE_SEQ_CTRL, seq_ctrl);
++ aspeed_video_write(video, VE_SEQ_CTRL, 0);
++ aspeed_video_write(video, VE_COMP_CTRL, 0);
++ aspeed_video_write(video, VE_BCD_CTRL, 0);
+ aspeed_video_write(video, VE_CTRL, ctrl);
+- aspeed_video_write(video, VE_COMP_CTRL, comp_ctrl);
+
+ /* Don't downscale */
+ aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000);
+@@ -975,11 +975,8 @@ static void aspeed_video_stop(struct aspeed_video *video)
+
+ aspeed_video_off(video);
+
+- if (video->srcs[0].size)
+- aspeed_video_free_buf(video, &video->srcs[0]);
+-
+- if (video->srcs[1].size)
+- aspeed_video_free_buf(video, &video->srcs[1]);
++ /* Lock VE registers */
++ aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_LOCK);
+
+ video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
+ video->flags = 0;
+@@ -1275,8 +1272,9 @@ static void aspeed_video_update_jpeg_quality(struct aspeed_video *video)
+
+ static void aspeed_video_update_subsampling(struct aspeed_video *video)
+ {
+- if (video->jpeg.virt)
+- aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
++ if (video->jpeg_hdr.virt)
++ aspeed_video_init_jpeg_table(video->jpeg_hdr.virt,
++ video->yuv420);
+
+ if (video->yuv420)
+ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
+@@ -1511,6 +1509,8 @@ static int aspeed_video_setup_video(struct aspeed_video *video)
+ struct v4l2_device *v4l2_dev = &video->v4l2_dev;
+ struct vb2_queue *vbq = &video->queue;
+ struct video_device *vdev = &video->vdev;
++ struct device *dev = video->dev;
++ int irq;
+ int rc;
+
+ video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
+@@ -1535,12 +1535,9 @@ static int aspeed_video_setup_video(struct aspeed_video *video)
+ V4L2_JPEG_CHROMA_SUBSAMPLING_444);
+
+ if (video->ctrl_handler.error) {
+- v4l2_ctrl_handler_free(&video->ctrl_handler);
+- v4l2_device_unregister(v4l2_dev);
+-
+ dev_err(video->dev, "Failed to init controls: %d\n",
+ video->ctrl_handler.error);
+- return rc;
++ goto err_release_v4l2_dev;
+ }
+
+ v4l2_dev->ctrl_handler = &video->ctrl_handler;
+@@ -1558,11 +1555,8 @@ static int aspeed_video_setup_video(struct aspeed_video *video)
+
+ rc = vb2_queue_init(vbq);
+ if (rc) {
+- v4l2_ctrl_handler_free(&video->ctrl_handler);
+- v4l2_device_unregister(v4l2_dev);
+-
+ dev_err(video->dev, "Failed to init vb2 queue\n");
+- return rc;
++ goto err_release_v4l2_dev;
+ }
+
+ vdev->queue = vbq;
+@@ -1580,36 +1574,41 @@ static int aspeed_video_setup_video(struct aspeed_video *video)
+ video_set_drvdata(vdev, video);
+ rc = video_register_device(vdev, VFL_TYPE_GRABBER, 0);
+ if (rc) {
+- vb2_queue_release(vbq);
+- v4l2_ctrl_handler_free(&video->ctrl_handler);
+- v4l2_device_unregister(v4l2_dev);
+-
+ dev_err(video->dev, "Failed to register video device\n");
+- return rc;
++ goto err_release_vb2_queue;
+ }
+
+- return 0;
+-}
+-
+-static int aspeed_video_init(struct aspeed_video *video)
+-{
+- int irq;
+- int rc;
+- struct device *dev = video->dev;
+-
+ irq = irq_of_parse_and_map(dev->of_node, 0);
+ if (!irq) {
+ dev_err(dev, "Unable to find IRQ\n");
+- return -ENODEV;
++ rc = -ENODEV;
++ goto err_release_vb2_queue;
+ }
+
+ rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
+ IRQF_ONESHOT, DEVICE_NAME, video);
+- if (rc < 0) {
++ if (rc) {
+ dev_err(dev, "Unable to request IRQ %d\n", irq);
+- return rc;
++ goto err_release_vb2_queue;
+ }
+
++ return 0;
++
++err_release_vb2_queue:
++ vb2_queue_release(vbq);
++err_release_v4l2_dev:
++ v4l2_ctrl_handler_free(&video->ctrl_handler);
++ v4l2_device_unregister(v4l2_dev);
++
++ return rc;
++}
++
++static int aspeed_video_init(struct aspeed_video *video)
++{
++ int rc;
++ struct device *dev = video->dev;
++ struct device_node *node;
++
+ video->eclk = devm_clk_get(dev, "eclk");
+ if (IS_ERR(video->eclk)) {
+ dev_err(dev, "Unable to get ECLK\n");
+@@ -1631,7 +1630,24 @@ static int aspeed_video_init(struct aspeed_video *video)
+ if (rc)
+ goto err_unprepare_eclk;
+
+- of_reserved_mem_device_init(dev);
++ rc = of_reserved_mem_device_init(dev);
++ if (rc) {
++ dev_err(dev, "Unable to get reserved memory %d\n", rc);
++ goto err_unprepare_eclk;
++ }
++
++ node = of_parse_phandle(dev->of_node, "memory-region", 0);
++ if (!node) {
++ rc = -ENOENT;
++ goto err_unprepare_eclk;
++ }
++
++ video->rsvd_mem = of_reserved_mem_lookup(node);
++ of_node_put(node);
++ if (!video->rsvd_mem) {
++ rc = -ENOENT;
++ goto err_unprepare_eclk;
++ }
+
+ rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (rc) {
+@@ -1639,17 +1655,55 @@ static int aspeed_video_init(struct aspeed_video *video)
+ goto err_release_reserved_mem;
+ }
+
+- if (!aspeed_video_alloc_buf(video, &video->jpeg,
++ if (!aspeed_video_alloc_buf(video, &video->jpeg_hdr,
+ VE_JPEG_HEADER_SIZE)) {
+ dev_err(dev, "Failed to allocate DMA for JPEG header\n");
+ rc = -ENOMEM;
+ goto err_release_reserved_mem;
+ }
+
+- aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
++ if (!aspeed_video_alloc_buf(video, &video->srcs[0],
++ VE_MAX_SRC_BUFFER_SIZE)) {
++ dev_err(dev, "Failed to allocate DMA for SRCS[0]\n");
++ rc = -ENOMEM;
++ goto err_release_dma_mem;
++ }
++
++ if (!aspeed_video_alloc_buf(video, &video->srcs[1],
++ VE_MAX_SRC_BUFFER_SIZE)) {
++ dev_err(dev, "Failed to allocate DMA for SRCS[1]\n");
++ rc = -ENOMEM;
++ goto err_release_dma_mem;
++ }
++
++ if (!aspeed_video_alloc_buf(video, &video->comp,
++ VE_MAX_COMP_BUFFER_SIZE)) {
++ dev_err(dev, "Failed to allocate DMA for compressed video\n");
++ rc = -ENOMEM;
++ goto err_release_dma_mem;
++ }
++
++ if (!aspeed_video_alloc_buf(video, &video->bcd,
++ VE_MAX_BCD_FLAG_BUFFER_SIZE)) {
++ dev_err(dev, "Failed to allocate DMA for BCD flag\n");
++ rc = -ENOMEM;
++ goto err_release_dma_mem;
++ }
++
++ aspeed_video_init_jpeg_table(video->jpeg_hdr.virt, video->yuv420);
++
++ aspeed_video_on(video);
++ aspeed_video_init_regs(video);
++ aspeed_video_off(video);
+
+ return 0;
+
++err_release_dma_mem:
++ aspeed_video_free_buf(video, &video->comp);
++ aspeed_video_free_buf(video, &video->bcd);
++ aspeed_video_free_buf(video, &video->jpeg_hdr);
++ aspeed_video_free_buf(video, &video->srcs[0]);
++ aspeed_video_free_buf(video, &video->srcs[1]);
+ err_release_reserved_mem:
+ of_reserved_mem_device_release(dev);
+ clk_unprepare(video->vclk);
+@@ -1662,7 +1716,6 @@ static int aspeed_video_init(struct aspeed_video *video)
+ static int aspeed_video_probe(struct platform_device *pdev)
+ {
+ int rc;
+- struct resource *res;
+ struct aspeed_video *video =
+ devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
+
+@@ -1677,10 +1730,7 @@ static int aspeed_video_probe(struct platform_device *pdev)
+ INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
+ INIT_LIST_HEAD(&video->buffers);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+- video->base = devm_ioremap_resource(video->dev, res);
+-
++ video->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(video->base))
+ return PTR_ERR(video->base);
+
+@@ -1689,8 +1739,12 @@ static int aspeed_video_probe(struct platform_device *pdev)
+ return rc;
+
+ rc = aspeed_video_setup_video(video);
+- if (rc)
++ if (rc) {
++ of_reserved_mem_device_release(video->dev);
++ clk_unprepare(video->vclk);
++ clk_unprepare(video->eclk);
+ return rc;
++ }
+
+ return 0;
+ }
+@@ -1714,8 +1768,11 @@ static int aspeed_video_remove(struct platform_device *pdev)
+
+ v4l2_device_unregister(v4l2_dev);
+
+- dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt,
+- video->jpeg.dma);
++ aspeed_video_free_buf(video, &video->comp);
++ aspeed_video_free_buf(video, &video->bcd);
++ aspeed_video_free_buf(video, &video->jpeg_hdr);
++ aspeed_video_free_buf(video, &video->srcs[0]);
++ aspeed_video_free_buf(video, &video->srcs[1]);
+
+ of_reserved_mem_device_release(dev);
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0121-Add-a-WA-to-defer-flash-writes-on-PS_ALERT_N-asserti.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0121-Add-a-WA-to-defer-flash-writes-on-PS_ALERT_N-asserti.patch
new file mode 100644
index 000000000..0c9bae00d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0121-Add-a-WA-to-defer-flash-writes-on-PS_ALERT_N-asserti.patch
@@ -0,0 +1,191 @@
+From 90035d4ef6ffb7893f629fa427db77c79e1e50e7 Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Sat, 24 Oct 2020 13:43:23 -0700
+Subject: [PATCH] Add a WA to defer flash writes on PS_ALERT_N assertion
+
+To prevent SPI flash corruption, this commit adds a WA which monitors
+PS_ALERT_N signal for detecting AC loss and it defers flash writes
+when the signal is asserted. Actually, the PS_ALERT_N is asserted
+even when PSU is in an unhealthy state so it also adds 10 seconds
+of timeout for the deferring that covers AC loss case effectively.
+If PSU gets back to healthy state, flash writes will be continued
+immediately.
+
+Note: This would be a customization for some specific platforms
+and this is a WA to cover a defect of H/W design. Do not try
+upstream it.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ .../arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 7 ++-
+ .../arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 4 ++
+ drivers/mtd/spi-nor/aspeed-smc.c | 61 +++++++++++++++++++
+ 3 files changed, 71 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts
+index e4ac4e3696f5..74fd5c52d7e3 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts
+@@ -3,6 +3,7 @@
+ #include "aspeed-g5.dtsi"
+ #include <dt-bindings/gpio/aspeed-gpio.h>
+ #include <dt-bindings/i2c/i2c.h>
++#include <dt-bindings/interrupt-controller/irq.h>
+
+ / {
+ model = "Intel AST2500 BMC";
+@@ -92,6 +93,10 @@
+ };
+
+ &fmc {
++ /delete-property/ interrupts;
++ interrupts-extended = <&vic 19>,
++ <&gpio ASPEED_GPIO(AA, 1) IRQ_TYPE_EDGE_BOTH>;
++ ps-alert-gpio = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ flash@0 {
+ status = "okay";
+@@ -185,7 +190,7 @@
+ /*X0-X7*/ "","","","","","","","",
+ /*Y0-Y7*/ "SIO_S3","SIO_S5","","SIO_ONCONTROL","","","","",
+ /*Z0-Z7*/ "","SIO_POWER_GOOD","","","","","","",
+- /*AA0-AA7*/ "P3VBAT_BRIDGE_EN","","","","PREQ_N","TCK_MUX_SEL","SMI","POST_COMPLETE",
++ /*AA0-AA7*/ "P3VBAT_BRIDGE_EN","IRQ_SML1_PMBUS_BMC_ALERT_N","","","PREQ_N","TCK_MUX_SEL","SMI","POST_COMPLETE",
+ /*AB0-AB7*/ "","NMI_BUTTON","ID_BUTTON","PS_PWROK","","","","",
+ /*AC0-AC7*/ "","","","","","","","";
+ };
+diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
+index e9cea7b63836..0ff929a68dd4 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts
+@@ -85,6 +85,10 @@
+ };
+
+ &fmc {
++ /delete-property/ interrupts;
++ interrupts-extended = <&gic GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
++ <&gpio0 ASPEED_GPIO(Y, 3) IRQ_TYPE_EDGE_BOTH>;
++ ps-alert-gpio = <&gpio0 ASPEED_GPIO(Y, 3) GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ flash@0 {
+ status = "okay";
+diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c
+index 6e2f3802d162..397c2998e620 100644
+--- a/drivers/mtd/spi-nor/aspeed-smc.c
++++ b/drivers/mtd/spi-nor/aspeed-smc.c
+@@ -9,12 +9,14 @@
+ #include <linux/clk.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
++#include <linux/gpio.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/spi-nor.h>
+ #include <linux/of.h>
++#include <linux/of_gpio.h>
+ #include <linux/of_platform.h>
+ #include <linux/sizes.h>
+ #include <linux/slab.h>
+@@ -216,10 +218,16 @@ struct aspeed_smc_controller {
+ u32 ahb_window_size; /* full mapping window size */
+
+ unsigned long clk_frequency;
++ unsigned int ps_alert_gpio;
+
+ struct aspeed_smc_chip *chips[0]; /* pointers to attached chips */
+ };
+
++static unsigned long aspeed_smc_flags = 0;
++#define FLAG_DEFER_WRITE 0
++#define WRITE_DEFER_MSEC 100 /* 100ms */
++#define WRITE_DEFER_MAX_COUNT 100 /* 100 x 100 = 10secs */
++
+ #define ASPEED_SPI_DEFAULT_FREQ 50000000
+
+ /*
+@@ -411,6 +419,17 @@ static int aspeed_smc_write_to_ahb(void __iomem *dst, const void *buf,
+ size_t len)
+ {
+ size_t offset = 0;
++ int defer_cnt = 0;
++
++ while (test_bit(FLAG_DEFER_WRITE, &aspeed_smc_flags)) {
++ pr_warn("%s deferring write, count: %d\n", DEVICE_NAME,
++ defer_cnt);
++ msleep(WRITE_DEFER_MSEC);
++ if (defer_cnt++ > WRITE_DEFER_MAX_COUNT) {
++ clear_bit(FLAG_DEFER_WRITE, &aspeed_smc_flags);
++ break;
++ }
++ }
+
+ if (IS_ALIGNED((uintptr_t)dst, sizeof(uintptr_t)) &&
+ IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) {
+@@ -1363,6 +1382,21 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
+ return ret;
+ }
+
++static irqreturn_t aspeed_smc_ps_alert_irq(int irq, void *arg)
++{
++ struct aspeed_smc_controller *controller = arg;
++
++ if (gpio_get_value(controller->ps_alert_gpio)) {
++ clear_bit(FLAG_DEFER_WRITE, &aspeed_smc_flags);
++ dev_warn(controller->dev, "clear FLAG_DEFER_WRITE\n");
++ } else {
++ set_bit(FLAG_DEFER_WRITE, &aspeed_smc_flags);
++ dev_warn(controller->dev, "set FLAG_DEFER_WRITE\n");
++ }
++
++ return IRQ_HANDLED;
++}
++
+ static int aspeed_smc_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+@@ -1373,6 +1407,7 @@ static int aspeed_smc_probe(struct platform_device *pdev)
+ struct clk *clk;
+ struct resource *res;
+ int ret;
++ int irq;
+
+ match = of_match_device(aspeed_smc_matches, &pdev->dev);
+ if (!match || !match->data)
+@@ -1409,6 +1444,32 @@ static int aspeed_smc_probe(struct platform_device *pdev)
+ controller->clk_frequency = clk_get_rate(clk);
+ devm_clk_put(&pdev->dev, clk);
+
++ controller->ps_alert_gpio = of_get_named_gpio(np, "ps-alert-gpio", 0);
++ if (!gpio_is_valid(controller->ps_alert_gpio)) {
++ dev_err(dev, "No valid ps-alert-gpio\n");
++ ret = controller->ps_alert_gpio;
++ return ret;
++ }
++
++ ret = devm_gpio_request_one(dev, controller->ps_alert_gpio,
++ GPIOF_DIR_IN, "ps-alert-gpio");
++ if (ret) {
++ dev_err(dev, "request gpio failed %d\n", ret);
++ return ret;
++ }
++
++ irq = platform_get_irq(pdev, 1);
++ if (irq < 0)
++ return irq;
++
++ ret = devm_request_irq(&pdev->dev, irq, aspeed_smc_ps_alert_irq,
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ "ps-alert-irq", controller);
++ if (ret) {
++ dev_err(dev, "request irq failed %d\n", ret);
++ return ret;
++ }
++
+ ret = aspeed_smc_setup_flash(controller, np, res);
+ if (ret)
+ dev_err(dev, "Aspeed SMC probe failed %d\n", ret);
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0123-peci-fix-error-handling-in-peci_dev_ioctl.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0123-peci-fix-error-handling-in-peci_dev_ioctl.patch
new file mode 100644
index 000000000..f82a08a1f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0123-peci-fix-error-handling-in-peci_dev_ioctl.patch
@@ -0,0 +1,43 @@
+From f0a37caf96a1583ed190abd7837f124dfadd5743 Mon Sep 17 00:00:00 2001
+From: Zev Weiss <zev@bewilderbeest.net>
+Date: Sun, 27 Sep 2020 07:27:33 +1000
+Subject: [PATCH] peci: fix error-handling in peci_dev_ioctl()
+
+peci_get_xfer_msg() returns NULL on failure, not an ERR_PTR. Also
+avoid calling kfree() on an ERR_PTR.
+
+Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
+Reviewed-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
+---
+ drivers/peci/peci-dev.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/peci/peci-dev.c b/drivers/peci/peci-dev.c
+index c574d13213af..8104468864bf 100644
+--- a/drivers/peci/peci-dev.c
++++ b/drivers/peci/peci-dev.c
+@@ -122,8 +122,8 @@ static long peci_dev_ioctl(struct file *file, uint iocmd, ulong arg)
+ }
+
+ xmsg = peci_get_xfer_msg(uxmsg.tx_len, uxmsg.rx_len);
+- if (IS_ERR(xmsg)) {
+- ret = PTR_ERR(xmsg);
++ if (!xmsg) {
++ ret = -ENOMEM;
+ break;
+ }
+
+@@ -172,7 +172,8 @@ static long peci_dev_ioctl(struct file *file, uint iocmd, ulong arg)
+ }
+
+ peci_put_xfer_msg(xmsg);
+- kfree(msg);
++ if (!IS_ERR(msg))
++ kfree(msg);
+
+ return (long)ret;
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/1001-Igore-0x3FF-in-aspeed_adc-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/1001-Igore-0x3FF-in-aspeed_adc-driver.patch
new file mode 100644
index 000000000..5f74d6993
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/1001-Igore-0x3FF-in-aspeed_adc-driver.patch
@@ -0,0 +1,75 @@
+From d1fb9431676f37ddf2a8673f84368793e5a88ab0 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Mon, 14 Sep 2020 12:02:03 -0700
+Subject: [PATCH] Igore 0x3FF in aspeed_adc driver
+
+ADC are 10 bits, 0x3FF means voltage exceeded reference voltage
+Several ADC voltages reported rare transient events corresponding
+to this value. Aspeed was consulted and did not identify possible
+root causes. As a work around, igore these valuse and return
+previous readings. If there were real issues, a slightly different
+reading like 0x3FE will still be returned and resulted in a sensor
+event.
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ drivers/iio/adc/aspeed_adc.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
+index 1dd5a97a16bc..c115797c4cc5 100644
+--- a/drivers/iio/adc/aspeed_adc.c
++++ b/drivers/iio/adc/aspeed_adc.c
+@@ -53,6 +53,9 @@
+ #define ASPEED_ADC_INIT_POLLING_TIME 500
+ #define ASPEED_ADC_INIT_TIMEOUT 500000
+
++#define ASPEED_ADC_CHANNELS_MAX 16
++#define ASPEED_ADC_RAW_VALUE_MAX 0x3ff
++
+ struct aspeed_adc_model_data {
+ const char *model_name;
+ unsigned int min_sampling_rate; // Hz
+@@ -71,6 +74,7 @@ struct aspeed_adc_data {
+ struct clk_hw *clk_scaler;
+ struct reset_control *rst;
+ int cv;
++ int channel_raw_value[ASPEED_ADC_CHANNELS_MAX];
+ };
+
+ #define ASPEED_CHAN(_idx, _data_reg_addr) { \
+@@ -124,6 +128,13 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ *val = readw(data->base + chan->address);
++ if (*val == ASPEED_ADC_RAW_VALUE_MAX) {
++ *val = data->channel_raw_value[chan->channel];
++ pr_err("aspeed_adc: channel %d drop invalid raw reading 0x3FF %d\n",
++ chan->channel, ASPEED_ADC_RAW_VALUE_MAX);
++ } else {
++ data->channel_raw_value[chan->channel] = *val;
++ }
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+@@ -206,6 +217,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
+ int ret;
+ u32 eng_ctrl = 0;
+ u32 adc_engine_control_reg_val;
++ int i;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
+ if (!indio_dev)
+@@ -298,6 +310,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
+
+ data->cv = 0x200 - (readl(data->base + 0x10) & GENMASK(9, 0));
+
++ for (i = 0; i < ASPEED_ADC_CHANNELS_MAX; i++)
++ data->channel_raw_value[i] = ASPEED_ADC_RAW_VALUE_MAX;
++
+ writel(eng_ctrl | ASPEED_OPERATION_MODE_NORMAL |
+ ASPEED_ENGINE_ENABLE | ASPEED_AUTOPENSATING, data->base + ASPEED_REG_ENGINE_CONTROL);
+ printk(KERN_INFO "aspeed_adc: cv %d \n", data->cv);
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
index 271b6035e..908dc0a8d 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
@@ -90,6 +90,10 @@ SRC_URI += " \
file://0117-Copy-raw-PECI-response-to-user-space-on-timeout.patch \
file://0118-Recalculate-AW-FCS-on-WrEndPointConfig-command.patch \
file://0119-Handle-pending-eSPI-HOST-OOB-RESET-VW-events.patch \
+ file://0123-peci-fix-error-handling-in-peci_dev_ioctl.patch \
+ file://1001-Igore-0x3FF-in-aspeed_adc-driver.patch \
+ file://0120-media-aspeed-adjust-irq-enabling-timing-and-resource.patch \
+ file://0121-Add-a-WA-to-defer-flash-writes-on-PS_ALERT_N-asserti.patch \
"
# CVE-2020-16166 vulnerability fix
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0001-Eliminate-swampd-core-dump-after-D-Bus-updates-senso.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0001-Eliminate-swampd-core-dump-after-D-Bus-updates-senso.patch
new file mode 100644
index 000000000..d2a8d7c40
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0001-Eliminate-swampd-core-dump-after-D-Bus-updates-senso.patch
@@ -0,0 +1,172 @@
+From 26db33e341f7e96931905aee4358353b0c6aee39 Mon Sep 17 00:00:00 2001
+From: Johnathan Mantey <johnathanx.mantey@intel.com>
+Date: Mon, 28 Sep 2020 11:06:58 -0700
+Subject: [PATCH] Eliminate swampd core dump after D-Bus updates sensors
+
+The swamp daemon intializes a list of sensors and uses those to
+periodically scan the state associated devices. Reading the sensors is
+done with an async timer, that runs code to re-arm an async timer.
+
+There is also a D-Bus update cycle that is independent of the async
+timer reading the sensors. When the D-Bus updates the number of
+sensors in the system a new list must be created. In order to create
+the new list the timers using the old list must be stopped. Only after
+those timers have stopped may a new list be generated, and a new set of
+timers started.
+
+The two processes are unware of each other. To safely perform the
+change the pointers to the list of zones and timers must be kept alive
+until all timer actions complete. Only after all references to the
+pointers have been release may the new state be built, and new timers
+started.
+
+Prior to this change swampd would throw a SYSSEGV fault due to an
+attempt to use a pointer that was no longer active.
+
+Tested:
+Issued a "reset -w" (Warm Reset command) from the EFI shell.
+Waited for the system to reboot, and enter EFI
+Checked for a core file in /var/lib/systemd/coredump
+Repeated step 1 if coredump file was not present.
+Completed 2900+ passes successfully when ealier code failed at less
+than 800 passes.
+
+Change-Id: I10ab824d8050be9eca63c18d7e5a62bdb41e9c64
+Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
+---
+ main.cpp | 14 ++++++++++----
+ pid/builder.cpp | 6 +++---
+ pid/builder.hpp | 2 +-
+ pid/pidloop.cpp | 13 +++++++------
+ pid/pidloop.hpp | 3 ++-
+ 5 files changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/main.cpp b/main.cpp
+index 2ab3fc4..46cb38d 100644
+--- a/main.cpp
++++ b/main.cpp
+@@ -72,10 +72,15 @@ static sdbusplus::asio::connection
+ void restartControlLoops()
+ {
+ static SensorManager mgmr;
+- static std::unordered_map<int64_t, std::unique_ptr<PIDZone>> zones;
+- static std::list<boost::asio::steady_timer> timers;
++ static std::unordered_map<int64_t, std::shared_ptr<PIDZone>> zones;
++ static std::vector<std::shared_ptr<boost::asio::steady_timer>> timers;
+
++ for (const auto timer : timers)
++ {
++ timer->cancel();
++ }
+ timers.clear();
++ zones.clear();
+
+ #if CONFIGURE_DBUS
+
+@@ -117,9 +122,10 @@ void restartControlLoops()
+
+ for (const auto& i : zones)
+ {
+- auto& timer = timers.emplace_back(io);
++ std::shared_ptr<boost::asio::steady_timer> timer = timers.emplace_back(
++ std::make_shared<boost::asio::steady_timer>(io));
+ std::cerr << "pushing zone " << i.first << "\n";
+- pidControlLoop(i.second.get(), timer);
++ pidControlLoop(i.second, timer);
+ }
+ }
+
+diff --git a/pid/builder.cpp b/pid/builder.cpp
+index 1fbfbd4..15fc4cd 100644
+--- a/pid/builder.cpp
++++ b/pid/builder.cpp
+@@ -35,12 +35,12 @@ static std::string getControlPath(int64_t zone)
+ return std::string(objectPath) + std::to_string(zone);
+ }
+
+-std::unordered_map<int64_t, std::unique_ptr<PIDZone>>
++std::unordered_map<int64_t, std::shared_ptr<PIDZone>>
+ buildZones(std::map<int64_t, conf::PIDConf>& zonePids,
+ std::map<int64_t, struct conf::ZoneConfig>& zoneConfigs,
+ SensorManager& mgr, sdbusplus::bus::bus& modeControlBus)
+ {
+- std::unordered_map<int64_t, std::unique_ptr<PIDZone>> zones;
++ std::unordered_map<int64_t, std::shared_ptr<PIDZone>> zones;
+
+ for (const auto& zi : zonePids)
+ {
+@@ -62,7 +62,7 @@ std::unordered_map<int64_t, std::unique_ptr<PIDZone>>
+
+ const conf::PIDConf& pidConfig = zi.second;
+
+- auto zone = std::make_unique<PIDZone>(
++ auto zone = std::make_shared<PIDZone>(
+ zoneId, zoneConf->second.minThermalOutput,
+ zoneConf->second.failsafePercent, mgr, modeControlBus,
+ getControlPath(zi.first).c_str(), deferSignals);
+diff --git a/pid/builder.hpp b/pid/builder.hpp
+index e500503..e3ba88c 100644
+--- a/pid/builder.hpp
++++ b/pid/builder.hpp
+@@ -7,7 +7,7 @@
+ #include <sdbusplus/bus.hpp>
+ #include <unordered_map>
+
+-std::unordered_map<int64_t, std::unique_ptr<PIDZone>>
++std::unordered_map<int64_t, std::shared_ptr<PIDZone>>
+ buildZones(std::map<int64_t, conf::PIDConf>& zonePids,
+ std::map<int64_t, struct conf::ZoneConfig>& zoneConfigs,
+ SensorManager& mgr, sdbusplus::bus::bus& modeControlBus);
+diff --git a/pid/pidloop.cpp b/pid/pidloop.cpp
+index 56bf8bd..14225ec 100644
+--- a/pid/pidloop.cpp
++++ b/pid/pidloop.cpp
+@@ -27,7 +27,7 @@
+ #include <thread>
+ #include <vector>
+
+-static void processThermals(PIDZone* zone)
++static void processThermals(std::shared_ptr<PIDZone> zone)
+ {
+ // Get the latest margins.
+ zone->updateSensors();
+@@ -40,8 +40,9 @@ static void processThermals(PIDZone* zone)
+ zone->determineMaxSetPointRequest();
+ }
+
+-void pidControlLoop(PIDZone* zone, boost::asio::steady_timer& timer, bool first,
+- int ms100cnt)
++void pidControlLoop(std::shared_ptr<PIDZone> zone,
++ std::shared_ptr<boost::asio::steady_timer> timer,
++ bool first, int ms100cnt)
+ {
+ if (first)
+ {
+@@ -54,9 +55,9 @@ void pidControlLoop(PIDZone* zone, boost::asio::steady_timer& timer, bool first,
+ processThermals(zone);
+ }
+
+- timer.expires_after(std::chrono::milliseconds(100));
+- timer.async_wait(
+- [zone, &timer, ms100cnt](const boost::system::error_code& ec) mutable {
++ timer->expires_after(std::chrono::milliseconds(100));
++ timer->async_wait(
++ [zone, timer, ms100cnt](const boost::system::error_code& ec) mutable {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ return; // timer being canceled, stop loop
+diff --git a/pid/pidloop.hpp b/pid/pidloop.hpp
+index 3a67954..7aef73a 100644
+--- a/pid/pidloop.hpp
++++ b/pid/pidloop.hpp
+@@ -14,5 +14,6 @@
+ * @param[in] first - boolean to denote if initialization needs to be run.
+ * @param[in] ms100cnt - loop timer counter.
+ */
+-void pidControlLoop(PIDZone* zone, boost::asio::steady_timer& timer,
++void pidControlLoop(std::shared_ptr<PIDZone> zone,
++ std::shared_ptr<boost::asio::steady_timer> timer,
+ bool first = true, int ms100cnt = 0);
+--
+2.26.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0002-Prevent-run-away-memory-consumption-from-swamped.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0002-Prevent-run-away-memory-consumption-from-swamped.patch
new file mode 100644
index 000000000..03ed37e6a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control/0002-Prevent-run-away-memory-consumption-from-swamped.patch
@@ -0,0 +1,270 @@
+From 76b39bb8e638114fdc448334926fe82003fc9598 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Wed, 21 Oct 2020 11:02:50 -0700
+Subject: [PATCH] Prevent run away memory consumption from swamped
+
+These set of changes mitigates swampd memory leak.
+Root cause of memory leak has not been identified.
+Changes include:
+1. Do not rebuild pid control loop for voltage sensor changes
+2. Use default system dbus for helper function temp dbus connection
+3. Only rebuild pid control loop when reload timer is not active
+4. Explicit clear sensor map in static sensor manager struct before
+rebuildng pid control loop.
+5. Add abort flag in pid loop.
+6. Increase event handler timeout time from 2 seconds to 8 seconds.
+
+Tested:
+Build and run 1000 dc cycle, reset and stop/start psusensor service.
+Swampd memory comsumption was stable after some increase.
+Statm for swampd:
+iteration 1: 1922 1326 1098 101 0 238 0
+iteration 1000: 2056 1506 1139 101 0 372 0
+Maximum statm for swampd: 2126 1546 1139 101 0 442 0
+
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ dbus/dbusconfiguration.cpp | 36 ++++++++++++++++++++++++++++--------
+ dbus/dbuspassive.cpp | 2 +-
+ dbus/dbuswrite.cpp | 8 ++++----
+ main.cpp | 7 ++++++-
+ pid/pidloop.cpp | 15 +++++++++++++++
+ pid/zone.hpp | 2 ++
+ sensors/manager.hpp | 6 ++++++
+ 7 files changed, 62 insertions(+), 14 deletions(-)
+
+diff --git a/dbus/dbusconfiguration.cpp b/dbus/dbusconfiguration.cpp
+index bfa2a7c..82e1da0 100644
+--- a/dbus/dbusconfiguration.cpp
++++ b/dbus/dbusconfiguration.cpp
+@@ -18,6 +18,7 @@
+ #include "util.hpp"
+
+ #include <algorithm>
++#include <boost/algorithm/string/predicate.hpp>
+ #include <boost/asio/steady_timer.hpp>
+ #include <chrono>
+ #include <functional>
+@@ -270,6 +271,11 @@ int eventHandler(sd_bus_message* m, void* context, sd_bus_error*)
+ }
+ }
+ }
++
++ if (path.str.find("/xyz/openbmc_project/sensors/voltage") == 0)
++ {
++ return 1;
++ }
+ }
+
+ boost::asio::steady_timer* timer =
+@@ -277,16 +283,27 @@ int eventHandler(sd_bus_message* m, void* context, sd_bus_error*)
+
+ // do a brief sleep as we tend to get a bunch of these events at
+ // once
+- timer->expires_after(std::chrono::seconds(2));
++ static int timercnt = 0;
++ ++timercnt;
++ timer->expires_after(std::chrono::seconds(8));
+ timer->async_wait([](const boost::system::error_code ec) {
+- if (ec == boost::asio::error::operation_aborted)
++ --timercnt;
++ if (ec)
+ {
+- /* another timer started*/
++ if (ec != boost::asio::error::operation_aborted)
++ {
++ // ec == boost::asio::error::operation_aborted means
++ // another timer started, which is normal
++ std::cerr << "Reload timer async handler error - timerCnt "
++ << timercnt << "\n";
++ }
+ return;
+ }
+-
+- std::cout << "New configuration detected, reloading\n.";
+- tryRestartControlLoops();
++ if (timercnt <= 0)
++ {
++ std::cout << "New configuration detected, reloading\n.";
++ tryRestartControlLoops();
++ }
+ });
+
+ return 1;
+@@ -433,7 +450,6 @@ void populatePidInfo(
+
+ bool init(sdbusplus::bus::bus& bus, boost::asio::steady_timer& timer)
+ {
+-
+ sensorConfig.clear();
+ zoneConfig.clear();
+ zoneDetailsConfig.clear();
+@@ -486,6 +502,11 @@ bool init(sdbusplus::bus::bus& bus, boost::asio::steady_timer& timer)
+ {
+ for (const auto& ownerPair : objectPair.second)
+ {
++ if (boost::ends_with(ownerPair.first, "ADCSensor"))
++ {
++ continue;
++ }
++
+ auto& owner = owners[ownerPair.first];
+ for (const std::string& interface : ownerPair.second)
+ {
+@@ -629,7 +650,6 @@ bool init(sdbusplus::bus::bus& bus, boost::asio::steady_timer& timer)
+ auto findBase = configuration.second.find(pidConfigurationInterface);
+ if (findBase != configuration.second.end())
+ {
+-
+ const auto& base =
+ configuration.second.at(pidConfigurationInterface);
+ const std::vector<std::string>& zones =
+diff --git a/dbus/dbuspassive.cpp b/dbus/dbuspassive.cpp
+index 02d1beb..4c6e405 100644
+--- a/dbus/dbuspassive.cpp
++++ b/dbus/dbuspassive.cpp
+@@ -41,7 +41,7 @@ std::unique_ptr<ReadInterface> DbusPassive::createDbusPassive(
+ }
+
+ /* Need to get the scale and initial value */
+- auto tempBus = sdbusplus::bus::new_system();
++ auto tempBus = sdbusplus::bus::new_default_system();
+
+ /* service == busname */
+ std::string path = getSensorPath(type, id);
+diff --git a/dbus/dbuswrite.cpp b/dbus/dbuswrite.cpp
+index 76f4ada..583a065 100644
+--- a/dbus/dbuswrite.cpp
++++ b/dbus/dbuswrite.cpp
+@@ -31,7 +31,7 @@ std::unique_ptr<WriteInterface>
+ DbusWritePercent::createDbusWrite(const std::string& path, int64_t min,
+ int64_t max, DbusHelperInterface& helper)
+ {
+- auto tempBus = sdbusplus::bus::new_system();
++ auto tempBus = sdbusplus::bus::new_default_system();
+ std::string connectionName;
+
+ try
+@@ -59,7 +59,7 @@ void DbusWritePercent::write(double value)
+ {
+ return;
+ }
+- auto writeBus = sdbusplus::bus::new_default();
++ auto writeBus = sdbusplus::bus::new_default_system();
+ auto mesg =
+ writeBus.new_method_call(connectionName.c_str(), path.c_str(),
+ "org.freedesktop.DBus.Properties", "Set");
+@@ -85,7 +85,7 @@ std::unique_ptr<WriteInterface>
+ DbusWrite::createDbusWrite(const std::string& path, int64_t min,
+ int64_t max, DbusHelperInterface& helper)
+ {
+- auto tempBus = sdbusplus::bus::new_system();
++ auto tempBus = sdbusplus::bus::new_default_system();
+ std::string connectionName;
+
+ try
+@@ -106,7 +106,7 @@ void DbusWrite::write(double value)
+ {
+ return;
+ }
+- auto writeBus = sdbusplus::bus::new_default();
++ auto writeBus = sdbusplus::bus::new_default_system();
+ auto mesg =
+ writeBus.new_method_call(connectionName.c_str(), path.c_str(),
+ "org.freedesktop.DBus.Properties", "Set");
+diff --git a/main.cpp b/main.cpp
+index 46cb38d..a07ca80 100644
+--- a/main.cpp
++++ b/main.cpp
+@@ -79,11 +79,15 @@ void restartControlLoops()
+ {
+ timer->cancel();
+ }
++ for (const auto zone : zones)
++ {
++ zone.second->abort = true;
++ }
+ timers.clear();
+ zones.clear();
++ mgmr.clearSensor();
+
+ #if CONFIGURE_DBUS
+-
+ static boost::asio::steady_timer reloadTimer(io);
+ if (!dbus_configuration::init(modeControlBus, reloadTimer))
+ {
+@@ -190,5 +194,6 @@ int main(int argc, char* argv[])
+ tryRestartControlLoops();
+
+ io.run();
++
+ return 0;
+ }
+diff --git a/pid/pidloop.cpp b/pid/pidloop.cpp
+index 14225ec..62bf323 100644
+--- a/pid/pidloop.cpp
++++ b/pid/pidloop.cpp
+@@ -22,6 +22,7 @@
+
+ #include <boost/asio/steady_timer.hpp>
+ #include <chrono>
++#include <iostream>
+ #include <map>
+ #include <memory>
+ #include <thread>
+@@ -60,8 +61,22 @@ void pidControlLoop(std::shared_ptr<PIDZone> zone,
+ [zone, timer, ms100cnt](const boost::system::error_code& ec) mutable {
+ if (ec == boost::asio::error::operation_aborted)
+ {
++ std::cerr << "pid loop timer cancelled " << zone << "\n";
+ return; // timer being canceled, stop loop
+ }
++ if (ec)
++ {
++ std::cerr << "pid loop timer err " << zone << "\n";
++ return;
++ }
++
++ if (zone->abort)
++ {
++ // on our way to destruct and construct new zone and timer
++ // stop the loop
++ std::cerr << "pid loop abort zone " << zone << "\n";
++ return;
++ }
+
+ /*
+ * This should sleep on the conditional wait for the listen thread
+diff --git a/pid/zone.hpp b/pid/zone.hpp
+index 3cf4e59..899636c 100644
+--- a/pid/zone.hpp
++++ b/pid/zone.hpp
+@@ -97,6 +97,8 @@ class PIDZone : public ZoneInterface, public ModeObject
+ /* Method for reading whether in fail-safe mode over dbus */
+ bool failSafe() const override;
+
++ bool abort = false;
++
+ private:
+ std::ofstream _log;
+
+diff --git a/sensors/manager.hpp b/sensors/manager.hpp
+index 411b302..5c7e69a 100644
+--- a/sensors/manager.hpp
++++ b/sensors/manager.hpp
+@@ -51,6 +51,12 @@ class SensorManager
+ return *_hostSensorBus;
+ }
+
++ void clearSensor(void)
++ {
++ _sensorMap.clear();
++ _sensorTypeList.clear();
++ }
++
+ private:
+ std::map<std::string, std::unique_ptr<Sensor>> _sensorMap;
+ std::map<std::string, std::vector<std::string>> _sensorTypeList;
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
index 2e4e23d40..7d717a01d 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/fans/phosphor-pid-control_%.bbappend
@@ -8,3 +8,7 @@ SRC_URI = "git://github.com/openbmc/phosphor-pid-control.git"
SRCREV = "6fc301fbc3775730a0e69f215110ec93bd9026f3"
FILES_${PN} = "${bindir}/swampd ${bindir}/setsensor"
+
+SRC_URI += "file://0001-Eliminate-swampd-core-dump-after-D-Bus-updates-senso.patch \
+ file://0002-Prevent-run-away-memory-consumption-from-swamped.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0015-Fix-delete-image-by-ID-and-inhibit-removal-of-bmc_ac.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0015-Fix-delete-image-by-ID-and-inhibit-removal-of-bmc_ac.patch
new file mode 100644
index 000000000..54efbee8c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/flash/phosphor-software-manager/0015-Fix-delete-image-by-ID-and-inhibit-removal-of-bmc_ac.patch
@@ -0,0 +1,153 @@
+From f2dd5e13a0774d8683542798dd96979f9d7a6691 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@intel.com>
+Date: Tue, 29 Sep 2020 13:38:35 -0700
+Subject: [PATCH] Fix delete image by ID and inhibit removal of bmc_active
+
+Delete image by ID was broken because when hitting the delete dbus
+interface, it recalculated the ID from the parent version, which then
+does not match because of the random number addition that was added to
+the ID when the parent interface was created. This saves away the parent
+interface ID and recalls it rather than recalculating it.
+
+Also, there was a logic error in deleting images that would delete the
+active BMC image. This fixes up that error.
+
+Tested: run multiple back-to back updates and see that when the fwupd
+ script calls delete on the seamless images, the interfaces are
+ deleted and that the bmc_active interface is not deleted.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@intel.com>
+---
+ item_updater.cpp | 17 +++++++++++------
+ pfr_image_manager.cpp | 2 +-
+ version.cpp | 2 +-
+ version.hpp | 19 +++++++++++++++----
+ 4 files changed, 28 insertions(+), 12 deletions(-)
+
+diff --git a/item_updater.cpp b/item_updater.cpp
+index db255d6..90970d3 100644
+--- a/item_updater.cpp
++++ b/item_updater.cpp
+@@ -133,7 +133,7 @@ void ItemUpdater::createActivation(sdbusplus::message::message& msg)
+ activationState, associations)));
+
+ auto versionPtr = std::make_unique<VersionClass>(
+- bus, path, version, purpose, filePath,
++ bus, path, versionId, version, purpose, filePath,
+ std::bind(&ItemUpdater::erase, this, std::placeholders::_1));
+ versionPtr->deleteObject =
+ std::make_unique<phosphor::software::manager::Delete>(bus, path,
+@@ -247,7 +247,7 @@ void ItemUpdater::processBMCImage()
+
+ // Create Version instance for this version.
+ auto versionPtr = std::make_unique<VersionClass>(
+- bus, path, version, purpose, "",
++ bus, path, id, version, purpose, "",
+ std::bind(&ItemUpdater::erase, this, std::placeholders::_1));
+ auto isVersionFunctional = versionPtr->isFunctional();
+ if (!isVersionFunctional)
+@@ -322,11 +322,11 @@ void ItemUpdater::erase(std::string entryId)
+ auto it = versions.find(entryId);
+ if (it != versions.end())
+ {
+- if (it->second->isFunctional() && ACTIVE_BMC_MAX_ALLOWED > 1)
++ if (it->second->isFunctional())
+ {
+- log<level::ERR>("Error: Version is currently running on the BMC. "
+- "Unable to remove.",
+- entry("VERSIONID=%s", entryId.c_str()));
++ log<level::INFO>("Error: Version is currently running on the BMC. "
++ "Unable to remove.",
++ entry("VERSIONID=%s", entryId.c_str()));
+ return;
+ }
+ }
+@@ -669,6 +669,11 @@ void ItemUpdater::freeSpace(Activation& caller)
+ std::size_t count = 0;
+ for (const auto& iter : activations)
+ {
++ if (versions.find(iter.second->versionId)->second->isFunctional())
++ {
++ // don't bother with function versions
++ continue;
++ }
+ if ((iter.second.get()->activation() ==
+ server::Activation::Activations::Active) ||
+ (iter.second.get()->activation() ==
+diff --git a/pfr_image_manager.cpp b/pfr_image_manager.cpp
+index 145237e..0c6c3d8 100644
+--- a/pfr_image_manager.cpp
++++ b/pfr_image_manager.cpp
+@@ -308,7 +308,7 @@ int Manager::processImage(const std::string& imgFilePath)
+ std::string objPath = std::string{SOFTWARE_OBJPATH} + '/' + id;
+
+ auto versionPtr = std::make_unique<Version>(
+- bus, objPath, ver, purpose, imageDirPath.string(),
++ bus, objPath, id, ver, purpose, imageDirPath.string(),
+ std::bind(&Manager::erase, this, std::placeholders::_1));
+ versionPtr->deleteObject =
+ std::make_unique<phosphor::software::manager::Delete>(bus, objPath,
+diff --git a/version.cpp b/version.cpp
+index 18f3f4f..e6fd481 100644
+--- a/version.cpp
++++ b/version.cpp
+@@ -182,7 +182,7 @@ void Delete::delete_()
+ {
+ if (parent.eraseCallback)
+ {
+- parent.eraseCallback(parent.getId(parent.version()));
++ parent.eraseCallback(parent.getExtId());
+ }
+ }
+
+diff --git a/version.hpp b/version.hpp
+index 9cf76da..ae70ea8 100644
+--- a/version.hpp
++++ b/version.hpp
+@@ -74,14 +74,15 @@ class Version : public VersionInherit
+ * @param[in] callback - The eraseFunc callback
+ */
+ Version(sdbusplus::bus::bus& bus, const std::string& objPath,
+- const std::string& versionString, VersionPurpose versionPurpose,
+- const std::string& filePath, eraseFunc callback) :
++ const std::string& extId, const std::string& versionString,
++ VersionPurpose versionPurpose, const std::string& filePath,
++ eraseFunc callback) :
+ VersionInherit(bus, (objPath).c_str(), true),
+- eraseCallback(callback), versionStr(versionString)
++ eraseCallback(callback), extId(extId), versionStr(versionString)
+ {
+ // Set properties.
+ purpose(versionPurpose);
+- version(versionString);
++ version(extId);
+ path(filePath);
+ // Emit deferred signal.
+ emit_object_added();
+@@ -134,6 +135,15 @@ class Version : public VersionInherit
+ */
+ bool isFunctional();
+
++ /* @brief Return the extended ID of this version object
++ *
++ * @ return - returns the extended ID string
++ */
++ std::string getExtId()
++ {
++ return extId;
++ }
++
+ /** @brief Persistent Delete D-Bus object */
+ std::unique_ptr<Delete> deleteObject;
+
+@@ -143,6 +153,7 @@ class Version : public VersionInherit
+ private:
+ /** @brief This Version's version string */
+ const std::string versionStr;
++ const std::string extId;
+ };
+
+ } // namespace manager
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Fix-memory-leak.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Fix-memory-leak.patch
new file mode 100644
index 000000000..2c433b623
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Fix-memory-leak.patch
@@ -0,0 +1,124 @@
+From 8bb79ae9384e876b617663a7df4fc8a7a749219e Mon Sep 17 00:00:00 2001
+From: James Feist <james.feist@linux.intel.com>
+Date: Mon, 28 Sep 2020 15:52:59 -0700
+Subject: [PATCH 1/1] Fix memory leak
+
+Downstream only fix to resolve leak. This makes the
+socket lambda capture by weak_ptr so that it no longer
+has ownership.
+
+Tested: Used script that creates leak, no more leak
+
+Signed-off-by: James Feist <james.feist@linux.intel.com>
+---
+ http/http_connection.h | 10 ++++++++--
+ http/http_request.h | 2 +-
+ include/dump_offload.hpp | 9 +++++++--
+ redfish-core/lib/event_service.hpp | 10 +++++++---
+ redfish-core/lib/redfish_sessions.hpp | 12 +++++++-----
+ 5 files changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/http/http_connection.h b/http/http_connection.h
+index 8db8108..4093e95 100644
+--- a/http/http_connection.h
++++ b/http/http_connection.h
+@@ -531,8 +531,14 @@ class Connection :
+
+ if (!isInvalidRequest)
+ {
+- req->socket = [this, self = shared_from_this()]() -> Adaptor& {
+- return self->socket();
++ auto self = this->weak_from_this();
++ req->socket = [self]() -> Adaptor* {
++ auto shared = self.lock();
++ if (shared)
++ {
++ return &(shared->socket());
++ }
++ return nullptr;
+ };
+
+ res.completeRequestHandler = [] {};
+diff --git a/http/http_request.h b/http/http_request.h
+index 95f88c7..3313582 100644
+--- a/http/http_request.h
++++ b/http/http_request.h
+@@ -36,7 +36,7 @@ struct Request
+ std::shared_ptr<crow::persistent_data::UserSession> session;
+
+ std::string userRole{};
+- std::function<Adaptor&()> socket;
++ std::function<Adaptor*()> socket;
+ Request(
+ boost::beast::http::request<boost::beast::http::string_body>& reqIn) :
+ req(reqIn),
+diff --git a/include/dump_offload.hpp b/include/dump_offload.hpp
+index 1777dfe..a01fb32 100644
+--- a/include/dump_offload.hpp
++++ b/include/dump_offload.hpp
+@@ -290,8 +290,13 @@ inline void handleDumpOffloadUrl(const crow::Request& req, crow::Response& res,
+ boost::asio::io_context* io_con = req.ioService;
+
+ handler = std::make_shared<Handler>(media, *io_con, entryId);
+- handler->stream =
+- std::make_shared<crow::Request::Adaptor>(std::move(req.socket()));
++ handler->stream = nullptr;
++ auto socket = req.socket();
++ if (socket)
++ {
++ handler->stream =
++ std::make_shared<crow::Request::Adaptor>(std::move(*socket));
++ }
+ handler->connect();
+ handler->waitForMessageOnSocket();
+ }
+diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
+index 351f689..40758e7 100644
+--- a/redfish-core/lib/event_service.hpp
++++ b/redfish-core/lib/event_service.hpp
+@@ -551,9 +551,13 @@ class EventServiceSSE : public Node
+ }
+ }
+ }
+-
+- std::shared_ptr<crow::Request::Adaptor> sseConn =
+- std::make_shared<crow::Request::Adaptor>(std::move(req.socket()));
++ auto socket = req.socket();
++ std::shared_ptr<crow::Request::Adaptor> sseConn = nullptr;
++ if (socket)
++ {
++ sseConn =
++ std::make_shared<crow::Request::Adaptor>(std::move((*socket)));
++ }
+ std::shared_ptr<Subscription> subValue =
+ std::make_shared<Subscription>(sseConn);
+
+diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
+index 8080e6f..267f98a 100644
+--- a/redfish-core/lib/redfish_sessions.hpp
++++ b/redfish-core/lib/redfish_sessions.hpp
+@@ -227,14 +227,16 @@ class SessionCollection : public Node
+ }
+ }
+ #endif
+-
++ auto socket = req.socket();
++ if (socket)
++ {
+ #ifdef BMCWEB_ENABLE_SSL
+- clientIp =
+- req.socket().next_layer().remote_endpoint().address().to_string();
++ clientIp =
++ (*socket).next_layer().remote_endpoint().address().to_string();
+ #else
+- clientIp = req.socket().remote_endpoint().address().to_string();
++ clientIp = (*socket).remote_endpoint().address().to_string();
+ #endif
+-
++ }
+ // User is authenticated - create session
+ std::shared_ptr<crow::persistent_data::UserSession> session =
+ crow::persistent_data::SessionStore::getInstance()
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Workaround-Fix-memory-leak.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Workaround-Fix-memory-leak.patch
deleted file mode 100644
index 90905762b..000000000
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0009-Workaround-Fix-memory-leak.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From f43d6ba7e32565a7881949070bd25cb13f50ebf7 Mon Sep 17 00:00:00 2001
-From: James Feist <james.feist@linux.intel.com>
-Date: Thu, 27 Aug 2020 13:56:52 -0700
-Subject: [PATCH 1/1] Workaround: Fix memory leak
-
-Req caputures self not allowing the connection to
-be freed. There is discussion in upstream about a
-real fix, this should be kept downstream only.
-
-Tested: Sent 1000 connections, saw no VSZ increase
-
-Change-Id: I63440abbe0882ffe228395b5d3bc869f10048ddc
-Signed-off-by: James Feist <james.feist@linux.intel.com>
----
- http/http_connection.h | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/http/http_connection.h b/http/http_connection.h
-index 109a272..393c2e7 100644
---- a/http/http_connection.h
-+++ b/http/http_connection.h
-@@ -422,6 +422,8 @@ class Connection :
- {
- adaptor.close();
- }
-+ // HACK TO REMOVE MEMORY LEAK
-+ req.reset();
- }
-
- void completeRequest()
---
-2.17.1
-
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0027-EventService-Improvements-and-limitations.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0027-EventService-Improvements-and-limitations.patch
new file mode 100644
index 000000000..23b8a429c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0027-EventService-Improvements-and-limitations.patch
@@ -0,0 +1,265 @@
+From 1a848063c3a90dd0910a33e8d5d01ef6fd48fdd6 Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Fri, 2 Oct 2020 02:03:08 +0530
+Subject: [PATCH] EventService: Improvements and limitations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Below improvements are made for MetricReport event
+format Types:
+ - To reduce load on D-Bus, removed “GetAll” D-Bus
+ method call. Use “PropertiesChanged” Signal
+ instead of “ReportUpdated” signal
+ - Optimize the getDateTime function call
+ - Set the sublimit of 2 for MetricReport subscriptions.
+ - Read ReportTimestamp from signal & fromat it.
+
+Tested:
+ - Stressed EventService along with Telemetry reports and
+ it works fine.
+ - Tried adding more than two MetricReport subscriptions
+ and it returns error as expected.
+ - Report timestamp works.
+
+Change-Id: I58773ea4e25eb0c792c2c43b7450ef52f01996fa
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ http/utility.h | 14 ++-
+ redfish-core/include/event_service_manager.hpp | 116 +++++++++++++------------
+ redfish-core/lib/event_service.hpp | 17 ++++
+ 3 files changed, 83 insertions(+), 64 deletions(-)
+
+diff --git a/http/utility.h b/http/utility.h
+index 8254091..666c13e 100644
+--- a/http/utility.h
++++ b/http/utility.h
+@@ -775,18 +775,16 @@ inline void convertToLinks(std::string& s)
+ */
+ inline std::string getDateTime(const std::time_t& time)
+ {
+- std::array<char, 128> dateTime;
+- std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
++ std::array<char, sizeof("0000-00-00T00:00:00+00:00\0")> dateTime;
+
+- if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
+- std::localtime(&time)))
++ size_t sz = std::strftime(dateTime.begin(), dateTime.size(), "%FT%T+00:00",
++ std::gmtime(&time));
++ if (sz == 0 || sz > dateTime.size())
+ {
+- // insert the colon required by the ISO 8601 standard
+- redfishDateTime = std::string(dateTime.data());
+- redfishDateTime.insert(redfishDateTime.end() - 2, ':');
++ return "";
+ }
+
+- return redfishDateTime;
++ return std::string(dateTime.data(), sz);
+ }
+
+ inline std::string dateTimeNow()
+diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
+index 8397159..b503e2f 100644
+--- a/redfish-core/include/event_service_manager.hpp
++++ b/redfish-core/include/event_service_manager.hpp
+@@ -40,6 +40,7 @@ namespace redfish
+
+ using ReadingsObjType =
+ std::vector<std::tuple<std::string, std::string, double, int32_t>>;
++using ReadingsAndTimestamp = std::tuple<int32_t, ReadingsObjType>;
+ using EventServiceConfig = std::tuple<bool, uint32_t, uint32_t>;
+
+ static constexpr const char* eventFormatType = "Event";
+@@ -1026,6 +1027,11 @@ class EventServiceManager
+ return count;
+ }
+
++ size_t getMetricReportSubscriptionsCount()
++ {
++ return noOfMetricReportSubscribers;
++ }
++
+ std::vector<std::string> getAllIDs()
+ {
+ std::vector<std::string> idList;
+@@ -1294,8 +1300,8 @@ class EventServiceManager
+
+ #endif
+
+- void getMetricReading(const std::string& service,
+- const std::string& objPath, const std::string& intf)
++ void getMetricReading(const std::string& objPath, const int32_t& reportTs,
++ const ReadingsObjType& readings)
+ {
+ std::size_t found = objPath.find_last_of("/");
+ if (found == std::string::npos)
+@@ -1311,55 +1317,22 @@ class EventServiceManager
+ return;
+ }
+
+- crow::connections::systemBus->async_method_call(
+- [idStr{std::move(idStr)}](
+- const boost::system::error_code ec,
+- boost::container::flat_map<
+- std::string, std::variant<int32_t, ReadingsObjType>>&
+- resp) {
+- if (ec)
+- {
+- BMCWEB_LOG_DEBUG
+- << "D-Bus call failed to GetAll metric readings.";
+- return;
+- }
+-
+- const int32_t* timestampPtr =
+- std::get_if<int32_t>(&resp["Timestamp"]);
+- if (!timestampPtr)
+- {
+- BMCWEB_LOG_DEBUG << "Failed to Get timestamp.";
+- return;
+- }
+-
+- ReadingsObjType* readingsPtr =
+- std::get_if<ReadingsObjType>(&resp["Readings"]);
+- if (!readingsPtr)
+- {
+- BMCWEB_LOG_DEBUG << "Failed to Get Readings property.";
+- return;
+- }
+-
+- if (!readingsPtr->size())
+- {
+- BMCWEB_LOG_DEBUG << "No metrics report to be transferred";
+- return;
+- }
++ if (!readings.size())
++ {
++ BMCWEB_LOG_DEBUG << "No metrics in report to be transferred";
++ return;
++ }
+
+- for (const auto& it :
+- EventServiceManager::getInstance().subscriptionsMap)
+- {
+- std::shared_ptr<Subscription> entry = it.second;
+- if (entry->eventFormatType == metricReportFormatType)
+- {
+- entry->filterAndSendReports(
+- idStr, crow::utility::getDateTime(*timestampPtr),
+- *readingsPtr);
+- }
+- }
+- },
+- service, objPath, "org.freedesktop.DBus.Properties", "GetAll",
+- intf);
++ for (const auto& it :
++ EventServiceManager::getInstance().subscriptionsMap)
++ {
++ std::shared_ptr<Subscription> entry = it.second;
++ if (entry->eventFormatType == metricReportFormatType)
++ {
++ entry->filterAndSendReports(
++ idStr, crow::utility::getDateTime(reportTs), readings);
++ }
++ }
+ }
+
+ void unregisterMetricReportSignal()
+@@ -1382,22 +1355,53 @@ class EventServiceManager
+
+ BMCWEB_LOG_DEBUG << "Metrics report signal - Register";
+ std::string matchStr(
+- "type='signal',member='ReportUpdate', "
+- "interface='xyz.openbmc_project.MonitoringService.Report'");
++ "type='signal',member='PropertiesChanged',"
++ "sender='xyz.openbmc_project.MonitoringService',"
++ "interface='org.freedesktop.DBus.Properties',"
++ "path_namespace='/xyz/openbmc_project/MonitoringService/Reports/"
++ "TelemetryService',"
++ "arg0='xyz.openbmc_project.MonitoringService.Report'");
+
+ matchTelemetryMonitor = std::make_shared<sdbusplus::bus::match::match>(
+ *crow::connections::systemBus, matchStr,
+ [this](sdbusplus::message::message& msg) {
+ if (msg.is_method_error())
+ {
+- BMCWEB_LOG_ERROR << "TelemetryMonitor Signal error";
++ BMCWEB_LOG_ERROR << "Received error in monitor signal";
+ return;
+ }
+
+- std::string service = msg.get_sender();
+ std::string objPath = msg.get_path();
+- std::string intf = msg.get_interface();
+- getMetricReading(service, objPath, intf);
++ std::string intf;
++ std::vector<
++ std::pair<std::string, std::variant<ReadingsAndTimestamp>>>
++ msgData;
++ msg.read(intf, msgData);
++
++ if (intf != "xyz.openbmc_project.MonitoringService.Report")
++ {
++ BMCWEB_LOG_ERROR
++ << "Received property from wrong interface";
++ return;
++ }
++
++ const ReadingsAndTimestamp* dataPtr = nullptr;
++ for (const auto& [key, var] : msgData)
++ {
++ if (key == "Readings")
++ {
++ dataPtr = std::get_if<ReadingsAndTimestamp>(&var);
++ break;
++ }
++ }
++ if (!dataPtr)
++ {
++ BMCWEB_LOG_ERROR << "Failed to get readings from signal";
++ return;
++ }
++
++ const auto& [timestamp, readings] = *dataPtr;
++ getMetricReading(objPath, timestamp, readings);
+ });
+ }
+
+diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
+index 40758e7..c3addca 100644
+--- a/redfish-core/lib/event_service.hpp
++++ b/redfish-core/lib/event_service.hpp
+@@ -28,6 +28,7 @@ static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
+
+ static constexpr const uint8_t maxNoOfSubscriptions = 20;
+ static constexpr const uint8_t maxNoOfSSESubscriptions = 10;
++static constexpr const uint8_t maxNoOfMetricReportSubscriptions = 2;
+
+ class EventService : public Node
+ {
+@@ -253,6 +254,22 @@ class EventDestinationCollection : public Node
+ }
+ }
+
++ if (eventFormatType)
++ {
++ if (*eventFormatType == metricReportFormatType)
++ {
++ if (EventServiceManager::getInstance()
++ .getMetricReportSubscriptionsCount() >=
++ maxNoOfMetricReportSubscriptions)
++ {
++ BMCWEB_LOG_ERROR
++ << "Max metric report subscription limit reached";
++ messages::eventSubscriptionLimitExceeded(asyncResp->res);
++ return;
++ }
++ }
++ }
++
+ // Validate the URL using regex expression
+ // Format: <protocol>://<host>:<port>/<uri>
+ // protocol: http/https
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0028-EventService-Schedule-MetricReport-data-format.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0028-EventService-Schedule-MetricReport-data-format.patch
new file mode 100644
index 000000000..7a58c3a98
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0028-EventService-Schedule-MetricReport-data-format.patch
@@ -0,0 +1,58 @@
+From 4b586eba14826f19daf84c17bd6b8170ce7d6337 Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Fri, 2 Oct 2020 16:18:04 +0530
+Subject: [PATCH] EventService: Schedule MetricReport data format
+
+Stress test with telemetric report data, bmcweb
+slows down in responding to redfish requests.
+Scheduling the MtericReport data filtering and
+MetricReport formmating to place back of queue.
+
+Tested:
+ - Improved redfish request data procesing
+
+Change-Id: I3664bbaa3ee2d749310205b574f5d969574cf29a
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ redfish-core/include/event_service_manager.hpp | 25 +++++++++++++++----------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
+index b503e2f..b6b8b5a 100644
+--- a/redfish-core/include/event_service_manager.hpp
++++ b/redfish-core/include/event_service_manager.hpp
+@@ -1323,16 +1323,21 @@ class EventServiceManager
+ return;
+ }
+
+- for (const auto& it :
+- EventServiceManager::getInstance().subscriptionsMap)
+- {
+- std::shared_ptr<Subscription> entry = it.second;
+- if (entry->eventFormatType == metricReportFormatType)
+- {
+- entry->filterAndSendReports(
+- idStr, crow::utility::getDateTime(reportTs), readings);
+- }
+- }
++ boost::asio::post(
++ crow::connections::systemBus->get_io_context(),
++ [this, idStr, reportTs, readings] {
++ for (const auto& it :
++ EventServiceManager::getInstance().subscriptionsMap)
++ {
++ std::shared_ptr<Subscription> entry = it.second;
++ if (entry->eventFormatType == metricReportFormatType)
++ {
++ entry->filterAndSendReports(
++ idStr, crow::utility::getDateTime(reportTs),
++ readings);
++ }
++ }
++ });
+ }
+
+ void unregisterMetricReportSignal()
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0029-Added-Validation-on-MessageId-and-RegistryPrefix.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0029-Added-Validation-on-MessageId-and-RegistryPrefix.patch
new file mode 100644
index 000000000..bee45d957
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0029-Added-Validation-on-MessageId-and-RegistryPrefix.patch
@@ -0,0 +1,166 @@
+From 729f09fd4918fec4615d6cee898fbb7aaebd6751 Mon Sep 17 00:00:00 2001
+From: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
+Date: Sat, 26 Sep 2020 03:45:41 +0530
+Subject: [PATCH] Added Validation on MessageId and RegistryPrefix
+
+Message ID's and Registry prefixes used to subscribe to an event
+will be checked against allowed values.
+Base registry prefix is removed, because there won't be any Redfish
+events logged with Base registry prefix.
+Corrected "Task" registry prefix to "TaskEvent".
+
+Tested:
+ - Validated POST action with different combinations of
+ Message id's and Registry Prefix.
+ - Redfish validator passed.
+
+Change-Id: Ie6dc0268ffaf03606395f9d78f19cfcb6f432120
+Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ redfish-core/include/event_service_manager.hpp | 48 +++++++++++++++++++-------
+ redfish-core/lib/event_service.hpp | 48 +++++++++++++++++++++++---
+ 2 files changed, 80 insertions(+), 16 deletions(-)
+
+diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
+index b6b8b5a..afbf799 100644
+--- a/redfish-core/include/event_service_manager.hpp
++++ b/redfish-core/include/event_service_manager.hpp
+@@ -18,6 +18,7 @@
+ #include "registries.hpp"
+ #include "registries/base_message_registry.hpp"
+ #include "registries/openbmc_message_registry.hpp"
++#include "registries/task_event_message_registry.hpp"
+
+ #include <sys/inotify.h>
+ #include <systemd/sd-journal.h>
+@@ -68,6 +69,40 @@ using EventLogObjectsType =
+
+ namespace message_registries
+ {
++static bool
++ isValidMessageId(const std::string& messageId,
++ const boost::beast::span<const MessageEntry>& registry)
++{
++ boost::beast::span<const MessageEntry>::const_iterator messageIdIt =
++ std::find_if(registry.cbegin(), registry.cend(),
++ [&messageId](const MessageEntry& messageEntry) {
++ return !messageId.compare(messageEntry.first);
++ });
++ if (messageIdIt != registry.cend())
++ {
++ return true;
++ }
++
++ return false;
++}
++
++static const boost::beast::span<const MessageEntry>
++ getRegistryFromPrefix(const std::string& registryName)
++{
++ if (std::string(task_event::header.registryPrefix) == registryName)
++ {
++ return boost::beast::span<const MessageEntry>(task_event::registry);
++ }
++ else if (std::string(openbmc::header.registryPrefix) == registryName)
++ {
++ return boost::beast::span<const MessageEntry>(openbmc::registry);
++ }
++ else if (std::string(base::header.registryPrefix) == registryName)
++ {
++ return boost::beast::span<const MessageEntry>(base::registry);
++ }
++ return boost::beast::span<const MessageEntry>(openbmc::registry);
++}
+ static const Message*
+ getMsgFromRegistry(const std::string& messageKey,
+ const boost::beast::span<const MessageEntry>& registry)
+@@ -101,18 +136,7 @@ static const Message* formatMessage(const std::string_view& messageID)
+ std::string& messageKey = fields[3];
+
+ // Find the right registry and check it for the MessageKey
+- if (std::string(base::header.registryPrefix) == registryName)
+- {
+- return getMsgFromRegistry(
+- messageKey, boost::beast::span<const MessageEntry>(base::registry));
+- }
+- if (std::string(openbmc::header.registryPrefix) == registryName)
+- {
+- return getMsgFromRegistry(
+- messageKey,
+- boost::beast::span<const MessageEntry>(openbmc::registry));
+- }
+- return nullptr;
++ return getMsgFromRegistry(messageKey, getRegistryFromPrefix(registryName));
+ }
+ } // namespace message_registries
+
+diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
+index c3addca..095b76d 100644
+--- a/redfish-core/lib/event_service.hpp
++++ b/redfish-core/lib/event_service.hpp
+@@ -21,8 +21,8 @@ namespace redfish
+
+ static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
+ eventFormatType, metricReportFormatType};
+-static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
+- "Base", "OpenBMC", "Task"};
++static constexpr const std::array<const char*, 2> supportedRegPrefixes = {
++ "OpenBMC", "TaskEvent"};
+ static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
+ "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
+
+@@ -393,8 +393,48 @@ class EventDestinationCollection : public Node
+
+ if (msgIds)
+ {
+- // Do we need to loop-up MessageRegistry and validate
+- // data for authenticity??? Not mandate, i believe.
++ std::vector<std::string> registryPrefix;
++
++ // If no registry prefixes are mentioned, consider all supported
++ // prefixes
++ if (subValue->registryPrefixes.empty())
++ {
++ registryPrefix.assign(supportedRegPrefixes.begin(),
++ supportedRegPrefixes.end());
++ }
++ else
++ {
++ registryPrefix = subValue->registryPrefixes;
++ }
++
++ for (const std::string& id : *msgIds)
++ {
++ bool validId = false;
++
++ // Check for Message ID in each of the selected Registry
++ for (const std::string& it : registryPrefix)
++ {
++ const boost::beast::span<
++ const redfish::message_registries::MessageEntry>&
++ registry =
++ redfish::message_registries::getRegistryFromPrefix(
++ it);
++
++ if (isValidMessageId(id, registry))
++ {
++ validId = true;
++ break;
++ }
++ }
++
++ if (!validId)
++ {
++ messages::propertyValueNotInList(asyncResp->res, id,
++ "MessageIds");
++ return;
++ }
++ }
++
+ subValue->registryMsgIds = *msgIds;
+ }
+
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0030-Initialize-Event-Service-Config-on-bmcweb-restart.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0030-Initialize-Event-Service-Config-on-bmcweb-restart.patch
new file mode 100644
index 000000000..60631bc3c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0030-Initialize-Event-Service-Config-on-bmcweb-restart.patch
@@ -0,0 +1,36 @@
+From 20f61051cc1dc68b5be2419a4ec0fdbfedf3466e Mon Sep 17 00:00:00 2001
+From: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
+Date: Wed, 7 Oct 2020 01:45:28 +0530
+Subject: [PATCH] Initialize Event Service Config on bmcweb restart
+
+Added instantiation of EventServiceManager Object in the
+EventService constructor to initialize Event Service Config
+and register the subscriptions from the config.
+
+Tested:
+ - Subscribed Events were successfully received on restart
+ of bmcweb Service as well as on reboot of bmc
+
+Change-Id: Ie2d446b49e172a057ba53e3d3692c40010fb88ff
+Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
+---
+ redfish-core/lib/event_service.hpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
+index 095b76d..7a29af5 100644
+--- a/redfish-core/lib/event_service.hpp
++++ b/redfish-core/lib/event_service.hpp
+@@ -42,6 +42,9 @@ class EventService : public Node
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
++
++ // Create EventServiceManager instance and initialize Config
++ EventServiceManager::getInstance();
+ }
+
+ private:
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0031-get-on-crashdump-can-follow-redfish-privileges.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0031-get-on-crashdump-can-follow-redfish-privileges.patch
new file mode 100644
index 000000000..0e12915a9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0031-get-on-crashdump-can-follow-redfish-privileges.patch
@@ -0,0 +1,140 @@
+From c2310caa0362eb01988a43a4b6114c52261628e0 Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Thu, 8 Oct 2020 12:33:57 +0530
+Subject: [PATCH] get on crashdump can follow redfish privileges
+
+Get & Head on crashdump uri's are deviated from redfish privilege
+registries(LogService), thinking of security concerns. But it can
+also follow normal 'Login' privilege like other LogService URI's.
+There is not security issue as 'Login' privilege means user is
+already authenticated.
+
+Tested:
+ - Verified get & head on crashdump uri's with login
+ user and it works fine.
+
+Change-Id: Iab913b633aa2daf5ecfa111a631071c095fa29d5
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ redfish-core/lib/log_services.hpp | 48 +++++++++++++--------------------------
+ 1 file changed, 16 insertions(+), 32 deletions(-)
+
+diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
+index 590243c..e6090e5 100644
+--- a/redfish-core/lib/log_services.hpp
++++ b/redfish-core/lib/log_services.hpp
+@@ -2403,11 +2403,9 @@ class CrashdumpService : public Node
+ CrashdumpService(CrowApp& app) :
+ Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+@@ -2463,11 +2461,9 @@ class CrashdumpClear : public Node
+ Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
+ "LogService.ClearLog/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+@@ -2556,11 +2552,9 @@ class CrashdumpEntryCollection : public Node
+ CrashdumpEntryCollection(CrowApp& app) :
+ Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+@@ -2643,11 +2637,9 @@ class CrashdumpEntry : public Node
+ "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/",
+ std::string())
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+@@ -2678,11 +2670,9 @@ class CrashdumpFile : public Node
+ "<str>/",
+ std::string(), std::string())
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+@@ -2780,11 +2770,9 @@ class OnDemandCrashdump : public Node
+ "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/Oem/"
+ "Crashdump.OnDemand/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+@@ -2852,11 +2840,9 @@ class TelemetryCrashdump : public Node
+ "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/Oem/"
+ "Crashdump.Telemetry/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+@@ -2924,11 +2910,9 @@ class SendRawPECI : public Node
+ "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/Oem/"
+ "Crashdump.SendRawPeci/")
+ {
+- // Note: Deviated from redfish privilege registry for GET & HEAD
+- // method for security reasons.
+ entityPrivileges = {
+- {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
+- {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
++ {boost::beast::http::verb::get, {{"Login"}}},
++ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0034-Avoid-using-deleted-Connection-in-Response.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0034-Avoid-using-deleted-Connection-in-Response.patch
new file mode 100644
index 000000000..1d6239527
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0034-Avoid-using-deleted-Connection-in-Response.patch
@@ -0,0 +1,42 @@
+From ab6152177b105625512c524f5c862acde260d72a Mon Sep 17 00:00:00 2001
+From: "Wludzik, Jozef" <jozef.wludzik@intel.com>
+Date: Mon, 19 Oct 2020 13:07:45 +0200
+Subject: [PATCH] Avoid using deleted Connection in Response
+
+Connection is destroyed when completeRequestHandler is nulled. It
+causes that memory is freed. When Response::end() is called and
+connection is not alive, completeRequest() method removes last
+shared_ptr reference by setting nullptr on completeRequestHandler
+member of Response. In this moment code is executed on destroyed
+object and can cause stack overflow.
+Fixed it by moving a call to completeRequest method to Asio
+executor in completeRequestHandler.
+
+Tested:
+ - Ran stress test that send a lot of GET and POST requests
+ without a bmcweb service crash
+
+Change-Id: Idcf6a06dac32e9eac08285b9b53a5e8afe36c955
+Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
+---
+ http/http_connection.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/http/http_connection.h b/http/http_connection.h
+index 4093e95..59a134f 100644
+--- a/http/http_connection.h
++++ b/http/http_connection.h
+@@ -557,7 +557,9 @@ class Connection :
+ {
+ needToCallAfterHandlers = true;
+ res.completeRequestHandler = [self(shared_from_this())] {
+- self->completeRequest();
++ boost::asio::post(self->adaptor.get_executor(), [self] {
++ self->completeRequest();
++ });
+ };
+ if (req->isUpgrade() &&
+ boost::iequals(
+--
+2.16.6
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0035-EventService-Fix-hostname-resolve-issue.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0035-EventService-Fix-hostname-resolve-issue.patch
new file mode 100644
index 000000000..372ff6801
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0035-EventService-Fix-hostname-resolve-issue.patch
@@ -0,0 +1,137 @@
+From c3a63a9ff4103b215d85845b98ba51c039511713 Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Fri, 16 Oct 2020 17:03:36 +0530
+Subject: [PATCH] EventService - Fix hostname resolve issue
+
+The hostname also accepted in EventService
+as destination. When this hostname resolution
+fails, causes the bmcweb crash. So avoid the
+bmcweb crash by catching exception and control
+goes to retry process like any other failure.
+
+Tested:
+ - No bmcweb crash observed when hostname resolve fails.
+ - Created subscription with invalid hostname and
+ verified the retry process.
+ - Created subscriptions with positive cases and all
+ works fine.
+
+Change-Id: I0adf6864911c4cf49a11110519c73556d87f3279
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ http/http_client.hpp | 54 ++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+diff --git a/http/http_client.hpp b/http/http_client.hpp
+index 6d3d702..abccc84 100644
+--- a/http/http_client.hpp
++++ b/http/http_client.hpp
+@@ -36,6 +36,9 @@ static constexpr unsigned int httpReadBodyLimit = 1024;
+ enum class ConnState
+ {
+ initialized,
++ resolveInProgress,
++ resolveFailed,
++ resolved,
+ connectInProgress,
+ connectFailed,
+ sslHandshakeInProgress,
+@@ -52,6 +55,7 @@ enum class ConnState
+ class HttpClient : public std::enable_shared_from_this<HttpClient>
+ {
+ private:
++ boost::asio::ip::tcp::resolver resolver;
+ boost::asio::ssl::context ctx{boost::asio::ssl::context::tlsv12_client};
+ boost::beast::tcp_stream conn;
+ std::optional<boost::beast::ssl_stream<boost::beast::tcp_stream&>> sslConn;
+@@ -76,6 +80,32 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
+ bool runningTimer;
+ ConnState state;
+
++ void doResolve()
++ {
++ BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":" << port;
++ if (state == ConnState::resolveInProgress)
++ {
++ return;
++ }
++ state = ConnState::resolveInProgress;
++ // TODO: Use async_resolver. boost asio example
++ // code as is crashing with async_resolve().
++ try
++ {
++ endpoint = resolver.resolve(host, port);
++ }
++ catch (const std::exception& e)
++ {
++ BMCWEB_LOG_ERROR << "Failed to resolve hostname: " << host << " - "
++ << e.what();
++ state = ConnState::resolveFailed;
++ checkQueue();
++ return;
++ }
++ state = ConnState::resolved;
++ checkQueue();
++ }
++
+ void doConnect()
+ {
+ if (useSsl)
+@@ -348,6 +378,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
+ }
+
+ if ((state == ConnState::connectFailed) ||
++ (state == ConnState::resolveFailed) ||
+ (state == ConnState::sendFailed) ||
+ (state == ConnState::recvFailed))
+ {
+@@ -393,16 +424,21 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
+ {
+ switch (state)
+ {
++ case ConnState::initialized:
++ case ConnState::resolveFailed:
++ case ConnState::connectFailed:
++ doResolve();
++ break;
+ case ConnState::connectInProgress:
++ case ConnState::resolveInProgress:
+ case ConnState::sslHandshakeInProgress:
+ case ConnState::sendInProgress:
+ case ConnState::suspended:
+ case ConnState::terminated:
+ // do nothing
+ break;
+- case ConnState::initialized:
+ case ConnState::closed:
+- case ConnState::connectFailed:
++ case ConnState::resolved:
+ case ConnState::sendFailed:
+ case ConnState::recvFailed:
+ {
+@@ -428,18 +464,12 @@ class HttpClient : public std::enable_shared_from_this<HttpClient>
+ const std::string& destIP, const std::string& destPort,
+ const std::string& destUri,
+ const bool inUseSsl = true) :
+- conn(ioc),
+- timer(ioc), subId(id), host(destIP), port(destPort), uri(destUri),
+- useSsl(inUseSsl), retryCount(0), maxRetryAttempts(5),
++ resolver(ioc),
++ conn(ioc), timer(ioc), subId(id), host(destIP), port(destPort),
++ uri(destUri), useSsl(inUseSsl), retryCount(0), maxRetryAttempts(5),
+ retryPolicyAction("TerminateAfterRetries"), runningTimer(false),
+ state(ConnState::initialized)
+- {
+- boost::asio::ip::tcp::resolver resolver(ioc);
+- // TODO: Use async_resolver. boost asio example
+- // code as is crashing with async_resolve().
+- // It needs debug.
+- endpoint = resolver.resolve(host, port);
+- }
++ {}
+
+ void sendData(const std::string& data)
+ {
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Redfish-TelemetryService-schema-implementation.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Redfish-TelemetryService-schema-implementation.patch
index 3850c8fa8..b30f874f6 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Redfish-TelemetryService-schema-implementation.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Redfish-TelemetryService-schema-implementation.patch
@@ -1,4 +1,4 @@
-From 7820421433349df28bd393e8d610d1848af0f1c8 Mon Sep 17 00:00:00 2001
+From 505ae9c2e6af470cdddcac9bac0de98afe0cfe58 Mon Sep 17 00:00:00 2001
From: "Wludzik, Jozef" <jozef.wludzik@intel.com>
Date: Mon, 27 Apr 2020 17:24:15 +0200
Subject: [PATCH 1/5] Redfish TelemetryService schema implementation
@@ -30,11 +30,11 @@ Change-Id: Ie6b0b49f4ef5eeaef07d1209b6c349270c04d570
redfish-core/include/utils/json_utils.hpp | 101 +++++++++++++
redfish-core/include/utils/telemetry_utils.hpp | 100 +++++++++++++
redfish-core/include/utils/time_utils.hpp | 97 +++++++++++++
- redfish-core/lib/metric_report.hpp | 149 +++++++++++++++++++
+ redfish-core/lib/metric_report.hpp | 164 +++++++++++++++++++++
redfish-core/lib/metric_report_definition.hpp | 193 +++++++++++++++++++++++++
redfish-core/lib/service_root.hpp | 2 +
redfish-core/lib/telemetry_service.hpp | 92 ++++++++++++
- 9 files changed, 765 insertions(+)
+ 9 files changed, 780 insertions(+)
create mode 100644 redfish-core/include/utils/telemetry_utils.hpp
create mode 100644 redfish-core/include/utils/time_utils.hpp
create mode 100644 redfish-core/lib/metric_report.hpp
@@ -73,7 +73,7 @@ index e1360f7..3df88d8 100644
} // namespace utility
} // namespace dbus
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
-index cc98e1a..3d4c117 100644
+index 2e568da..898f548 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -25,6 +25,8 @@
@@ -93,7 +93,7 @@ index cc98e1a..3d4c117 100644
#include "../lib/thermal.hpp"
#include "../lib/update_service.hpp"
#ifdef BMCWEB_ENABLE_VM_NBDPROXY
-@@ -202,6 +205,13 @@ class RedfishService
+@@ -209,6 +212,13 @@ class RedfishService
nodes.emplace_back(std::make_unique<HypervisorInterface>(app));
nodes.emplace_back(std::make_unique<HypervisorSystem>(app));
@@ -445,10 +445,10 @@ index 0000000..0256b3f
+} // namespace redfish
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
new file mode 100644
-index 0000000..a52d680
+index 0000000..d2f9dd5
--- /dev/null
+++ b/redfish-core/lib/metric_report.hpp
-@@ -0,0 +1,149 @@
+@@ -0,0 +1,164 @@
+/*
+// Copyright (c) 2018-2020 Intel Corporation
+//
@@ -541,6 +541,7 @@ index 0000000..a52d680
+
+ using Readings =
+ std::vector<std::tuple<std::string, std::string, double, int32_t>>;
++ using TimestampAndReadings = std::tuple<int32_t, Readings>;
+ using MetricValues = std::vector<std::map<std::string, std::string>>;
+
+ static MetricValues toMetricValues(const Readings& readings)
@@ -575,7 +576,7 @@ index 0000000..a52d680
+ [asyncResp](
+ const boost::system::error_code ec,
+ const boost::container::flat_map<
-+ std::string, std::variant<Readings, int32_t>>& ret) {
++ std::string, std::variant<TimestampAndReadings>>& ret) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
@@ -583,12 +584,26 @@ index 0000000..a52d680
+ return;
+ }
+
-+ json_util::assignIfPresent<int32_t>(
-+ ret, "Timestamp", asyncResp->res.jsonValue["Timestamp"],
-+ crow::utility::getDateTime);
-+ json_util::assignIfPresent<Readings>(
-+ ret, "Readings", asyncResp->res.jsonValue["MetricValues"],
-+ toMetricValues);
++ auto found = ret.find("Readings");
++ if (found == ret.end())
++ {
++ messages::internalError(asyncResp->res);
++ BMCWEB_LOG_ERROR << "Missing Readings property";
++ return;
++ }
++
++ const TimestampAndReadings* timestampAndReadingsPtr =
++ std::get_if<TimestampAndReadings>(&found->second);
++ if (!timestampAndReadingsPtr)
++ {
++ messages::internalError(asyncResp->res);
++ return;
++ }
++ const auto& [timestamp, readings] = *timestampAndReadingsPtr;
++ asyncResp->res.jsonValue["Timestamp"] =
++ crow::utility::getDateTime(timestamp);
++ asyncResp->res.jsonValue["MetricValues"] =
++ toMetricValues(readings);
+ },
+ "xyz.openbmc_project.MonitoringService", reportPath,
+ "xyz.openbmc_project.MonitoringService.Report");
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Add-support-for-POST-in-MetricReportDefinitions.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Add-support-for-POST-in-MetricReportDefinitions.patch
index 8a8690bf3..309d39ba0 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Add-support-for-POST-in-MetricReportDefinitions.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Add-support-for-POST-in-MetricReportDefinitions.patch
@@ -234,7 +234,7 @@ index d82ae59..ecbab0c 100644
+static constexpr size_t maxShortParamLength = 255;
+static constexpr size_t maxLongParamLength = 1024;
+static constexpr size_t maxDbusNameLength = 255;
-+static constexpr size_t maxArraySize = 100;
++static constexpr size_t maxArraySize = 200;
+static constexpr size_t maxReportIdLen =
+ maxDbusNameLength - std::string_view(telemetry::telemetryPath).size() -
+ std::string_view("/").size();
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-OnRequest-in-MetricReportDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-OnRequest-in-MetricReportDefinition.patch
index e996ac585..f95a0fe47 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-OnRequest-in-MetricReportDefinition.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-OnRequest-in-MetricReportDefinition.patch
@@ -1,4 +1,4 @@
-From 9fc7d722b3192df9940062185b40ebb0fabad518 Mon Sep 17 00:00:00 2001
+From 1ccc028dc20ab1e585de225b8c50a7492499008c Mon Sep 17 00:00:00 2001
From: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Date: Mon, 8 Jun 2020 15:16:10 +0200
Subject: [PATCH 4/5] Add support for "OnRequest" in MetricReportDefinition
@@ -94,7 +94,7 @@ index 05ed00f..6c4e810 100644
{
messages::resourceNotFound(asyncResp->res, schemaType, id);
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
-index a52d680..877e7f1 100644
+index d2f9dd5..f8230a5 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -85,7 +85,7 @@ class MetricReport : public Node
@@ -106,7 +106,7 @@ index a52d680..877e7f1 100644
}
using Readings =
-@@ -143,6 +143,57 @@ class MetricReport : public Node
+@@ -158,6 +158,57 @@ class MetricReport : public Node
"xyz.openbmc_project.MonitoringService.Report");
}
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-support-for-MetricDefinition-scheme.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-support-for-MetricDefinition-scheme.patch
index f7da8a556..8c7ef2c27 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-support-for-MetricDefinition-scheme.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-support-for-MetricDefinition-scheme.patch
@@ -1,4 +1,4 @@
-From b1da8901b5985d6a77b63ca9eb0570b46528f0bd Mon Sep 17 00:00:00 2001
+From fe2ed86210958f23fa0a8bd14c260e9cf4648e5a Mon Sep 17 00:00:00 2001
From: "Wludzik, Jozef" <jozef.wludzik@intel.com>
Date: Mon, 8 Jun 2020 17:15:54 +0200
Subject: [PATCH 5/5] Add support for MetricDefinition scheme
@@ -17,15 +17,15 @@ Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00
---
redfish-core/include/redfish.hpp | 3 +
redfish-core/include/utils/telemetry_utils.hpp | 2 +
- redfish-core/lib/metric_definition.hpp | 300 +++++++++++++++++++++++++
- redfish-core/lib/metric_report.hpp | 65 +++++-
+ redfish-core/lib/metric_definition.hpp | 299 +++++++++++++++++++++++++
+ redfish-core/lib/metric_report.hpp | 66 +++++-
redfish-core/lib/sensors.hpp | 43 +++-
redfish-core/lib/telemetry_service.hpp | 2 +
6 files changed, 402 insertions(+), 13 deletions(-)
create mode 100644 redfish-core/lib/metric_definition.hpp
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
-index 3d4c117..2a12bf9 100644
+index 898f548..1c3b5de 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -25,6 +25,7 @@
@@ -36,7 +36,7 @@ index 3d4c117..2a12bf9 100644
#include "../lib/metric_report.hpp"
#include "../lib/metric_report_definition.hpp"
#include "../lib/network_protocol.hpp"
-@@ -206,6 +207,8 @@ class RedfishService
+@@ -213,6 +214,8 @@ class RedfishService
nodes.emplace_back(std::make_unique<HypervisorSystem>(app));
nodes.emplace_back(std::make_unique<TelemetryService>(app));
@@ -60,10 +60,10 @@ index 6c4e810..bb747c4 100644
static constexpr const char* metricReportUri =
diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp
new file mode 100644
-index 0000000..837a068
+index 0000000..ff1b1ad
--- /dev/null
+++ b/redfish-core/lib/metric_definition.hpp
-@@ -0,0 +1,300 @@
+@@ -0,0 +1,299 @@
+/*
+// Copyright (c) 2018-2020 Intel Corporation
+//
@@ -323,7 +323,6 @@ index 0000000..837a068
+ asyncResp->res.jsonValue["MetricType"] = "Numeric";
+ asyncResp->res.jsonValue["Implementation"] = "PhysicalSensor";
+ asyncResp->res.jsonValue["IsLinear"] = true;
-+ asyncResp->res.jsonValue["TimestampAccuracy"] = "PT0.1S";
+ auto unit = sensorUnits.find(id);
+ if (unit != sensorUnits.end())
+ {
@@ -365,12 +364,12 @@ index 0000000..837a068
+
+} // namespace redfish
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
-index 877e7f1..be72b18 100644
+index f8230a5..d4cdee1 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
-@@ -91,6 +91,9 @@ class MetricReport : public Node
- using Readings =
+@@ -92,6 +92,9 @@ class MetricReport : public Node
std::vector<std::tuple<std::string, std::string, double, int32_t>>;
+ using TimestampAndReadings = std::tuple<int32_t, Readings>;
using MetricValues = std::vector<std::map<std::string, std::string>>;
+ using ReadingParameters =
+ std::vector<std::tuple<std::vector<sdbusplus::message::object_path>,
@@ -378,7 +377,7 @@ index 877e7f1..be72b18 100644
static MetricValues toMetricValues(const Readings& readings)
{
-@@ -109,6 +112,49 @@ class MetricReport : public Node
+@@ -110,6 +113,49 @@ class MetricReport : public Node
return metricValues;
}
@@ -428,22 +427,23 @@ index 877e7f1..be72b18 100644
static void getReportProperties(const std::shared_ptr<AsyncResp> asyncResp,
const std::string& reportPath,
const std::string& id)
-@@ -124,7 +170,8 @@ class MetricReport : public Node
+@@ -125,7 +171,9 @@ class MetricReport : public Node
[asyncResp](
const boost::system::error_code ec,
const boost::container::flat_map<
-- std::string, std::variant<Readings, int32_t>>& ret) {
+- std::string, std::variant<TimestampAndReadings>>& ret) {
+ std::string,
-+ std::variant<Readings, int32_t, ReadingParameters>>& ret) {
++ std::variant<TimestampAndReadings,
++ ReadingParameters>>& ret) {
if (ec)
{
messages::internalError(asyncResp->res);
-@@ -138,6 +185,22 @@ class MetricReport : public Node
- json_util::assignIfPresent<Readings>(
- ret, "Readings", asyncResp->res.jsonValue["MetricValues"],
- toMetricValues);
+@@ -153,6 +201,22 @@ class MetricReport : public Node
+ crow::utility::getDateTime(timestamp);
+ asyncResp->res.jsonValue["MetricValues"] =
+ toMetricValues(readings);
+
-+ auto found = ret.find("ReadingParameters");
++ found = ret.find("ReadingParameters");
+ if (found != ret.end())
+ {
+ auto params =
@@ -462,7 +462,7 @@ index 877e7f1..be72b18 100644
"xyz.openbmc_project.MonitoringService", reportPath,
"xyz.openbmc_project.MonitoringService.Report");
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
-index f12bbe0..1fa1009 100644
+index 48aa439..e700081 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -53,20 +53,39 @@ static constexpr std::string_view thermal = "Thermal";
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
index f36be0d15..38f0fe532 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -28,7 +28,6 @@ SRC_URI += "file://0001-Firmware-update-support-for-StandBySpare.patch \
file://0012-System-Replace-chassis-name-in-Redfish.patch \
file://0013-url_view-throws-if-a-parse-error-is-found.patch \
file://0014-add-sufficient-delay-to-create-fw-update-object.patch \
- file://0009-Workaround-Fix-memory-leak.patch \
file://0015-Add-firmware-activation-messages-to-the-registry.patch \
file://0016-EventService-Fix-type-mismatch-in-MetricReport.patch \
file://0017-Add-MutualExclusiveProperties-registry.patch \
@@ -41,6 +40,14 @@ SRC_URI += "file://0001-Firmware-update-support-for-StandBySpare.patch \
file://0024-EventService-Log-events-for-subscription-actions.patch \
file://0025-Add-missing-Context-property-to-MetricReport.patch \
file://0026-http-status-code-for-subscriber-limit-exceed.patch \
+ file://0009-Fix-memory-leak.patch \
+ file://0027-EventService-Improvements-and-limitations.patch \
+ file://0028-EventService-Schedule-MetricReport-data-format.patch \
+ file://0029-Added-Validation-on-MessageId-and-RegistryPrefix.patch \
+ file://0030-Initialize-Event-Service-Config-on-bmcweb-restart.patch \
+ file://0031-get-on-crashdump-can-follow-redfish-privileges.patch \
+ file://0034-Avoid-using-deleted-Connection-in-Response.patch \
+ file://0035-EventService-Fix-hostname-resolve-issue.patch \
"
# Temporary downstream mirror of upstream patches, see telemetry\README for details
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
index f6a9e9f35..6949d7a0c 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0071-chassishandler-SetSystemBootOptions-to-new-API.patch
@@ -544,11 +544,11 @@ index f5e7375..ca7cd2c 100644
+ uint2_t setStatus;
+ uint6_t rsvd;
+
-+ if (data.unpack(rsvd, setStatus) != 0 || !data.fullyUnpacked())
++ if (data.unpack(setStatus, rsvd) != 0 || !data.fullyUnpacked())
+ {
+ return ipmi::responseReqDataLenInvalid();
+ }
-+ if (rsvd || setStatus != static_cast<uint2_t>(setComplete))
++ if (rsvd)
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch
index 272626e07..a9040ebbe 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch
@@ -35,12 +35,12 @@ Boot parameter data: 8008000000
Signed-off-by: srikanta mondal <srikantax.mondal@intel.com>
Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
---
- chassishandler.cpp | 231 +++++++++++++++++++++++----------------------
+ chassishandler.cpp | 232 +++++++++++++++++++++++----------------------
chassishandler.hpp | 7 --
- 2 files changed, 119 insertions(+), 119 deletions(-)
+ 2 files changed, 120 insertions(+), 119 deletions(-)
diff --git a/chassishandler.cpp b/chassishandler.cpp
-index ca7cd2c..bbb3f81 100644
+index 4cce657..5f0cba3 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -44,9 +44,6 @@ static constexpr uint8_t setParmBootFlagsPermanent = 0x40;
@@ -192,7 +192,7 @@ index ca7cd2c..bbb3f81 100644
}
#endif
-@@ -1561,44 +1567,52 @@ static ipmi::Cc setBootMode(const Mode::Modes& mode)
+@@ -1561,44 +1567,53 @@ static ipmi::Cc setBootMode(const Mode::Modes& mode)
static constexpr uint8_t setComplete = 0x0;
static constexpr uint8_t setInProgress = 0x1;
static uint8_t transferStatus = setComplete;
@@ -249,7 +249,8 @@ index ca7cd2c..bbb3f81 100644
- resp->parm = static_cast<uint8_t>(BootOptionParameter::setInProgress);
- resp->data[0] = transferStatus;
- return IPMI_CC_OK;
-+ return ipmi::response(transferStatus);
++ response.pack(bootOptionParameter, reserved1, transferStatus);
++ return ipmi::responseSuccess(std::move(response));
}
- std::memset(resp, 0, sizeof(*resp));
@@ -269,7 +270,7 @@ index ca7cd2c..bbb3f81 100644
using namespace chassis::internal;
using namespace chassis::internal::cache;
-@@ -1619,8 +1633,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+@@ -1619,8 +1634,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
{
log<level::ERR>("Error in BootSource Get");
report<InternalFailure>();
@@ -279,7 +280,7 @@ index ca7cd2c..bbb3f81 100644
}
std::variant<std::string> result;
reply.read(result);
-@@ -1638,8 +1651,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+@@ -1638,8 +1652,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
{
log<level::ERR>("Error in BootMode Get");
report<InternalFailure>();
@@ -289,7 +290,7 @@ index ca7cd2c..bbb3f81 100644
}
reply.read(result);
auto bootMode =
-@@ -1655,59 +1667,54 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+@@ -1655,59 +1668,54 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
{
bootOption = modeDbusToIpmi.at(bootMode);
}
@@ -384,7 +385,7 @@ index ca7cd2c..bbb3f81 100644
}
ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
-@@ -1820,7 +1827,6 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
+@@ -1820,7 +1828,6 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
if (sourceIpmiToDbus.end() != sourceItr)
{
rc = setBootSource(sourceItr->second);
@@ -392,7 +393,7 @@ index ca7cd2c..bbb3f81 100644
if (rc != ipmi::ccSuccess)
{
log<level::ERR>("ipmiChassisSetSysBootOptions: Error in "
-@@ -2067,9 +2073,10 @@ void register_netfn_chassis_functions()
+@@ -2067,9 +2074,10 @@ void register_netfn_chassis_functions()
ipmi::Privilege::User, ipmiSetChassisCap);
// <Get System Boot Options>
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0007-Treat-pwd-is-not-set-if-no-entry-in-shadow-for-usr.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0007-Treat-pwd-is-not-set-if-no-entry-in-shadow-for-usr.patch
new file mode 100644
index 000000000..aa7a967b8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0007-Treat-pwd-is-not-set-if-no-entry-in-shadow-for-usr.patch
@@ -0,0 +1,49 @@
+From 5f401fe15b7911292ca3bf5de9068813cc8c0a10 Mon Sep 17 00:00:00 2001
+From: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+Date: Fri, 18 Sep 2020 15:59:06 +0000
+Subject: [PATCH] Treat pwd is not set if no entry in shadow for usr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are situations (mostly manipulated), when user entry is present
+in /etc/password, but not in /etc/shadow. Even though user can’t login
+without proper entry in /etc/shadow, it is a valid user and password
+update is only required
+
+Tested:
+1. Manually removed a user entry in /etc/shadow
+2. Restarted phosphor-user-manager service
+3. Made sure user is listed, and able to update the password through
+ ipmitool set password command
+4. Queried the user entry again and confirmed PasswordExpired is
+ returned as false.
+
+Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+Change-Id: I818be9a63121448210a99c175005708788279963
+---
+ user_mgr.cpp | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/user_mgr.cpp b/user_mgr.cpp
+index d1f881e..0447fe7 100644
+--- a/user_mgr.cpp
++++ b/user_mgr.cpp
+@@ -763,9 +763,11 @@ bool UserMgr::userPasswordExpired(const std::string &userName)
+ }
+ else
+ {
+- log<level::ERR>("User does not exist",
+- entry("USER_NAME=%s", userName.c_str()));
+- elog<UserNameDoesNotExist>();
++ // User entry is missing in /etc/shadow, indicating no SHA password.
++ // Treat this as new user without password entry in /etc/shadow
++ // TODO: Add property to indicate user password was not set yet
++ // https://github.com/openbmc/phosphor-user-manager/issues/8
++ return false;
+ }
+
+ return false;
+--
+2.26.2
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
index 5733eceed..8f6fbf760 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
@@ -7,4 +7,5 @@ EXTRA_OECONF += "${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'a
SRC_URI += " \
file://0005-Added-suport-for-multiple-user-manager-services.patch \
file://0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch \
+ file://0007-Treat-pwd-is-not-set-if-no-entry-in-shadow-for-usr.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit/0002-Add-support-for-ssl-config.patch b/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit/0002-Add-support-for-ssl-config.patch
new file mode 100644
index 000000000..95ffc0a48
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit/0002-Add-support-for-ssl-config.patch
@@ -0,0 +1,66 @@
+diff --git a/plugins/curl/curl.c b/plugins/curl/curl.c
+index 610511f7..92be4656 100644
+--- a/plugins/curl/curl.c
++++ b/plugins/curl/curl.c
+@@ -69,6 +69,8 @@ static const char *proxy = NULL;
+ static char *proxy_password = NULL;
+ static const char *proxy_user = NULL;
+ static bool sslverify = true;
++static const char *ssl_version = NULL;
++static const char *ssl_cipher_list = NULL;
+ static bool tcp_keepalive = false;
+ static bool tcp_nodelay = true;
+ static uint32_t timeout = 0;
+@@ -232,6 +234,12 @@ curl_config (const char *key, const char *value)
+ sslverify = r;
+ }
+
++ else if (strcmp (key, "ssl-version") == 0)
++ ssl_version = value;
++
++ else if (strcmp (key, "ssl-cipher-list") == 0)
++ ssl_cipher_list = value;
++
+ else if (strcmp (key, "tcp-keepalive") == 0) {
+ r = nbdkit_parse_bool (value);
+ if (r == -1)
+@@ -302,6 +310,8 @@ curl_config_complete (void)
+ "proxy-user=<USER> The proxy user.\n" \
+ "timeout=<TIMEOUT> Set the timeout for requests (seconds).\n" \
+ "sslverify=false Do not verify SSL certificate of remote host.\n" \
++ "ssl-version=<VERSION> Specify preferred TLS/SSL version.\n " \
++ "ssl-cipher-list=C1:C2:.. Specify TLS/SSL cipher suites to be used.\n" \
+ "tcp-keepalive=true Enable TCP keepalives.\n" \
+ "tcp-nodelay=false Disable Nagle’s algorithm.\n" \
+ "unix-socket-path=<PATH> Open Unix domain socket instead of TCP/IP.\n" \
+@@ -418,6 +428,30 @@ curl_open (int readonly)
+ curl_easy_setopt (h->c, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt (h->c, CURLOPT_SSL_VERIFYHOST, 0L);
+ }
++ if (ssl_version) {
++ if (strcmp (ssl_version, "tlsv1") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
++ else if (strcmp (ssl_version, "sslv2") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv2);
++ else if (strcmp (ssl_version, "sslv3") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
++ else if (strcmp (ssl_version, "tlsv1.0") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0);
++ else if (strcmp (ssl_version, "tlsv1.1") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
++ else if (strcmp (ssl_version, "tlsv1.2") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
++ else if (strcmp (ssl_version, "tlsv1.3") == 0)
++ curl_easy_setopt (h->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_3);
++ else {
++ display_curl_error (h, r, "curl_easy_setopt: CURLOPT_SSLVERSION [%s]",
++ ssl_version);
++ goto err;
++ }
++
++ }
++ if (ssl_cipher_list)
++ curl_easy_setopt (h->c, CURLOPT_SSL_CIPHER_LIST, ssl_cipher_list);
+ if (tcp_keepalive)
+ curl_easy_setopt (h->c, CURLOPT_TCP_KEEPALIVE, 1L);
+ if (!tcp_nodelay)
diff --git a/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit_git.bb b/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit_git.bb
index b97dea75c..01b3fc27e 100644
--- a/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit_git.bb
+++ b/meta-openbmc-mods/meta-common/recipes-utilities/nbdkit/nbdkit_git.bb
@@ -11,6 +11,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=4332a97808994cf2133a65b6c6f33eaf"
SRC_URI = "git://github.com/libguestfs/nbdkit.git;protocol=https"
SRC_URI += "file://0001-Force-nbdkit-to-send-PATCH-as-upload-method.patch"
+SRC_URI += "file://0002-Add-support-for-ssl-config.patch"
PV = "1.17.5+git${SRCPV}"
SRCREV = "c8406880c6603bb617dae131dd0a8826c05869ca"